File: | clang/lib/Sema/SemaOpenMP.cpp |
Warning: | line 2199, column 54 Access to field 'OpenMPLevel' results in a dereference of a null pointer (loaded from variable 'CSI') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===// | ||||||||
2 | // | ||||||||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||||||||
4 | // See https://llvm.org/LICENSE.txt for license information. | ||||||||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||||||
6 | // | ||||||||
7 | //===----------------------------------------------------------------------===// | ||||||||
8 | /// \file | ||||||||
9 | /// This file implements semantic analysis for OpenMP directives and | ||||||||
10 | /// clauses. | ||||||||
11 | /// | ||||||||
12 | //===----------------------------------------------------------------------===// | ||||||||
13 | |||||||||
14 | #include "TreeTransform.h" | ||||||||
15 | #include "clang/AST/ASTContext.h" | ||||||||
16 | #include "clang/AST/ASTMutationListener.h" | ||||||||
17 | #include "clang/AST/CXXInheritance.h" | ||||||||
18 | #include "clang/AST/Decl.h" | ||||||||
19 | #include "clang/AST/DeclCXX.h" | ||||||||
20 | #include "clang/AST/DeclOpenMP.h" | ||||||||
21 | #include "clang/AST/OpenMPClause.h" | ||||||||
22 | #include "clang/AST/StmtCXX.h" | ||||||||
23 | #include "clang/AST/StmtOpenMP.h" | ||||||||
24 | #include "clang/AST/StmtVisitor.h" | ||||||||
25 | #include "clang/AST/TypeOrdering.h" | ||||||||
26 | #include "clang/Basic/DiagnosticSema.h" | ||||||||
27 | #include "clang/Basic/OpenMPKinds.h" | ||||||||
28 | #include "clang/Basic/PartialDiagnostic.h" | ||||||||
29 | #include "clang/Basic/TargetInfo.h" | ||||||||
30 | #include "clang/Sema/Initialization.h" | ||||||||
31 | #include "clang/Sema/Lookup.h" | ||||||||
32 | #include "clang/Sema/Scope.h" | ||||||||
33 | #include "clang/Sema/ScopeInfo.h" | ||||||||
34 | #include "clang/Sema/SemaInternal.h" | ||||||||
35 | #include "llvm/ADT/IndexedMap.h" | ||||||||
36 | #include "llvm/ADT/PointerEmbeddedInt.h" | ||||||||
37 | #include "llvm/ADT/STLExtras.h" | ||||||||
38 | #include "llvm/Frontend/OpenMP/OMPConstants.h" | ||||||||
39 | #include <set> | ||||||||
40 | |||||||||
41 | using namespace clang; | ||||||||
42 | using namespace llvm::omp; | ||||||||
43 | |||||||||
44 | //===----------------------------------------------------------------------===// | ||||||||
45 | // Stack of data-sharing attributes for variables | ||||||||
46 | //===----------------------------------------------------------------------===// | ||||||||
47 | |||||||||
48 | static const Expr *checkMapClauseExpressionBase( | ||||||||
49 | Sema &SemaRef, Expr *E, | ||||||||
50 | OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, | ||||||||
51 | OpenMPClauseKind CKind, bool NoDiagnose); | ||||||||
52 | |||||||||
53 | namespace { | ||||||||
54 | /// Default data sharing attributes, which can be applied to directive. | ||||||||
55 | enum DefaultDataSharingAttributes { | ||||||||
56 | DSA_unspecified = 0, /// Data sharing attribute not specified. | ||||||||
57 | DSA_none = 1 << 0, /// Default data sharing attribute 'none'. | ||||||||
58 | DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. | ||||||||
59 | DSA_firstprivate = 1 << 2, /// Default data sharing attribute 'firstprivate'. | ||||||||
60 | }; | ||||||||
61 | |||||||||
62 | /// Stack for tracking declarations used in OpenMP directives and | ||||||||
63 | /// clauses and their data-sharing attributes. | ||||||||
64 | class DSAStackTy { | ||||||||
65 | public: | ||||||||
66 | struct DSAVarData { | ||||||||
67 | OpenMPDirectiveKind DKind = OMPD_unknown; | ||||||||
68 | OpenMPClauseKind CKind = OMPC_unknown; | ||||||||
69 | unsigned Modifier = 0; | ||||||||
70 | const Expr *RefExpr = nullptr; | ||||||||
71 | DeclRefExpr *PrivateCopy = nullptr; | ||||||||
72 | SourceLocation ImplicitDSALoc; | ||||||||
73 | bool AppliedToPointee = false; | ||||||||
74 | DSAVarData() = default; | ||||||||
75 | DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, | ||||||||
76 | const Expr *RefExpr, DeclRefExpr *PrivateCopy, | ||||||||
77 | SourceLocation ImplicitDSALoc, unsigned Modifier, | ||||||||
78 | bool AppliedToPointee) | ||||||||
79 | : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr), | ||||||||
80 | PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc), | ||||||||
81 | AppliedToPointee(AppliedToPointee) {} | ||||||||
82 | }; | ||||||||
83 | using OperatorOffsetTy = | ||||||||
84 | llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; | ||||||||
85 | using DoacrossDependMapTy = | ||||||||
86 | llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; | ||||||||
87 | /// Kind of the declaration used in the uses_allocators clauses. | ||||||||
88 | enum class UsesAllocatorsDeclKind { | ||||||||
89 | /// Predefined allocator | ||||||||
90 | PredefinedAllocator, | ||||||||
91 | /// User-defined allocator | ||||||||
92 | UserDefinedAllocator, | ||||||||
93 | /// The declaration that represent allocator trait | ||||||||
94 | AllocatorTrait, | ||||||||
95 | }; | ||||||||
96 | |||||||||
97 | private: | ||||||||
98 | struct DSAInfo { | ||||||||
99 | OpenMPClauseKind Attributes = OMPC_unknown; | ||||||||
100 | unsigned Modifier = 0; | ||||||||
101 | /// Pointer to a reference expression and a flag which shows that the | ||||||||
102 | /// variable is marked as lastprivate(true) or not (false). | ||||||||
103 | llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; | ||||||||
104 | DeclRefExpr *PrivateCopy = nullptr; | ||||||||
105 | /// true if the attribute is applied to the pointee, not the variable | ||||||||
106 | /// itself. | ||||||||
107 | bool AppliedToPointee = false; | ||||||||
108 | }; | ||||||||
109 | using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; | ||||||||
110 | using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; | ||||||||
111 | using LCDeclInfo = std::pair<unsigned, VarDecl *>; | ||||||||
112 | using LoopControlVariablesMapTy = | ||||||||
113 | llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; | ||||||||
114 | /// Struct that associates a component with the clause kind where they are | ||||||||
115 | /// found. | ||||||||
116 | struct MappedExprComponentTy { | ||||||||
117 | OMPClauseMappableExprCommon::MappableExprComponentLists Components; | ||||||||
118 | OpenMPClauseKind Kind = OMPC_unknown; | ||||||||
119 | }; | ||||||||
120 | using MappedExprComponentsTy = | ||||||||
121 | llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; | ||||||||
122 | using CriticalsWithHintsTy = | ||||||||
123 | llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; | ||||||||
124 | struct ReductionData { | ||||||||
125 | using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; | ||||||||
126 | SourceRange ReductionRange; | ||||||||
127 | llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; | ||||||||
128 | ReductionData() = default; | ||||||||
129 | void set(BinaryOperatorKind BO, SourceRange RR) { | ||||||||
130 | ReductionRange = RR; | ||||||||
131 | ReductionOp = BO; | ||||||||
132 | } | ||||||||
133 | void set(const Expr *RefExpr, SourceRange RR) { | ||||||||
134 | ReductionRange = RR; | ||||||||
135 | ReductionOp = RefExpr; | ||||||||
136 | } | ||||||||
137 | }; | ||||||||
138 | using DeclReductionMapTy = | ||||||||
139 | llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; | ||||||||
140 | struct DefaultmapInfo { | ||||||||
141 | OpenMPDefaultmapClauseModifier ImplicitBehavior = | ||||||||
142 | OMPC_DEFAULTMAP_MODIFIER_unknown; | ||||||||
143 | SourceLocation SLoc; | ||||||||
144 | DefaultmapInfo() = default; | ||||||||
145 | DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc) | ||||||||
146 | : ImplicitBehavior(M), SLoc(Loc) {} | ||||||||
147 | }; | ||||||||
148 | |||||||||
149 | struct SharingMapTy { | ||||||||
150 | DeclSAMapTy SharingMap; | ||||||||
151 | DeclReductionMapTy ReductionMap; | ||||||||
152 | UsedRefMapTy AlignedMap; | ||||||||
153 | UsedRefMapTy NontemporalMap; | ||||||||
154 | MappedExprComponentsTy MappedExprComponents; | ||||||||
155 | LoopControlVariablesMapTy LCVMap; | ||||||||
156 | DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; | ||||||||
157 | SourceLocation DefaultAttrLoc; | ||||||||
158 | DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown]; | ||||||||
159 | OpenMPDirectiveKind Directive = OMPD_unknown; | ||||||||
160 | DeclarationNameInfo DirectiveName; | ||||||||
161 | Scope *CurScope = nullptr; | ||||||||
162 | SourceLocation ConstructLoc; | ||||||||
163 | /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to | ||||||||
164 | /// get the data (loop counters etc.) about enclosing loop-based construct. | ||||||||
165 | /// This data is required during codegen. | ||||||||
166 | DoacrossDependMapTy DoacrossDepends; | ||||||||
167 | /// First argument (Expr *) contains optional argument of the | ||||||||
168 | /// 'ordered' clause, the second one is true if the regions has 'ordered' | ||||||||
169 | /// clause, false otherwise. | ||||||||
170 | llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; | ||||||||
171 | unsigned AssociatedLoops = 1; | ||||||||
172 | bool HasMutipleLoops = false; | ||||||||
173 | const Decl *PossiblyLoopCounter = nullptr; | ||||||||
174 | bool NowaitRegion = false; | ||||||||
175 | bool CancelRegion = false; | ||||||||
176 | bool LoopStart = false; | ||||||||
177 | bool BodyComplete = false; | ||||||||
178 | SourceLocation PrevScanLocation; | ||||||||
179 | SourceLocation PrevOrderedLocation; | ||||||||
180 | SourceLocation InnerTeamsRegionLoc; | ||||||||
181 | /// Reference to the taskgroup task_reduction reference expression. | ||||||||
182 | Expr *TaskgroupReductionRef = nullptr; | ||||||||
183 | llvm::DenseSet<QualType> MappedClassesQualTypes; | ||||||||
184 | SmallVector<Expr *, 4> InnerUsedAllocators; | ||||||||
185 | llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates; | ||||||||
186 | /// List of globals marked as declare target link in this target region | ||||||||
187 | /// (isOpenMPTargetExecutionDirective(Directive) == true). | ||||||||
188 | llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; | ||||||||
189 | /// List of decls used in inclusive/exclusive clauses of the scan directive. | ||||||||
190 | llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective; | ||||||||
191 | llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind> | ||||||||
192 | UsesAllocatorsDecls; | ||||||||
193 | Expr *DeclareMapperVar = nullptr; | ||||||||
194 | SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, | ||||||||
195 | Scope *CurScope, SourceLocation Loc) | ||||||||
196 | : Directive(DKind), DirectiveName(Name), CurScope(CurScope), | ||||||||
197 | ConstructLoc(Loc) {} | ||||||||
198 | SharingMapTy() = default; | ||||||||
199 | }; | ||||||||
200 | |||||||||
201 | using StackTy = SmallVector<SharingMapTy, 4>; | ||||||||
202 | |||||||||
203 | /// Stack of used declaration and their data-sharing attributes. | ||||||||
204 | DeclSAMapTy Threadprivates; | ||||||||
205 | const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; | ||||||||
206 | SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; | ||||||||
207 | /// true, if check for DSA must be from parent directive, false, if | ||||||||
208 | /// from current directive. | ||||||||
209 | OpenMPClauseKind ClauseKindMode = OMPC_unknown; | ||||||||
210 | Sema &SemaRef; | ||||||||
211 | bool ForceCapturing = false; | ||||||||
212 | /// true if all the variables in the target executable directives must be | ||||||||
213 | /// captured by reference. | ||||||||
214 | bool ForceCaptureByReferenceInTargetExecutable = false; | ||||||||
215 | CriticalsWithHintsTy Criticals; | ||||||||
216 | unsigned IgnoredStackElements = 0; | ||||||||
217 | |||||||||
218 | /// Iterators over the stack iterate in order from innermost to outermost | ||||||||
219 | /// directive. | ||||||||
220 | using const_iterator = StackTy::const_reverse_iterator; | ||||||||
221 | const_iterator begin() const { | ||||||||
222 | return Stack.empty() ? const_iterator() | ||||||||
223 | : Stack.back().first.rbegin() + IgnoredStackElements; | ||||||||
224 | } | ||||||||
225 | const_iterator end() const { | ||||||||
226 | return Stack.empty() ? const_iterator() : Stack.back().first.rend(); | ||||||||
227 | } | ||||||||
228 | using iterator = StackTy::reverse_iterator; | ||||||||
229 | iterator begin() { | ||||||||
230 | return Stack.empty() ? iterator() | ||||||||
231 | : Stack.back().first.rbegin() + IgnoredStackElements; | ||||||||
232 | } | ||||||||
233 | iterator end() { | ||||||||
234 | return Stack.empty() ? iterator() : Stack.back().first.rend(); | ||||||||
235 | } | ||||||||
236 | |||||||||
237 | // Convenience operations to get at the elements of the stack. | ||||||||
238 | |||||||||
239 | bool isStackEmpty() const { | ||||||||
240 | return Stack.empty() || | ||||||||
241 | Stack.back().second != CurrentNonCapturingFunctionScope || | ||||||||
242 | Stack.back().first.size() <= IgnoredStackElements; | ||||||||
243 | } | ||||||||
244 | size_t getStackSize() const { | ||||||||
245 | return isStackEmpty() ? 0 | ||||||||
246 | : Stack.back().first.size() - IgnoredStackElements; | ||||||||
247 | } | ||||||||
248 | |||||||||
249 | SharingMapTy *getTopOfStackOrNull() { | ||||||||
250 | size_t Size = getStackSize(); | ||||||||
251 | if (Size == 0) | ||||||||
252 | return nullptr; | ||||||||
253 | return &Stack.back().first[Size - 1]; | ||||||||
254 | } | ||||||||
255 | const SharingMapTy *getTopOfStackOrNull() const { | ||||||||
256 | return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); | ||||||||
257 | } | ||||||||
258 | SharingMapTy &getTopOfStack() { | ||||||||
259 | assert(!isStackEmpty() && "no current directive")((!isStackEmpty() && "no current directive") ? static_cast <void> (0) : __assert_fail ("!isStackEmpty() && \"no current directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 259, __PRETTY_FUNCTION__)); | ||||||||
260 | return *getTopOfStackOrNull(); | ||||||||
261 | } | ||||||||
262 | const SharingMapTy &getTopOfStack() const { | ||||||||
263 | return const_cast<DSAStackTy&>(*this).getTopOfStack(); | ||||||||
264 | } | ||||||||
265 | |||||||||
266 | SharingMapTy *getSecondOnStackOrNull() { | ||||||||
267 | size_t Size = getStackSize(); | ||||||||
268 | if (Size <= 1) | ||||||||
269 | return nullptr; | ||||||||
270 | return &Stack.back().first[Size - 2]; | ||||||||
271 | } | ||||||||
272 | const SharingMapTy *getSecondOnStackOrNull() const { | ||||||||
273 | return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); | ||||||||
274 | } | ||||||||
275 | |||||||||
276 | /// Get the stack element at a certain level (previously returned by | ||||||||
277 | /// \c getNestingLevel). | ||||||||
278 | /// | ||||||||
279 | /// Note that nesting levels count from outermost to innermost, and this is | ||||||||
280 | /// the reverse of our iteration order where new inner levels are pushed at | ||||||||
281 | /// the front of the stack. | ||||||||
282 | SharingMapTy &getStackElemAtLevel(unsigned Level) { | ||||||||
283 | assert(Level < getStackSize() && "no such stack element")((Level < getStackSize() && "no such stack element" ) ? static_cast<void> (0) : __assert_fail ("Level < getStackSize() && \"no such stack element\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 283, __PRETTY_FUNCTION__)); | ||||||||
284 | return Stack.back().first[Level]; | ||||||||
285 | } | ||||||||
286 | const SharingMapTy &getStackElemAtLevel(unsigned Level) const { | ||||||||
287 | return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); | ||||||||
288 | } | ||||||||
289 | |||||||||
290 | DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; | ||||||||
291 | |||||||||
292 | /// Checks if the variable is a local for OpenMP region. | ||||||||
293 | bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; | ||||||||
294 | |||||||||
295 | /// Vector of previously declared requires directives | ||||||||
296 | SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; | ||||||||
297 | /// omp_allocator_handle_t type. | ||||||||
298 | QualType OMPAllocatorHandleT; | ||||||||
299 | /// omp_depend_t type. | ||||||||
300 | QualType OMPDependT; | ||||||||
301 | /// omp_event_handle_t type. | ||||||||
302 | QualType OMPEventHandleT; | ||||||||
303 | /// omp_alloctrait_t type. | ||||||||
304 | QualType OMPAlloctraitT; | ||||||||
305 | /// Expression for the predefined allocators. | ||||||||
306 | Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { | ||||||||
307 | nullptr}; | ||||||||
308 | /// Vector of previously encountered target directives | ||||||||
309 | SmallVector<SourceLocation, 2> TargetLocations; | ||||||||
310 | SourceLocation AtomicLocation; | ||||||||
311 | |||||||||
312 | public: | ||||||||
313 | explicit DSAStackTy(Sema &S) : SemaRef(S) {} | ||||||||
314 | |||||||||
315 | /// Sets omp_allocator_handle_t type. | ||||||||
316 | void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } | ||||||||
317 | /// Gets omp_allocator_handle_t type. | ||||||||
318 | QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } | ||||||||
319 | /// Sets omp_alloctrait_t type. | ||||||||
320 | void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; } | ||||||||
321 | /// Gets omp_alloctrait_t type. | ||||||||
322 | QualType getOMPAlloctraitT() const { return OMPAlloctraitT; } | ||||||||
323 | /// Sets the given default allocator. | ||||||||
324 | void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, | ||||||||
325 | Expr *Allocator) { | ||||||||
326 | OMPPredefinedAllocators[AllocatorKind] = Allocator; | ||||||||
327 | } | ||||||||
328 | /// Returns the specified default allocator. | ||||||||
329 | Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { | ||||||||
330 | return OMPPredefinedAllocators[AllocatorKind]; | ||||||||
331 | } | ||||||||
332 | /// Sets omp_depend_t type. | ||||||||
333 | void setOMPDependT(QualType Ty) { OMPDependT = Ty; } | ||||||||
334 | /// Gets omp_depend_t type. | ||||||||
335 | QualType getOMPDependT() const { return OMPDependT; } | ||||||||
336 | |||||||||
337 | /// Sets omp_event_handle_t type. | ||||||||
338 | void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; } | ||||||||
339 | /// Gets omp_event_handle_t type. | ||||||||
340 | QualType getOMPEventHandleT() const { return OMPEventHandleT; } | ||||||||
341 | |||||||||
342 | bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } | ||||||||
343 | OpenMPClauseKind getClauseParsingMode() const { | ||||||||
344 | assert(isClauseParsingMode() && "Must be in clause parsing mode.")((isClauseParsingMode() && "Must be in clause parsing mode." ) ? static_cast<void> (0) : __assert_fail ("isClauseParsingMode() && \"Must be in clause parsing mode.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 344, __PRETTY_FUNCTION__)); | ||||||||
345 | return ClauseKindMode; | ||||||||
346 | } | ||||||||
347 | void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } | ||||||||
348 | |||||||||
349 | bool isBodyComplete() const { | ||||||||
350 | const SharingMapTy *Top = getTopOfStackOrNull(); | ||||||||
351 | return Top && Top->BodyComplete; | ||||||||
352 | } | ||||||||
353 | void setBodyComplete() { | ||||||||
354 | getTopOfStack().BodyComplete = true; | ||||||||
355 | } | ||||||||
356 | |||||||||
357 | bool isForceVarCapturing() const { return ForceCapturing; } | ||||||||
358 | void setForceVarCapturing(bool V) { ForceCapturing = V; } | ||||||||
359 | |||||||||
360 | void setForceCaptureByReferenceInTargetExecutable(bool V) { | ||||||||
361 | ForceCaptureByReferenceInTargetExecutable = V; | ||||||||
362 | } | ||||||||
363 | bool isForceCaptureByReferenceInTargetExecutable() const { | ||||||||
364 | return ForceCaptureByReferenceInTargetExecutable; | ||||||||
365 | } | ||||||||
366 | |||||||||
367 | void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, | ||||||||
368 | Scope *CurScope, SourceLocation Loc) { | ||||||||
369 | assert(!IgnoredStackElements &&((!IgnoredStackElements && "cannot change stack while ignoring elements" ) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 370, __PRETTY_FUNCTION__)) | ||||||||
370 | "cannot change stack while ignoring elements")((!IgnoredStackElements && "cannot change stack while ignoring elements" ) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 370, __PRETTY_FUNCTION__)); | ||||||||
371 | if (Stack.empty() || | ||||||||
372 | Stack.back().second != CurrentNonCapturingFunctionScope) | ||||||||
373 | Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); | ||||||||
374 | Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); | ||||||||
375 | Stack.back().first.back().DefaultAttrLoc = Loc; | ||||||||
376 | } | ||||||||
377 | |||||||||
378 | void pop() { | ||||||||
379 | assert(!IgnoredStackElements &&((!IgnoredStackElements && "cannot change stack while ignoring elements" ) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 380, __PRETTY_FUNCTION__)) | ||||||||
380 | "cannot change stack while ignoring elements")((!IgnoredStackElements && "cannot change stack while ignoring elements" ) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 380, __PRETTY_FUNCTION__)); | ||||||||
381 | assert(!Stack.back().first.empty() &&((!Stack.back().first.empty() && "Data-sharing attributes stack is empty!" ) ? static_cast<void> (0) : __assert_fail ("!Stack.back().first.empty() && \"Data-sharing attributes stack is empty!\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 382, __PRETTY_FUNCTION__)) | ||||||||
382 | "Data-sharing attributes stack is empty!")((!Stack.back().first.empty() && "Data-sharing attributes stack is empty!" ) ? static_cast<void> (0) : __assert_fail ("!Stack.back().first.empty() && \"Data-sharing attributes stack is empty!\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 382, __PRETTY_FUNCTION__)); | ||||||||
383 | Stack.back().first.pop_back(); | ||||||||
384 | } | ||||||||
385 | |||||||||
386 | /// RAII object to temporarily leave the scope of a directive when we want to | ||||||||
387 | /// logically operate in its parent. | ||||||||
388 | class ParentDirectiveScope { | ||||||||
389 | DSAStackTy &Self; | ||||||||
390 | bool Active; | ||||||||
391 | public: | ||||||||
392 | ParentDirectiveScope(DSAStackTy &Self, bool Activate) | ||||||||
393 | : Self(Self), Active(false) { | ||||||||
394 | if (Activate) | ||||||||
395 | enable(); | ||||||||
396 | } | ||||||||
397 | ~ParentDirectiveScope() { disable(); } | ||||||||
398 | void disable() { | ||||||||
399 | if (Active) { | ||||||||
400 | --Self.IgnoredStackElements; | ||||||||
401 | Active = false; | ||||||||
402 | } | ||||||||
403 | } | ||||||||
404 | void enable() { | ||||||||
405 | if (!Active) { | ||||||||
406 | ++Self.IgnoredStackElements; | ||||||||
407 | Active = true; | ||||||||
408 | } | ||||||||
409 | } | ||||||||
410 | }; | ||||||||
411 | |||||||||
412 | /// Marks that we're started loop parsing. | ||||||||
413 | void loopInit() { | ||||||||
414 | assert(isOpenMPLoopDirective(getCurrentDirective()) &&((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive." ) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 415, __PRETTY_FUNCTION__)) | ||||||||
415 | "Expected loop-based directive.")((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive." ) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 415, __PRETTY_FUNCTION__)); | ||||||||
416 | getTopOfStack().LoopStart = true; | ||||||||
417 | } | ||||||||
418 | /// Start capturing of the variables in the loop context. | ||||||||
419 | void loopStart() { | ||||||||
420 | assert(isOpenMPLoopDirective(getCurrentDirective()) &&((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive." ) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 421, __PRETTY_FUNCTION__)) | ||||||||
421 | "Expected loop-based directive.")((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive." ) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 421, __PRETTY_FUNCTION__)); | ||||||||
422 | getTopOfStack().LoopStart = false; | ||||||||
423 | } | ||||||||
424 | /// true, if variables are captured, false otherwise. | ||||||||
425 | bool isLoopStarted() const { | ||||||||
426 | assert(isOpenMPLoopDirective(getCurrentDirective()) &&((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive." ) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 427, __PRETTY_FUNCTION__)) | ||||||||
427 | "Expected loop-based directive.")((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive." ) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 427, __PRETTY_FUNCTION__)); | ||||||||
428 | return !getTopOfStack().LoopStart; | ||||||||
429 | } | ||||||||
430 | /// Marks (or clears) declaration as possibly loop counter. | ||||||||
431 | void resetPossibleLoopCounter(const Decl *D = nullptr) { | ||||||||
432 | getTopOfStack().PossiblyLoopCounter = | ||||||||
433 | D ? D->getCanonicalDecl() : D; | ||||||||
434 | } | ||||||||
435 | /// Gets the possible loop counter decl. | ||||||||
436 | const Decl *getPossiblyLoopCunter() const { | ||||||||
437 | return getTopOfStack().PossiblyLoopCounter; | ||||||||
438 | } | ||||||||
439 | /// Start new OpenMP region stack in new non-capturing function. | ||||||||
440 | void pushFunction() { | ||||||||
441 | assert(!IgnoredStackElements &&((!IgnoredStackElements && "cannot change stack while ignoring elements" ) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 442, __PRETTY_FUNCTION__)) | ||||||||
442 | "cannot change stack while ignoring elements")((!IgnoredStackElements && "cannot change stack while ignoring elements" ) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 442, __PRETTY_FUNCTION__)); | ||||||||
443 | const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); | ||||||||
444 | assert(!isa<CapturingScopeInfo>(CurFnScope))((!isa<CapturingScopeInfo>(CurFnScope)) ? static_cast< void> (0) : __assert_fail ("!isa<CapturingScopeInfo>(CurFnScope)" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 444, __PRETTY_FUNCTION__)); | ||||||||
445 | CurrentNonCapturingFunctionScope = CurFnScope; | ||||||||
446 | } | ||||||||
447 | /// Pop region stack for non-capturing function. | ||||||||
448 | void popFunction(const FunctionScopeInfo *OldFSI) { | ||||||||
449 | assert(!IgnoredStackElements &&((!IgnoredStackElements && "cannot change stack while ignoring elements" ) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 450, __PRETTY_FUNCTION__)) | ||||||||
450 | "cannot change stack while ignoring elements")((!IgnoredStackElements && "cannot change stack while ignoring elements" ) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 450, __PRETTY_FUNCTION__)); | ||||||||
451 | if (!Stack.empty() && Stack.back().second == OldFSI) { | ||||||||
452 | assert(Stack.back().first.empty())((Stack.back().first.empty()) ? static_cast<void> (0) : __assert_fail ("Stack.back().first.empty()", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 452, __PRETTY_FUNCTION__)); | ||||||||
453 | Stack.pop_back(); | ||||||||
454 | } | ||||||||
455 | CurrentNonCapturingFunctionScope = nullptr; | ||||||||
456 | for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { | ||||||||
457 | if (!isa<CapturingScopeInfo>(FSI)) { | ||||||||
458 | CurrentNonCapturingFunctionScope = FSI; | ||||||||
459 | break; | ||||||||
460 | } | ||||||||
461 | } | ||||||||
462 | } | ||||||||
463 | |||||||||
464 | void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { | ||||||||
465 | Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); | ||||||||
466 | } | ||||||||
467 | const std::pair<const OMPCriticalDirective *, llvm::APSInt> | ||||||||
468 | getCriticalWithHint(const DeclarationNameInfo &Name) const { | ||||||||
469 | auto I = Criticals.find(Name.getAsString()); | ||||||||
470 | if (I != Criticals.end()) | ||||||||
471 | return I->second; | ||||||||
472 | return std::make_pair(nullptr, llvm::APSInt()); | ||||||||
473 | } | ||||||||
474 | /// If 'aligned' declaration for given variable \a D was not seen yet, | ||||||||
475 | /// add it and return NULL; otherwise return previous occurrence's expression | ||||||||
476 | /// for diagnostics. | ||||||||
477 | const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); | ||||||||
478 | /// If 'nontemporal' declaration for given variable \a D was not seen yet, | ||||||||
479 | /// add it and return NULL; otherwise return previous occurrence's expression | ||||||||
480 | /// for diagnostics. | ||||||||
481 | const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE); | ||||||||
482 | |||||||||
483 | /// Register specified variable as loop control variable. | ||||||||
484 | void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); | ||||||||
485 | /// Check if the specified variable is a loop control variable for | ||||||||
486 | /// current region. | ||||||||
487 | /// \return The index of the loop control variable in the list of associated | ||||||||
488 | /// for-loops (from outer to inner). | ||||||||
489 | const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; | ||||||||
490 | /// Check if the specified variable is a loop control variable for | ||||||||
491 | /// parent region. | ||||||||
492 | /// \return The index of the loop control variable in the list of associated | ||||||||
493 | /// for-loops (from outer to inner). | ||||||||
494 | const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; | ||||||||
495 | /// Check if the specified variable is a loop control variable for | ||||||||
496 | /// current region. | ||||||||
497 | /// \return The index of the loop control variable in the list of associated | ||||||||
498 | /// for-loops (from outer to inner). | ||||||||
499 | const LCDeclInfo isLoopControlVariable(const ValueDecl *D, | ||||||||
500 | unsigned Level) const; | ||||||||
501 | /// Get the loop control variable for the I-th loop (or nullptr) in | ||||||||
502 | /// parent directive. | ||||||||
503 | const ValueDecl *getParentLoopControlVariable(unsigned I) const; | ||||||||
504 | |||||||||
505 | /// Marks the specified decl \p D as used in scan directive. | ||||||||
506 | void markDeclAsUsedInScanDirective(ValueDecl *D) { | ||||||||
507 | if (SharingMapTy *Stack = getSecondOnStackOrNull()) | ||||||||
508 | Stack->UsedInScanDirective.insert(D); | ||||||||
509 | } | ||||||||
510 | |||||||||
511 | /// Checks if the specified declaration was used in the inner scan directive. | ||||||||
512 | bool isUsedInScanDirective(ValueDecl *D) const { | ||||||||
513 | if (const SharingMapTy *Stack = getTopOfStackOrNull()) | ||||||||
514 | return Stack->UsedInScanDirective.count(D) > 0; | ||||||||
515 | return false; | ||||||||
516 | } | ||||||||
517 | |||||||||
518 | /// Adds explicit data sharing attribute to the specified declaration. | ||||||||
519 | void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, | ||||||||
520 | DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0, | ||||||||
521 | bool AppliedToPointee = false); | ||||||||
522 | |||||||||
523 | /// Adds additional information for the reduction items with the reduction id | ||||||||
524 | /// represented as an operator. | ||||||||
525 | void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, | ||||||||
526 | BinaryOperatorKind BOK); | ||||||||
527 | /// Adds additional information for the reduction items with the reduction id | ||||||||
528 | /// represented as reduction identifier. | ||||||||
529 | void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, | ||||||||
530 | const Expr *ReductionRef); | ||||||||
531 | /// Returns the location and reduction operation from the innermost parent | ||||||||
532 | /// region for the given \p D. | ||||||||
533 | const DSAVarData | ||||||||
534 | getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, | ||||||||
535 | BinaryOperatorKind &BOK, | ||||||||
536 | Expr *&TaskgroupDescriptor) const; | ||||||||
537 | /// Returns the location and reduction operation from the innermost parent | ||||||||
538 | /// region for the given \p D. | ||||||||
539 | const DSAVarData | ||||||||
540 | getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, | ||||||||
541 | const Expr *&ReductionRef, | ||||||||
542 | Expr *&TaskgroupDescriptor) const; | ||||||||
543 | /// Return reduction reference expression for the current taskgroup or | ||||||||
544 | /// parallel/worksharing directives with task reductions. | ||||||||
545 | Expr *getTaskgroupReductionRef() const { | ||||||||
546 | assert((getTopOfStack().Directive == OMPD_taskgroup ||(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "taskgroup reference expression requested for non taskgroup or " "parallel/worksharing directive.") ? static_cast<void> (0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 551, __PRETTY_FUNCTION__)) | ||||||||
547 | ((isOpenMPParallelDirective(getTopOfStack().Directive) ||(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "taskgroup reference expression requested for non taskgroup or " "parallel/worksharing directive.") ? static_cast<void> (0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 551, __PRETTY_FUNCTION__)) | ||||||||
548 | isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "taskgroup reference expression requested for non taskgroup or " "parallel/worksharing directive.") ? static_cast<void> (0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 551, __PRETTY_FUNCTION__)) | ||||||||
549 | !isOpenMPSimdDirective(getTopOfStack().Directive))) &&(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "taskgroup reference expression requested for non taskgroup or " "parallel/worksharing directive.") ? static_cast<void> (0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 551, __PRETTY_FUNCTION__)) | ||||||||
550 | "taskgroup reference expression requested for non taskgroup or "(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "taskgroup reference expression requested for non taskgroup or " "parallel/worksharing directive.") ? static_cast<void> (0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 551, __PRETTY_FUNCTION__)) | ||||||||
551 | "parallel/worksharing directive.")(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "taskgroup reference expression requested for non taskgroup or " "parallel/worksharing directive.") ? static_cast<void> (0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 551, __PRETTY_FUNCTION__)); | ||||||||
552 | return getTopOfStack().TaskgroupReductionRef; | ||||||||
553 | } | ||||||||
554 | /// Checks if the given \p VD declaration is actually a taskgroup reduction | ||||||||
555 | /// descriptor variable at the \p Level of OpenMP regions. | ||||||||
556 | bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { | ||||||||
557 | return getStackElemAtLevel(Level).TaskgroupReductionRef && | ||||||||
558 | cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) | ||||||||
559 | ->getDecl() == VD; | ||||||||
560 | } | ||||||||
561 | |||||||||
562 | /// Returns data sharing attributes from top of the stack for the | ||||||||
563 | /// specified declaration. | ||||||||
564 | const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); | ||||||||
565 | /// Returns data-sharing attributes for the specified declaration. | ||||||||
566 | const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; | ||||||||
567 | /// Returns data-sharing attributes for the specified declaration. | ||||||||
568 | const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const; | ||||||||
569 | /// Checks if the specified variables has data-sharing attributes which | ||||||||
570 | /// match specified \a CPred predicate in any directive which matches \a DPred | ||||||||
571 | /// predicate. | ||||||||
572 | const DSAVarData | ||||||||
573 | hasDSA(ValueDecl *D, | ||||||||
574 | const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, | ||||||||
575 | const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, | ||||||||
576 | bool FromParent) const; | ||||||||
577 | /// Checks if the specified variables has data-sharing attributes which | ||||||||
578 | /// match specified \a CPred predicate in any innermost directive which | ||||||||
579 | /// matches \a DPred predicate. | ||||||||
580 | const DSAVarData | ||||||||
581 | hasInnermostDSA(ValueDecl *D, | ||||||||
582 | const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, | ||||||||
583 | const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, | ||||||||
584 | bool FromParent) const; | ||||||||
585 | /// Checks if the specified variables has explicit data-sharing | ||||||||
586 | /// attributes which match specified \a CPred predicate at the specified | ||||||||
587 | /// OpenMP region. | ||||||||
588 | bool | ||||||||
589 | hasExplicitDSA(const ValueDecl *D, | ||||||||
590 | const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, | ||||||||
591 | unsigned Level, bool NotLastprivate = false) const; | ||||||||
592 | |||||||||
593 | /// Returns true if the directive at level \Level matches in the | ||||||||
594 | /// specified \a DPred predicate. | ||||||||
595 | bool hasExplicitDirective( | ||||||||
596 | const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, | ||||||||
597 | unsigned Level) const; | ||||||||
598 | |||||||||
599 | /// Finds a directive which matches specified \a DPred predicate. | ||||||||
600 | bool hasDirective( | ||||||||
601 | const llvm::function_ref<bool( | ||||||||
602 | OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> | ||||||||
603 | DPred, | ||||||||
604 | bool FromParent) const; | ||||||||
605 | |||||||||
606 | /// Returns currently analyzed directive. | ||||||||
607 | OpenMPDirectiveKind getCurrentDirective() const { | ||||||||
608 | const SharingMapTy *Top = getTopOfStackOrNull(); | ||||||||
609 | return Top ? Top->Directive : OMPD_unknown; | ||||||||
610 | } | ||||||||
611 | /// Returns directive kind at specified level. | ||||||||
612 | OpenMPDirectiveKind getDirective(unsigned Level) const { | ||||||||
613 | assert(!isStackEmpty() && "No directive at specified level.")((!isStackEmpty() && "No directive at specified level." ) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"No directive at specified level.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 613, __PRETTY_FUNCTION__)); | ||||||||
614 | return getStackElemAtLevel(Level).Directive; | ||||||||
615 | } | ||||||||
616 | /// Returns the capture region at the specified level. | ||||||||
617 | OpenMPDirectiveKind getCaptureRegion(unsigned Level, | ||||||||
618 | unsigned OpenMPCaptureLevel) const { | ||||||||
619 | SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; | ||||||||
620 | getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); | ||||||||
621 | return CaptureRegions[OpenMPCaptureLevel]; | ||||||||
622 | } | ||||||||
623 | /// Returns parent directive. | ||||||||
624 | OpenMPDirectiveKind getParentDirective() const { | ||||||||
625 | const SharingMapTy *Parent = getSecondOnStackOrNull(); | ||||||||
626 | return Parent ? Parent->Directive : OMPD_unknown; | ||||||||
627 | } | ||||||||
628 | |||||||||
629 | /// Add requires decl to internal vector | ||||||||
630 | void addRequiresDecl(OMPRequiresDecl *RD) { | ||||||||
631 | RequiresDecls.push_back(RD); | ||||||||
632 | } | ||||||||
633 | |||||||||
634 | /// Checks if the defined 'requires' directive has specified type of clause. | ||||||||
635 | template <typename ClauseType> | ||||||||
636 | bool hasRequiresDeclWithClause() const { | ||||||||
637 | return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { | ||||||||
638 | return llvm::any_of(D->clauselists(), [](const OMPClause *C) { | ||||||||
639 | return isa<ClauseType>(C); | ||||||||
640 | }); | ||||||||
641 | }); | ||||||||
642 | } | ||||||||
643 | |||||||||
644 | /// Checks for a duplicate clause amongst previously declared requires | ||||||||
645 | /// directives | ||||||||
646 | bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { | ||||||||
647 | bool IsDuplicate = false; | ||||||||
648 | for (OMPClause *CNew : ClauseList) { | ||||||||
649 | for (const OMPRequiresDecl *D : RequiresDecls) { | ||||||||
650 | for (const OMPClause *CPrev : D->clauselists()) { | ||||||||
651 | if (CNew->getClauseKind() == CPrev->getClauseKind()) { | ||||||||
652 | SemaRef.Diag(CNew->getBeginLoc(), | ||||||||
653 | diag::err_omp_requires_clause_redeclaration) | ||||||||
654 | << getOpenMPClauseName(CNew->getClauseKind()); | ||||||||
655 | SemaRef.Diag(CPrev->getBeginLoc(), | ||||||||
656 | diag::note_omp_requires_previous_clause) | ||||||||
657 | << getOpenMPClauseName(CPrev->getClauseKind()); | ||||||||
658 | IsDuplicate = true; | ||||||||
659 | } | ||||||||
660 | } | ||||||||
661 | } | ||||||||
662 | } | ||||||||
663 | return IsDuplicate; | ||||||||
664 | } | ||||||||
665 | |||||||||
666 | /// Add location of previously encountered target to internal vector | ||||||||
667 | void addTargetDirLocation(SourceLocation LocStart) { | ||||||||
668 | TargetLocations.push_back(LocStart); | ||||||||
669 | } | ||||||||
670 | |||||||||
671 | /// Add location for the first encountered atomicc directive. | ||||||||
672 | void addAtomicDirectiveLoc(SourceLocation Loc) { | ||||||||
673 | if (AtomicLocation.isInvalid()) | ||||||||
674 | AtomicLocation = Loc; | ||||||||
675 | } | ||||||||
676 | |||||||||
677 | /// Returns the location of the first encountered atomic directive in the | ||||||||
678 | /// module. | ||||||||
679 | SourceLocation getAtomicDirectiveLoc() const { | ||||||||
680 | return AtomicLocation; | ||||||||
681 | } | ||||||||
682 | |||||||||
683 | // Return previously encountered target region locations. | ||||||||
684 | ArrayRef<SourceLocation> getEncounteredTargetLocs() const { | ||||||||
685 | return TargetLocations; | ||||||||
686 | } | ||||||||
687 | |||||||||
688 | /// Set default data sharing attribute to none. | ||||||||
689 | void setDefaultDSANone(SourceLocation Loc) { | ||||||||
690 | getTopOfStack().DefaultAttr = DSA_none; | ||||||||
691 | getTopOfStack().DefaultAttrLoc = Loc; | ||||||||
692 | } | ||||||||
693 | /// Set default data sharing attribute to shared. | ||||||||
694 | void setDefaultDSAShared(SourceLocation Loc) { | ||||||||
695 | getTopOfStack().DefaultAttr = DSA_shared; | ||||||||
696 | getTopOfStack().DefaultAttrLoc = Loc; | ||||||||
697 | } | ||||||||
698 | /// Set default data sharing attribute to firstprivate. | ||||||||
699 | void setDefaultDSAFirstPrivate(SourceLocation Loc) { | ||||||||
700 | getTopOfStack().DefaultAttr = DSA_firstprivate; | ||||||||
701 | getTopOfStack().DefaultAttrLoc = Loc; | ||||||||
702 | } | ||||||||
703 | /// Set default data mapping attribute to Modifier:Kind | ||||||||
704 | void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, | ||||||||
705 | OpenMPDefaultmapClauseKind Kind, | ||||||||
706 | SourceLocation Loc) { | ||||||||
707 | DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind]; | ||||||||
708 | DMI.ImplicitBehavior = M; | ||||||||
709 | DMI.SLoc = Loc; | ||||||||
710 | } | ||||||||
711 | /// Check whether the implicit-behavior has been set in defaultmap | ||||||||
712 | bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) { | ||||||||
713 | if (VariableCategory == OMPC_DEFAULTMAP_unknown) | ||||||||
714 | return getTopOfStack() | ||||||||
715 | .DefaultmapMap[OMPC_DEFAULTMAP_aggregate] | ||||||||
716 | .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || | ||||||||
717 | getTopOfStack() | ||||||||
718 | .DefaultmapMap[OMPC_DEFAULTMAP_scalar] | ||||||||
719 | .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || | ||||||||
720 | getTopOfStack() | ||||||||
721 | .DefaultmapMap[OMPC_DEFAULTMAP_pointer] | ||||||||
722 | .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown; | ||||||||
723 | return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior != | ||||||||
724 | OMPC_DEFAULTMAP_MODIFIER_unknown; | ||||||||
725 | } | ||||||||
726 | |||||||||
727 | DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const { | ||||||||
728 | return getStackSize() <= Level ? DSA_unspecified | ||||||||
729 | : getStackElemAtLevel(Level).DefaultAttr; | ||||||||
730 | } | ||||||||
731 | DefaultDataSharingAttributes getDefaultDSA() const { | ||||||||
732 | return isStackEmpty() ? DSA_unspecified | ||||||||
733 | : getTopOfStack().DefaultAttr; | ||||||||
734 | } | ||||||||
735 | SourceLocation getDefaultDSALocation() const { | ||||||||
736 | return isStackEmpty() ? SourceLocation() | ||||||||
737 | : getTopOfStack().DefaultAttrLoc; | ||||||||
738 | } | ||||||||
739 | OpenMPDefaultmapClauseModifier | ||||||||
740 | getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const { | ||||||||
741 | return isStackEmpty() | ||||||||
742 | ? OMPC_DEFAULTMAP_MODIFIER_unknown | ||||||||
743 | : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior; | ||||||||
744 | } | ||||||||
745 | OpenMPDefaultmapClauseModifier | ||||||||
746 | getDefaultmapModifierAtLevel(unsigned Level, | ||||||||
747 | OpenMPDefaultmapClauseKind Kind) const { | ||||||||
748 | return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior; | ||||||||
749 | } | ||||||||
750 | bool isDefaultmapCapturedByRef(unsigned Level, | ||||||||
751 | OpenMPDefaultmapClauseKind Kind) const { | ||||||||
752 | OpenMPDefaultmapClauseModifier M = | ||||||||
753 | getDefaultmapModifierAtLevel(Level, Kind); | ||||||||
754 | if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) { | ||||||||
755 | return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) || | ||||||||
756 | (M == OMPC_DEFAULTMAP_MODIFIER_to) || | ||||||||
757 | (M == OMPC_DEFAULTMAP_MODIFIER_from) || | ||||||||
758 | (M == OMPC_DEFAULTMAP_MODIFIER_tofrom); | ||||||||
759 | } | ||||||||
760 | return true; | ||||||||
761 | } | ||||||||
762 | static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M, | ||||||||
763 | OpenMPDefaultmapClauseKind Kind) { | ||||||||
764 | switch (Kind) { | ||||||||
765 | case OMPC_DEFAULTMAP_scalar: | ||||||||
766 | case OMPC_DEFAULTMAP_pointer: | ||||||||
767 | return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) || | ||||||||
768 | (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) || | ||||||||
769 | (M == OMPC_DEFAULTMAP_MODIFIER_default); | ||||||||
770 | case OMPC_DEFAULTMAP_aggregate: | ||||||||
771 | return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate; | ||||||||
772 | default: | ||||||||
773 | break; | ||||||||
774 | } | ||||||||
775 | llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum")::llvm::llvm_unreachable_internal("Unexpected OpenMPDefaultmapClauseKind enum" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 775); | ||||||||
776 | } | ||||||||
777 | bool mustBeFirstprivateAtLevel(unsigned Level, | ||||||||
778 | OpenMPDefaultmapClauseKind Kind) const { | ||||||||
779 | OpenMPDefaultmapClauseModifier M = | ||||||||
780 | getDefaultmapModifierAtLevel(Level, Kind); | ||||||||
781 | return mustBeFirstprivateBase(M, Kind); | ||||||||
782 | } | ||||||||
783 | bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const { | ||||||||
784 | OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind); | ||||||||
785 | return mustBeFirstprivateBase(M, Kind); | ||||||||
786 | } | ||||||||
787 | |||||||||
788 | /// Checks if the specified variable is a threadprivate. | ||||||||
789 | bool isThreadPrivate(VarDecl *D) { | ||||||||
790 | const DSAVarData DVar = getTopDSA(D, false); | ||||||||
791 | return isOpenMPThreadPrivate(DVar.CKind); | ||||||||
792 | } | ||||||||
793 | |||||||||
794 | /// Marks current region as ordered (it has an 'ordered' clause). | ||||||||
795 | void setOrderedRegion(bool IsOrdered, const Expr *Param, | ||||||||
796 | OMPOrderedClause *Clause) { | ||||||||
797 | if (IsOrdered) | ||||||||
798 | getTopOfStack().OrderedRegion.emplace(Param, Clause); | ||||||||
799 | else | ||||||||
800 | getTopOfStack().OrderedRegion.reset(); | ||||||||
801 | } | ||||||||
802 | /// Returns true, if region is ordered (has associated 'ordered' clause), | ||||||||
803 | /// false - otherwise. | ||||||||
804 | bool isOrderedRegion() const { | ||||||||
805 | if (const SharingMapTy *Top = getTopOfStackOrNull()) | ||||||||
806 | return Top->OrderedRegion.hasValue(); | ||||||||
807 | return false; | ||||||||
808 | } | ||||||||
809 | /// Returns optional parameter for the ordered region. | ||||||||
810 | std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { | ||||||||
811 | if (const SharingMapTy *Top = getTopOfStackOrNull()) | ||||||||
812 | if (Top->OrderedRegion.hasValue()) | ||||||||
813 | return Top->OrderedRegion.getValue(); | ||||||||
814 | return std::make_pair(nullptr, nullptr); | ||||||||
815 | } | ||||||||
816 | /// Returns true, if parent region is ordered (has associated | ||||||||
817 | /// 'ordered' clause), false - otherwise. | ||||||||
818 | bool isParentOrderedRegion() const { | ||||||||
819 | if (const SharingMapTy *Parent = getSecondOnStackOrNull()) | ||||||||
820 | return Parent->OrderedRegion.hasValue(); | ||||||||
821 | return false; | ||||||||
822 | } | ||||||||
823 | /// Returns optional parameter for the ordered region. | ||||||||
824 | std::pair<const Expr *, OMPOrderedClause *> | ||||||||
825 | getParentOrderedRegionParam() const { | ||||||||
826 | if (const SharingMapTy *Parent = getSecondOnStackOrNull()) | ||||||||
827 | if (Parent->OrderedRegion.hasValue()) | ||||||||
828 | return Parent->OrderedRegion.getValue(); | ||||||||
829 | return std::make_pair(nullptr, nullptr); | ||||||||
830 | } | ||||||||
831 | /// Marks current region as nowait (it has a 'nowait' clause). | ||||||||
832 | void setNowaitRegion(bool IsNowait = true) { | ||||||||
833 | getTopOfStack().NowaitRegion = IsNowait; | ||||||||
834 | } | ||||||||
835 | /// Returns true, if parent region is nowait (has associated | ||||||||
836 | /// 'nowait' clause), false - otherwise. | ||||||||
837 | bool isParentNowaitRegion() const { | ||||||||
838 | if (const SharingMapTy *Parent = getSecondOnStackOrNull()) | ||||||||
839 | return Parent->NowaitRegion; | ||||||||
840 | return false; | ||||||||
841 | } | ||||||||
842 | /// Marks parent region as cancel region. | ||||||||
843 | void setParentCancelRegion(bool Cancel = true) { | ||||||||
844 | if (SharingMapTy *Parent = getSecondOnStackOrNull()) | ||||||||
845 | Parent->CancelRegion |= Cancel; | ||||||||
846 | } | ||||||||
847 | /// Return true if current region has inner cancel construct. | ||||||||
848 | bool isCancelRegion() const { | ||||||||
849 | const SharingMapTy *Top = getTopOfStackOrNull(); | ||||||||
850 | return Top ? Top->CancelRegion : false; | ||||||||
851 | } | ||||||||
852 | |||||||||
853 | /// Mark that parent region already has scan directive. | ||||||||
854 | void setParentHasScanDirective(SourceLocation Loc) { | ||||||||
855 | if (SharingMapTy *Parent = getSecondOnStackOrNull()) | ||||||||
856 | Parent->PrevScanLocation = Loc; | ||||||||
857 | } | ||||||||
858 | /// Return true if current region has inner cancel construct. | ||||||||
859 | bool doesParentHasScanDirective() const { | ||||||||
860 | const SharingMapTy *Top = getSecondOnStackOrNull(); | ||||||||
861 | return Top ? Top->PrevScanLocation.isValid() : false; | ||||||||
862 | } | ||||||||
863 | /// Return true if current region has inner cancel construct. | ||||||||
864 | SourceLocation getParentScanDirectiveLoc() const { | ||||||||
865 | const SharingMapTy *Top = getSecondOnStackOrNull(); | ||||||||
866 | return Top ? Top->PrevScanLocation : SourceLocation(); | ||||||||
867 | } | ||||||||
868 | /// Mark that parent region already has ordered directive. | ||||||||
869 | void setParentHasOrderedDirective(SourceLocation Loc) { | ||||||||
870 | if (SharingMapTy *Parent = getSecondOnStackOrNull()) | ||||||||
871 | Parent->PrevOrderedLocation = Loc; | ||||||||
872 | } | ||||||||
873 | /// Return true if current region has inner ordered construct. | ||||||||
874 | bool doesParentHasOrderedDirective() const { | ||||||||
875 | const SharingMapTy *Top = getSecondOnStackOrNull(); | ||||||||
876 | return Top ? Top->PrevOrderedLocation.isValid() : false; | ||||||||
877 | } | ||||||||
878 | /// Returns the location of the previously specified ordered directive. | ||||||||
879 | SourceLocation getParentOrderedDirectiveLoc() const { | ||||||||
880 | const SharingMapTy *Top = getSecondOnStackOrNull(); | ||||||||
881 | return Top ? Top->PrevOrderedLocation : SourceLocation(); | ||||||||
882 | } | ||||||||
883 | |||||||||
884 | /// Set collapse value for the region. | ||||||||
885 | void setAssociatedLoops(unsigned Val) { | ||||||||
886 | getTopOfStack().AssociatedLoops = Val; | ||||||||
887 | if (Val > 1) | ||||||||
888 | getTopOfStack().HasMutipleLoops = true; | ||||||||
889 | } | ||||||||
890 | /// Return collapse value for region. | ||||||||
891 | unsigned getAssociatedLoops() const { | ||||||||
892 | const SharingMapTy *Top = getTopOfStackOrNull(); | ||||||||
893 | return Top ? Top->AssociatedLoops : 0; | ||||||||
894 | } | ||||||||
895 | /// Returns true if the construct is associated with multiple loops. | ||||||||
896 | bool hasMutipleLoops() const { | ||||||||
897 | const SharingMapTy *Top = getTopOfStackOrNull(); | ||||||||
898 | return Top ? Top->HasMutipleLoops : false; | ||||||||
899 | } | ||||||||
900 | |||||||||
901 | /// Marks current target region as one with closely nested teams | ||||||||
902 | /// region. | ||||||||
903 | void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { | ||||||||
904 | if (SharingMapTy *Parent = getSecondOnStackOrNull()) | ||||||||
905 | Parent->InnerTeamsRegionLoc = TeamsRegionLoc; | ||||||||
906 | } | ||||||||
907 | /// Returns true, if current region has closely nested teams region. | ||||||||
908 | bool hasInnerTeamsRegion() const { | ||||||||
909 | return getInnerTeamsRegionLoc().isValid(); | ||||||||
910 | } | ||||||||
911 | /// Returns location of the nested teams region (if any). | ||||||||
912 | SourceLocation getInnerTeamsRegionLoc() const { | ||||||||
913 | const SharingMapTy *Top = getTopOfStackOrNull(); | ||||||||
914 | return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); | ||||||||
915 | } | ||||||||
916 | |||||||||
917 | Scope *getCurScope() const { | ||||||||
918 | const SharingMapTy *Top = getTopOfStackOrNull(); | ||||||||
919 | return Top ? Top->CurScope : nullptr; | ||||||||
920 | } | ||||||||
921 | SourceLocation getConstructLoc() const { | ||||||||
922 | const SharingMapTy *Top = getTopOfStackOrNull(); | ||||||||
923 | return Top ? Top->ConstructLoc : SourceLocation(); | ||||||||
924 | } | ||||||||
925 | |||||||||
926 | /// Do the check specified in \a Check to all component lists and return true | ||||||||
927 | /// if any issue is found. | ||||||||
928 | bool checkMappableExprComponentListsForDecl( | ||||||||
929 | const ValueDecl *VD, bool CurrentRegionOnly, | ||||||||
930 | const llvm::function_ref< | ||||||||
931 | bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, | ||||||||
932 | OpenMPClauseKind)> | ||||||||
933 | Check) const { | ||||||||
934 | if (isStackEmpty()) | ||||||||
935 | return false; | ||||||||
936 | auto SI = begin(); | ||||||||
937 | auto SE = end(); | ||||||||
938 | |||||||||
939 | if (SI == SE) | ||||||||
940 | return false; | ||||||||
941 | |||||||||
942 | if (CurrentRegionOnly) | ||||||||
943 | SE = std::next(SI); | ||||||||
944 | else | ||||||||
945 | std::advance(SI, 1); | ||||||||
946 | |||||||||
947 | for (; SI != SE; ++SI) { | ||||||||
948 | auto MI = SI->MappedExprComponents.find(VD); | ||||||||
949 | if (MI != SI->MappedExprComponents.end()) | ||||||||
950 | for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : | ||||||||
951 | MI->second.Components) | ||||||||
952 | if (Check(L, MI->second.Kind)) | ||||||||
953 | return true; | ||||||||
954 | } | ||||||||
955 | return false; | ||||||||
956 | } | ||||||||
957 | |||||||||
958 | /// Do the check specified in \a Check to all component lists at a given level | ||||||||
959 | /// and return true if any issue is found. | ||||||||
960 | bool checkMappableExprComponentListsForDeclAtLevel( | ||||||||
961 | const ValueDecl *VD, unsigned Level, | ||||||||
962 | const llvm::function_ref< | ||||||||
963 | bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, | ||||||||
964 | OpenMPClauseKind)> | ||||||||
965 | Check) const { | ||||||||
966 | if (getStackSize() <= Level) | ||||||||
967 | return false; | ||||||||
968 | |||||||||
969 | const SharingMapTy &StackElem = getStackElemAtLevel(Level); | ||||||||
970 | auto MI = StackElem.MappedExprComponents.find(VD); | ||||||||
971 | if (MI != StackElem.MappedExprComponents.end()) | ||||||||
972 | for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : | ||||||||
973 | MI->second.Components) | ||||||||
974 | if (Check(L, MI->second.Kind)) | ||||||||
975 | return true; | ||||||||
976 | return false; | ||||||||
977 | } | ||||||||
978 | |||||||||
979 | /// Create a new mappable expression component list associated with a given | ||||||||
980 | /// declaration and initialize it with the provided list of components. | ||||||||
981 | void addMappableExpressionComponents( | ||||||||
982 | const ValueDecl *VD, | ||||||||
983 | OMPClauseMappableExprCommon::MappableExprComponentListRef Components, | ||||||||
984 | OpenMPClauseKind WhereFoundClauseKind) { | ||||||||
985 | MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; | ||||||||
986 | // Create new entry and append the new components there. | ||||||||
987 | MEC.Components.resize(MEC.Components.size() + 1); | ||||||||
988 | MEC.Components.back().append(Components.begin(), Components.end()); | ||||||||
989 | MEC.Kind = WhereFoundClauseKind; | ||||||||
990 | } | ||||||||
991 | |||||||||
992 | unsigned getNestingLevel() const { | ||||||||
993 | assert(!isStackEmpty())((!isStackEmpty()) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty()", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 993, __PRETTY_FUNCTION__)); | ||||||||
994 | return getStackSize() - 1; | ||||||||
995 | } | ||||||||
996 | void addDoacrossDependClause(OMPDependClause *C, | ||||||||
997 | const OperatorOffsetTy &OpsOffs) { | ||||||||
998 | SharingMapTy *Parent = getSecondOnStackOrNull(); | ||||||||
999 | assert(Parent && isOpenMPWorksharingDirective(Parent->Directive))((Parent && isOpenMPWorksharingDirective(Parent->Directive )) ? static_cast<void> (0) : __assert_fail ("Parent && isOpenMPWorksharingDirective(Parent->Directive)" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 999, __PRETTY_FUNCTION__)); | ||||||||
1000 | Parent->DoacrossDepends.try_emplace(C, OpsOffs); | ||||||||
1001 | } | ||||||||
1002 | llvm::iterator_range<DoacrossDependMapTy::const_iterator> | ||||||||
1003 | getDoacrossDependClauses() const { | ||||||||
1004 | const SharingMapTy &StackElem = getTopOfStack(); | ||||||||
1005 | if (isOpenMPWorksharingDirective(StackElem.Directive)) { | ||||||||
1006 | const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; | ||||||||
1007 | return llvm::make_range(Ref.begin(), Ref.end()); | ||||||||
1008 | } | ||||||||
1009 | return llvm::make_range(StackElem.DoacrossDepends.end(), | ||||||||
1010 | StackElem.DoacrossDepends.end()); | ||||||||
1011 | } | ||||||||
1012 | |||||||||
1013 | // Store types of classes which have been explicitly mapped | ||||||||
1014 | void addMappedClassesQualTypes(QualType QT) { | ||||||||
1015 | SharingMapTy &StackElem = getTopOfStack(); | ||||||||
1016 | StackElem.MappedClassesQualTypes.insert(QT); | ||||||||
1017 | } | ||||||||
1018 | |||||||||
1019 | // Return set of mapped classes types | ||||||||
1020 | bool isClassPreviouslyMapped(QualType QT) const { | ||||||||
1021 | const SharingMapTy &StackElem = getTopOfStack(); | ||||||||
1022 | return StackElem.MappedClassesQualTypes.count(QT) != 0; | ||||||||
1023 | } | ||||||||
1024 | |||||||||
1025 | /// Adds global declare target to the parent target region. | ||||||||
1026 | void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { | ||||||||
1027 | assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(((*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E-> getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && "Expected declare target link global." ) ? static_cast<void> (0) : __assert_fail ("*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && \"Expected declare target link global.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1029, __PRETTY_FUNCTION__)) | ||||||||
1028 | E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&((*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E-> getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && "Expected declare target link global." ) ? static_cast<void> (0) : __assert_fail ("*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && \"Expected declare target link global.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1029, __PRETTY_FUNCTION__)) | ||||||||
1029 | "Expected declare target link global.")((*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E-> getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && "Expected declare target link global." ) ? static_cast<void> (0) : __assert_fail ("*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && \"Expected declare target link global.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1029, __PRETTY_FUNCTION__)); | ||||||||
1030 | for (auto &Elem : *this) { | ||||||||
1031 | if (isOpenMPTargetExecutionDirective(Elem.Directive)) { | ||||||||
1032 | Elem.DeclareTargetLinkVarDecls.push_back(E); | ||||||||
1033 | return; | ||||||||
1034 | } | ||||||||
1035 | } | ||||||||
1036 | } | ||||||||
1037 | |||||||||
1038 | /// Returns the list of globals with declare target link if current directive | ||||||||
1039 | /// is target. | ||||||||
1040 | ArrayRef<DeclRefExpr *> getLinkGlobals() const { | ||||||||
1041 | assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&((isOpenMPTargetExecutionDirective(getCurrentDirective()) && "Expected target executable directive.") ? static_cast<void > (0) : __assert_fail ("isOpenMPTargetExecutionDirective(getCurrentDirective()) && \"Expected target executable directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1042, __PRETTY_FUNCTION__)) | ||||||||
1042 | "Expected target executable directive.")((isOpenMPTargetExecutionDirective(getCurrentDirective()) && "Expected target executable directive.") ? static_cast<void > (0) : __assert_fail ("isOpenMPTargetExecutionDirective(getCurrentDirective()) && \"Expected target executable directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1042, __PRETTY_FUNCTION__)); | ||||||||
1043 | return getTopOfStack().DeclareTargetLinkVarDecls; | ||||||||
1044 | } | ||||||||
1045 | |||||||||
1046 | /// Adds list of allocators expressions. | ||||||||
1047 | void addInnerAllocatorExpr(Expr *E) { | ||||||||
1048 | getTopOfStack().InnerUsedAllocators.push_back(E); | ||||||||
1049 | } | ||||||||
1050 | /// Return list of used allocators. | ||||||||
1051 | ArrayRef<Expr *> getInnerAllocators() const { | ||||||||
1052 | return getTopOfStack().InnerUsedAllocators; | ||||||||
1053 | } | ||||||||
1054 | /// Marks the declaration as implicitly firstprivate nin the task-based | ||||||||
1055 | /// regions. | ||||||||
1056 | void addImplicitTaskFirstprivate(unsigned Level, Decl *D) { | ||||||||
1057 | getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D); | ||||||||
1058 | } | ||||||||
1059 | /// Checks if the decl is implicitly firstprivate in the task-based region. | ||||||||
1060 | bool isImplicitTaskFirstprivate(Decl *D) const { | ||||||||
1061 | return getTopOfStack().ImplicitTaskFirstprivates.count(D) > 0; | ||||||||
1062 | } | ||||||||
1063 | |||||||||
1064 | /// Marks decl as used in uses_allocators clause as the allocator. | ||||||||
1065 | void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) { | ||||||||
1066 | getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind); | ||||||||
1067 | } | ||||||||
1068 | /// Checks if specified decl is used in uses allocator clause as the | ||||||||
1069 | /// allocator. | ||||||||
1070 | Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level, | ||||||||
1071 | const Decl *D) const { | ||||||||
1072 | const SharingMapTy &StackElem = getTopOfStack(); | ||||||||
1073 | auto I = StackElem.UsesAllocatorsDecls.find(D); | ||||||||
1074 | if (I == StackElem.UsesAllocatorsDecls.end()) | ||||||||
1075 | return None; | ||||||||
1076 | return I->getSecond(); | ||||||||
1077 | } | ||||||||
1078 | Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const { | ||||||||
1079 | const SharingMapTy &StackElem = getTopOfStack(); | ||||||||
1080 | auto I = StackElem.UsesAllocatorsDecls.find(D); | ||||||||
1081 | if (I == StackElem.UsesAllocatorsDecls.end()) | ||||||||
1082 | return None; | ||||||||
1083 | return I->getSecond(); | ||||||||
1084 | } | ||||||||
1085 | |||||||||
1086 | void addDeclareMapperVarRef(Expr *Ref) { | ||||||||
1087 | SharingMapTy &StackElem = getTopOfStack(); | ||||||||
1088 | StackElem.DeclareMapperVar = Ref; | ||||||||
1089 | } | ||||||||
1090 | const Expr *getDeclareMapperVarRef() const { | ||||||||
1091 | const SharingMapTy *Top = getTopOfStackOrNull(); | ||||||||
1092 | return Top ? Top->DeclareMapperVar : nullptr; | ||||||||
1093 | } | ||||||||
1094 | }; | ||||||||
1095 | |||||||||
1096 | bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { | ||||||||
1097 | return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); | ||||||||
1098 | } | ||||||||
1099 | |||||||||
1100 | bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { | ||||||||
1101 | return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || | ||||||||
1102 | DKind == OMPD_unknown; | ||||||||
1103 | } | ||||||||
1104 | |||||||||
1105 | } // namespace | ||||||||
1106 | |||||||||
1107 | static const Expr *getExprAsWritten(const Expr *E) { | ||||||||
1108 | if (const auto *FE = dyn_cast<FullExpr>(E)) | ||||||||
1109 | E = FE->getSubExpr(); | ||||||||
1110 | |||||||||
1111 | if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) | ||||||||
1112 | E = MTE->getSubExpr(); | ||||||||
1113 | |||||||||
1114 | while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) | ||||||||
1115 | E = Binder->getSubExpr(); | ||||||||
1116 | |||||||||
1117 | if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) | ||||||||
1118 | E = ICE->getSubExprAsWritten(); | ||||||||
1119 | return E->IgnoreParens(); | ||||||||
1120 | } | ||||||||
1121 | |||||||||
1122 | static Expr *getExprAsWritten(Expr *E) { | ||||||||
1123 | return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); | ||||||||
1124 | } | ||||||||
1125 | |||||||||
1126 | static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { | ||||||||
1127 | if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) | ||||||||
1128 | if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) | ||||||||
1129 | D = ME->getMemberDecl(); | ||||||||
1130 | const auto *VD = dyn_cast<VarDecl>(D); | ||||||||
1131 | const auto *FD = dyn_cast<FieldDecl>(D); | ||||||||
1132 | if (VD != nullptr) { | ||||||||
1133 | VD = VD->getCanonicalDecl(); | ||||||||
1134 | D = VD; | ||||||||
1135 | } else { | ||||||||
1136 | assert(FD)((FD) ? static_cast<void> (0) : __assert_fail ("FD", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1136, __PRETTY_FUNCTION__)); | ||||||||
1137 | FD = FD->getCanonicalDecl(); | ||||||||
1138 | D = FD; | ||||||||
1139 | } | ||||||||
1140 | return D; | ||||||||
1141 | } | ||||||||
1142 | |||||||||
1143 | static ValueDecl *getCanonicalDecl(ValueDecl *D) { | ||||||||
1144 | return const_cast<ValueDecl *>( | ||||||||
1145 | getCanonicalDecl(const_cast<const ValueDecl *>(D))); | ||||||||
1146 | } | ||||||||
1147 | |||||||||
1148 | DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, | ||||||||
1149 | ValueDecl *D) const { | ||||||||
1150 | D = getCanonicalDecl(D); | ||||||||
1151 | auto *VD = dyn_cast<VarDecl>(D); | ||||||||
1152 | const auto *FD = dyn_cast<FieldDecl>(D); | ||||||||
1153 | DSAVarData DVar; | ||||||||
1154 | if (Iter == end()) { | ||||||||
1155 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||||
1156 | // in a region but not in construct] | ||||||||
1157 | // File-scope or namespace-scope variables referenced in called routines | ||||||||
1158 | // in the region are shared unless they appear in a threadprivate | ||||||||
1159 | // directive. | ||||||||
1160 | if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) | ||||||||
1161 | DVar.CKind = OMPC_shared; | ||||||||
1162 | |||||||||
1163 | // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced | ||||||||
1164 | // in a region but not in construct] | ||||||||
1165 | // Variables with static storage duration that are declared in called | ||||||||
1166 | // routines in the region are shared. | ||||||||
1167 | if (VD && VD->hasGlobalStorage()) | ||||||||
1168 | DVar.CKind = OMPC_shared; | ||||||||
1169 | |||||||||
1170 | // Non-static data members are shared by default. | ||||||||
1171 | if (FD) | ||||||||
1172 | DVar.CKind = OMPC_shared; | ||||||||
1173 | |||||||||
1174 | return DVar; | ||||||||
1175 | } | ||||||||
1176 | |||||||||
1177 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||||
1178 | // in a Construct, C/C++, predetermined, p.1] | ||||||||
1179 | // Variables with automatic storage duration that are declared in a scope | ||||||||
1180 | // inside the construct are private. | ||||||||
1181 | if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && | ||||||||
1182 | (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { | ||||||||
1183 | DVar.CKind = OMPC_private; | ||||||||
1184 | return DVar; | ||||||||
1185 | } | ||||||||
1186 | |||||||||
1187 | DVar.DKind = Iter->Directive; | ||||||||
1188 | // Explicitly specified attributes and local variables with predetermined | ||||||||
1189 | // attributes. | ||||||||
1190 | if (Iter->SharingMap.count(D)) { | ||||||||
1191 | const DSAInfo &Data = Iter->SharingMap.lookup(D); | ||||||||
1192 | DVar.RefExpr = Data.RefExpr.getPointer(); | ||||||||
1193 | DVar.PrivateCopy = Data.PrivateCopy; | ||||||||
1194 | DVar.CKind = Data.Attributes; | ||||||||
1195 | DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; | ||||||||
1196 | DVar.Modifier = Data.Modifier; | ||||||||
1197 | DVar.AppliedToPointee = Data.AppliedToPointee; | ||||||||
1198 | return DVar; | ||||||||
1199 | } | ||||||||
1200 | |||||||||
1201 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||||
1202 | // in a Construct, C/C++, implicitly determined, p.1] | ||||||||
1203 | // In a parallel or task construct, the data-sharing attributes of these | ||||||||
1204 | // variables are determined by the default clause, if present. | ||||||||
1205 | switch (Iter->DefaultAttr) { | ||||||||
1206 | case DSA_shared: | ||||||||
1207 | DVar.CKind = OMPC_shared; | ||||||||
1208 | DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; | ||||||||
1209 | return DVar; | ||||||||
1210 | case DSA_none: | ||||||||
1211 | return DVar; | ||||||||
1212 | case DSA_firstprivate: | ||||||||
1213 | if (VD->getStorageDuration() == SD_Static && | ||||||||
1214 | VD->getDeclContext()->isFileContext()) { | ||||||||
1215 | DVar.CKind = OMPC_unknown; | ||||||||
1216 | } else { | ||||||||
1217 | DVar.CKind = OMPC_firstprivate; | ||||||||
1218 | } | ||||||||
1219 | DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; | ||||||||
1220 | return DVar; | ||||||||
1221 | case DSA_unspecified: | ||||||||
1222 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||||
1223 | // in a Construct, implicitly determined, p.2] | ||||||||
1224 | // In a parallel construct, if no default clause is present, these | ||||||||
1225 | // variables are shared. | ||||||||
1226 | DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; | ||||||||
1227 | if ((isOpenMPParallelDirective(DVar.DKind) && | ||||||||
1228 | !isOpenMPTaskLoopDirective(DVar.DKind)) || | ||||||||
1229 | isOpenMPTeamsDirective(DVar.DKind)) { | ||||||||
1230 | DVar.CKind = OMPC_shared; | ||||||||
1231 | return DVar; | ||||||||
1232 | } | ||||||||
1233 | |||||||||
1234 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||||
1235 | // in a Construct, implicitly determined, p.4] | ||||||||
1236 | // In a task construct, if no default clause is present, a variable that in | ||||||||
1237 | // the enclosing context is determined to be shared by all implicit tasks | ||||||||
1238 | // bound to the current team is shared. | ||||||||
1239 | if (isOpenMPTaskingDirective(DVar.DKind)) { | ||||||||
1240 | DSAVarData DVarTemp; | ||||||||
1241 | const_iterator I = Iter, E = end(); | ||||||||
1242 | do { | ||||||||
1243 | ++I; | ||||||||
1244 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables | ||||||||
1245 | // Referenced in a Construct, implicitly determined, p.6] | ||||||||
1246 | // In a task construct, if no default clause is present, a variable | ||||||||
1247 | // whose data-sharing attribute is not determined by the rules above is | ||||||||
1248 | // firstprivate. | ||||||||
1249 | DVarTemp = getDSA(I, D); | ||||||||
1250 | if (DVarTemp.CKind != OMPC_shared) { | ||||||||
1251 | DVar.RefExpr = nullptr; | ||||||||
1252 | DVar.CKind = OMPC_firstprivate; | ||||||||
1253 | return DVar; | ||||||||
1254 | } | ||||||||
1255 | } while (I != E && !isImplicitTaskingRegion(I->Directive)); | ||||||||
1256 | DVar.CKind = | ||||||||
1257 | (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; | ||||||||
1258 | return DVar; | ||||||||
1259 | } | ||||||||
1260 | } | ||||||||
1261 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||||
1262 | // in a Construct, implicitly determined, p.3] | ||||||||
1263 | // For constructs other than task, if no default clause is present, these | ||||||||
1264 | // variables inherit their data-sharing attributes from the enclosing | ||||||||
1265 | // context. | ||||||||
1266 | return getDSA(++Iter, D); | ||||||||
1267 | } | ||||||||
1268 | |||||||||
1269 | const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, | ||||||||
1270 | const Expr *NewDE) { | ||||||||
1271 | assert(!isStackEmpty() && "Data sharing attributes stack is empty")((!isStackEmpty() && "Data sharing attributes stack is empty" ) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data sharing attributes stack is empty\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1271, __PRETTY_FUNCTION__)); | ||||||||
1272 | D = getCanonicalDecl(D); | ||||||||
1273 | SharingMapTy &StackElem = getTopOfStack(); | ||||||||
1274 | auto It = StackElem.AlignedMap.find(D); | ||||||||
1275 | if (It == StackElem.AlignedMap.end()) { | ||||||||
1276 | assert(NewDE && "Unexpected nullptr expr to be added into aligned map")((NewDE && "Unexpected nullptr expr to be added into aligned map" ) ? static_cast<void> (0) : __assert_fail ("NewDE && \"Unexpected nullptr expr to be added into aligned map\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1276, __PRETTY_FUNCTION__)); | ||||||||
1277 | StackElem.AlignedMap[D] = NewDE; | ||||||||
1278 | return nullptr; | ||||||||
1279 | } | ||||||||
1280 | assert(It->second && "Unexpected nullptr expr in the aligned map")((It->second && "Unexpected nullptr expr in the aligned map" ) ? static_cast<void> (0) : __assert_fail ("It->second && \"Unexpected nullptr expr in the aligned map\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1280, __PRETTY_FUNCTION__)); | ||||||||
1281 | return It->second; | ||||||||
1282 | } | ||||||||
1283 | |||||||||
1284 | const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D, | ||||||||
1285 | const Expr *NewDE) { | ||||||||
1286 | assert(!isStackEmpty() && "Data sharing attributes stack is empty")((!isStackEmpty() && "Data sharing attributes stack is empty" ) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data sharing attributes stack is empty\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1286, __PRETTY_FUNCTION__)); | ||||||||
1287 | D = getCanonicalDecl(D); | ||||||||
1288 | SharingMapTy &StackElem = getTopOfStack(); | ||||||||
1289 | auto It = StackElem.NontemporalMap.find(D); | ||||||||
1290 | if (It == StackElem.NontemporalMap.end()) { | ||||||||
1291 | assert(NewDE && "Unexpected nullptr expr to be added into aligned map")((NewDE && "Unexpected nullptr expr to be added into aligned map" ) ? static_cast<void> (0) : __assert_fail ("NewDE && \"Unexpected nullptr expr to be added into aligned map\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1291, __PRETTY_FUNCTION__)); | ||||||||
1292 | StackElem.NontemporalMap[D] = NewDE; | ||||||||
1293 | return nullptr; | ||||||||
1294 | } | ||||||||
1295 | assert(It->second && "Unexpected nullptr expr in the aligned map")((It->second && "Unexpected nullptr expr in the aligned map" ) ? static_cast<void> (0) : __assert_fail ("It->second && \"Unexpected nullptr expr in the aligned map\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1295, __PRETTY_FUNCTION__)); | ||||||||
1296 | return It->second; | ||||||||
1297 | } | ||||||||
1298 | |||||||||
1299 | void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { | ||||||||
1300 | assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty" ) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1300, __PRETTY_FUNCTION__)); | ||||||||
1301 | D = getCanonicalDecl(D); | ||||||||
1302 | SharingMapTy &StackElem = getTopOfStack(); | ||||||||
1303 | StackElem.LCVMap.try_emplace( | ||||||||
1304 | D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); | ||||||||
1305 | } | ||||||||
1306 | |||||||||
1307 | const DSAStackTy::LCDeclInfo | ||||||||
1308 | DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { | ||||||||
1309 | assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty" ) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1309, __PRETTY_FUNCTION__)); | ||||||||
1310 | D = getCanonicalDecl(D); | ||||||||
1311 | const SharingMapTy &StackElem = getTopOfStack(); | ||||||||
1312 | auto It = StackElem.LCVMap.find(D); | ||||||||
1313 | if (It != StackElem.LCVMap.end()) | ||||||||
1314 | return It->second; | ||||||||
1315 | return {0, nullptr}; | ||||||||
1316 | } | ||||||||
1317 | |||||||||
1318 | const DSAStackTy::LCDeclInfo | ||||||||
1319 | DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const { | ||||||||
1320 | assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty" ) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1320, __PRETTY_FUNCTION__)); | ||||||||
1321 | D = getCanonicalDecl(D); | ||||||||
1322 | for (unsigned I = Level + 1; I > 0; --I) { | ||||||||
1323 | const SharingMapTy &StackElem = getStackElemAtLevel(I - 1); | ||||||||
1324 | auto It = StackElem.LCVMap.find(D); | ||||||||
1325 | if (It != StackElem.LCVMap.end()) | ||||||||
1326 | return It->second; | ||||||||
1327 | } | ||||||||
1328 | return {0, nullptr}; | ||||||||
1329 | } | ||||||||
1330 | |||||||||
1331 | const DSAStackTy::LCDeclInfo | ||||||||
1332 | DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { | ||||||||
1333 | const SharingMapTy *Parent = getSecondOnStackOrNull(); | ||||||||
1334 | assert(Parent && "Data-sharing attributes stack is empty")((Parent && "Data-sharing attributes stack is empty") ? static_cast<void> (0) : __assert_fail ("Parent && \"Data-sharing attributes stack is empty\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1334, __PRETTY_FUNCTION__)); | ||||||||
1335 | D = getCanonicalDecl(D); | ||||||||
1336 | auto It = Parent->LCVMap.find(D); | ||||||||
1337 | if (It != Parent->LCVMap.end()) | ||||||||
1338 | return It->second; | ||||||||
1339 | return {0, nullptr}; | ||||||||
1340 | } | ||||||||
1341 | |||||||||
1342 | const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { | ||||||||
1343 | const SharingMapTy *Parent = getSecondOnStackOrNull(); | ||||||||
1344 | assert(Parent && "Data-sharing attributes stack is empty")((Parent && "Data-sharing attributes stack is empty") ? static_cast<void> (0) : __assert_fail ("Parent && \"Data-sharing attributes stack is empty\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1344, __PRETTY_FUNCTION__)); | ||||||||
1345 | if (Parent->LCVMap.size() < I) | ||||||||
1346 | return nullptr; | ||||||||
1347 | for (const auto &Pair : Parent->LCVMap) | ||||||||
1348 | if (Pair.second.first == I) | ||||||||
1349 | return Pair.first; | ||||||||
1350 | return nullptr; | ||||||||
1351 | } | ||||||||
1352 | |||||||||
1353 | void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, | ||||||||
1354 | DeclRefExpr *PrivateCopy, unsigned Modifier, | ||||||||
1355 | bool AppliedToPointee) { | ||||||||
1356 | D = getCanonicalDecl(D); | ||||||||
1357 | if (A == OMPC_threadprivate) { | ||||||||
1358 | DSAInfo &Data = Threadprivates[D]; | ||||||||
1359 | Data.Attributes = A; | ||||||||
1360 | Data.RefExpr.setPointer(E); | ||||||||
1361 | Data.PrivateCopy = nullptr; | ||||||||
1362 | Data.Modifier = Modifier; | ||||||||
1363 | } else { | ||||||||
1364 | DSAInfo &Data = getTopOfStack().SharingMap[D]; | ||||||||
1365 | assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||((Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate ) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate ) || (isLoopControlVariable(D).first && A == OMPC_private )) ? static_cast<void> (0) : __assert_fail ("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1368, __PRETTY_FUNCTION__)) | ||||||||
1366 | (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||((Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate ) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate ) || (isLoopControlVariable(D).first && A == OMPC_private )) ? static_cast<void> (0) : __assert_fail ("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1368, __PRETTY_FUNCTION__)) | ||||||||
1367 | (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||((Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate ) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate ) || (isLoopControlVariable(D).first && A == OMPC_private )) ? static_cast<void> (0) : __assert_fail ("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1368, __PRETTY_FUNCTION__)) | ||||||||
1368 | (isLoopControlVariable(D).first && A == OMPC_private))((Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate ) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate ) || (isLoopControlVariable(D).first && A == OMPC_private )) ? static_cast<void> (0) : __assert_fail ("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1368, __PRETTY_FUNCTION__)); | ||||||||
1369 | Data.Modifier = Modifier; | ||||||||
1370 | if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { | ||||||||
1371 | Data.RefExpr.setInt(/*IntVal=*/true); | ||||||||
1372 | return; | ||||||||
1373 | } | ||||||||
1374 | const bool IsLastprivate = | ||||||||
1375 | A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; | ||||||||
1376 | Data.Attributes = A; | ||||||||
1377 | Data.RefExpr.setPointerAndInt(E, IsLastprivate); | ||||||||
1378 | Data.PrivateCopy = PrivateCopy; | ||||||||
1379 | Data.AppliedToPointee = AppliedToPointee; | ||||||||
1380 | if (PrivateCopy) { | ||||||||
1381 | DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; | ||||||||
1382 | Data.Modifier = Modifier; | ||||||||
1383 | Data.Attributes = A; | ||||||||
1384 | Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); | ||||||||
1385 | Data.PrivateCopy = nullptr; | ||||||||
1386 | Data.AppliedToPointee = AppliedToPointee; | ||||||||
1387 | } | ||||||||
1388 | } | ||||||||
1389 | } | ||||||||
1390 | |||||||||
1391 | /// Build a variable declaration for OpenMP loop iteration variable. | ||||||||
1392 | static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, | ||||||||
1393 | StringRef Name, const AttrVec *Attrs = nullptr, | ||||||||
1394 | DeclRefExpr *OrigRef = nullptr) { | ||||||||
1395 | DeclContext *DC = SemaRef.CurContext; | ||||||||
1396 | IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); | ||||||||
1397 | TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); | ||||||||
1398 | auto *Decl = | ||||||||
1399 | VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); | ||||||||
1400 | if (Attrs) { | ||||||||
1401 | for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); | ||||||||
1402 | I != E; ++I) | ||||||||
1403 | Decl->addAttr(*I); | ||||||||
1404 | } | ||||||||
1405 | Decl->setImplicit(); | ||||||||
1406 | if (OrigRef) { | ||||||||
1407 | Decl->addAttr( | ||||||||
1408 | OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); | ||||||||
1409 | } | ||||||||
1410 | return Decl; | ||||||||
1411 | } | ||||||||
1412 | |||||||||
1413 | static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, | ||||||||
1414 | SourceLocation Loc, | ||||||||
1415 | bool RefersToCapture = false) { | ||||||||
1416 | D->setReferenced(); | ||||||||
1417 | D->markUsed(S.Context); | ||||||||
1418 | return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), | ||||||||
1419 | SourceLocation(), D, RefersToCapture, Loc, Ty, | ||||||||
1420 | VK_LValue); | ||||||||
1421 | } | ||||||||
1422 | |||||||||
1423 | void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, | ||||||||
1424 | BinaryOperatorKind BOK) { | ||||||||
1425 | D = getCanonicalDecl(D); | ||||||||
1426 | assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty" ) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1426, __PRETTY_FUNCTION__)); | ||||||||
1427 | assert(((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && "Additional reduction info may be specified only for reduction items." ) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1429, __PRETTY_FUNCTION__)) | ||||||||
1428 | getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && "Additional reduction info may be specified only for reduction items." ) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1429, __PRETTY_FUNCTION__)) | ||||||||
1429 | "Additional reduction info may be specified only for reduction items.")((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && "Additional reduction info may be specified only for reduction items." ) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1429, __PRETTY_FUNCTION__)); | ||||||||
1430 | ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; | ||||||||
1431 | assert(ReductionData.ReductionRange.isInvalid() &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1437, __PRETTY_FUNCTION__)) | ||||||||
1432 | (getTopOfStack().Directive == OMPD_taskgroup ||((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1437, __PRETTY_FUNCTION__)) | ||||||||
1433 | ((isOpenMPParallelDirective(getTopOfStack().Directive) ||((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1437, __PRETTY_FUNCTION__)) | ||||||||
1434 | isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1437, __PRETTY_FUNCTION__)) | ||||||||
1435 | !isOpenMPSimdDirective(getTopOfStack().Directive))) &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1437, __PRETTY_FUNCTION__)) | ||||||||
1436 | "Additional reduction info may be specified only once for reduction "((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1437, __PRETTY_FUNCTION__)) | ||||||||
1437 | "items.")((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1437, __PRETTY_FUNCTION__)); | ||||||||
1438 | ReductionData.set(BOK, SR); | ||||||||
1439 | Expr *&TaskgroupReductionRef = | ||||||||
1440 | getTopOfStack().TaskgroupReductionRef; | ||||||||
1441 | if (!TaskgroupReductionRef) { | ||||||||
1442 | VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), | ||||||||
1443 | SemaRef.Context.VoidPtrTy, ".task_red."); | ||||||||
1444 | TaskgroupReductionRef = | ||||||||
1445 | buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); | ||||||||
1446 | } | ||||||||
1447 | } | ||||||||
1448 | |||||||||
1449 | void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, | ||||||||
1450 | const Expr *ReductionRef) { | ||||||||
1451 | D = getCanonicalDecl(D); | ||||||||
1452 | assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty" ) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1452, __PRETTY_FUNCTION__)); | ||||||||
1453 | assert(((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && "Additional reduction info may be specified only for reduction items." ) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1455, __PRETTY_FUNCTION__)) | ||||||||
1454 | getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && "Additional reduction info may be specified only for reduction items." ) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1455, __PRETTY_FUNCTION__)) | ||||||||
1455 | "Additional reduction info may be specified only for reduction items.")((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && "Additional reduction info may be specified only for reduction items." ) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1455, __PRETTY_FUNCTION__)); | ||||||||
1456 | ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; | ||||||||
1457 | assert(ReductionData.ReductionRange.isInvalid() &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1463, __PRETTY_FUNCTION__)) | ||||||||
1458 | (getTopOfStack().Directive == OMPD_taskgroup ||((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1463, __PRETTY_FUNCTION__)) | ||||||||
1459 | ((isOpenMPParallelDirective(getTopOfStack().Directive) ||((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1463, __PRETTY_FUNCTION__)) | ||||||||
1460 | isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1463, __PRETTY_FUNCTION__)) | ||||||||
1461 | !isOpenMPSimdDirective(getTopOfStack().Directive))) &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1463, __PRETTY_FUNCTION__)) | ||||||||
1462 | "Additional reduction info may be specified only once for reduction "((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1463, __PRETTY_FUNCTION__)) | ||||||||
1463 | "items.")((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1463, __PRETTY_FUNCTION__)); | ||||||||
1464 | ReductionData.set(ReductionRef, SR); | ||||||||
1465 | Expr *&TaskgroupReductionRef = | ||||||||
1466 | getTopOfStack().TaskgroupReductionRef; | ||||||||
1467 | if (!TaskgroupReductionRef) { | ||||||||
1468 | VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), | ||||||||
1469 | SemaRef.Context.VoidPtrTy, ".task_red."); | ||||||||
1470 | TaskgroupReductionRef = | ||||||||
1471 | buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); | ||||||||
1472 | } | ||||||||
1473 | } | ||||||||
1474 | |||||||||
1475 | const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( | ||||||||
1476 | const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, | ||||||||
1477 | Expr *&TaskgroupDescriptor) const { | ||||||||
1478 | D = getCanonicalDecl(D); | ||||||||
1479 | assert(!isStackEmpty() && "Data-sharing attributes stack is empty.")((!isStackEmpty() && "Data-sharing attributes stack is empty." ) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1479, __PRETTY_FUNCTION__)); | ||||||||
1480 | for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { | ||||||||
1481 | const DSAInfo &Data = I->SharingMap.lookup(D); | ||||||||
1482 | if (Data.Attributes != OMPC_reduction || | ||||||||
1483 | Data.Modifier != OMPC_REDUCTION_task) | ||||||||
1484 | continue; | ||||||||
1485 | const ReductionData &ReductionData = I->ReductionMap.lookup(D); | ||||||||
1486 | if (!ReductionData.ReductionOp || | ||||||||
1487 | ReductionData.ReductionOp.is<const Expr *>()) | ||||||||
1488 | return DSAVarData(); | ||||||||
1489 | SR = ReductionData.ReductionRange; | ||||||||
1490 | BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); | ||||||||
1491 | assert(I->TaskgroupReductionRef && "taskgroup reduction reference "((I->TaskgroupReductionRef && "taskgroup reduction reference " "expression for the descriptor is not " "set.") ? static_cast <void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1493, __PRETTY_FUNCTION__)) | ||||||||
1492 | "expression for the descriptor is not "((I->TaskgroupReductionRef && "taskgroup reduction reference " "expression for the descriptor is not " "set.") ? static_cast <void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1493, __PRETTY_FUNCTION__)) | ||||||||
1493 | "set.")((I->TaskgroupReductionRef && "taskgroup reduction reference " "expression for the descriptor is not " "set.") ? static_cast <void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1493, __PRETTY_FUNCTION__)); | ||||||||
1494 | TaskgroupDescriptor = I->TaskgroupReductionRef; | ||||||||
1495 | return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), | ||||||||
1496 | Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task, | ||||||||
1497 | /*AppliedToPointee=*/false); | ||||||||
1498 | } | ||||||||
1499 | return DSAVarData(); | ||||||||
1500 | } | ||||||||
1501 | |||||||||
1502 | const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( | ||||||||
1503 | const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, | ||||||||
1504 | Expr *&TaskgroupDescriptor) const { | ||||||||
1505 | D = getCanonicalDecl(D); | ||||||||
1506 | assert(!isStackEmpty() && "Data-sharing attributes stack is empty.")((!isStackEmpty() && "Data-sharing attributes stack is empty." ) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1506, __PRETTY_FUNCTION__)); | ||||||||
1507 | for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { | ||||||||
1508 | const DSAInfo &Data = I->SharingMap.lookup(D); | ||||||||
1509 | if (Data.Attributes != OMPC_reduction || | ||||||||
1510 | Data.Modifier != OMPC_REDUCTION_task) | ||||||||
1511 | continue; | ||||||||
1512 | const ReductionData &ReductionData = I->ReductionMap.lookup(D); | ||||||||
1513 | if (!ReductionData.ReductionOp || | ||||||||
1514 | !ReductionData.ReductionOp.is<const Expr *>()) | ||||||||
1515 | return DSAVarData(); | ||||||||
1516 | SR = ReductionData.ReductionRange; | ||||||||
1517 | ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); | ||||||||
1518 | assert(I->TaskgroupReductionRef && "taskgroup reduction reference "((I->TaskgroupReductionRef && "taskgroup reduction reference " "expression for the descriptor is not " "set.") ? static_cast <void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1520, __PRETTY_FUNCTION__)) | ||||||||
1519 | "expression for the descriptor is not "((I->TaskgroupReductionRef && "taskgroup reduction reference " "expression for the descriptor is not " "set.") ? static_cast <void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1520, __PRETTY_FUNCTION__)) | ||||||||
1520 | "set.")((I->TaskgroupReductionRef && "taskgroup reduction reference " "expression for the descriptor is not " "set.") ? static_cast <void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1520, __PRETTY_FUNCTION__)); | ||||||||
1521 | TaskgroupDescriptor = I->TaskgroupReductionRef; | ||||||||
1522 | return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), | ||||||||
1523 | Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task, | ||||||||
1524 | /*AppliedToPointee=*/false); | ||||||||
1525 | } | ||||||||
1526 | return DSAVarData(); | ||||||||
1527 | } | ||||||||
1528 | |||||||||
1529 | bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { | ||||||||
1530 | D = D->getCanonicalDecl(); | ||||||||
1531 | for (const_iterator E = end(); I != E; ++I) { | ||||||||
1532 | if (isImplicitOrExplicitTaskingRegion(I->Directive) || | ||||||||
1533 | isOpenMPTargetExecutionDirective(I->Directive)) { | ||||||||
1534 | Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; | ||||||||
1535 | Scope *CurScope = getCurScope(); | ||||||||
1536 | while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) | ||||||||
1537 | CurScope = CurScope->getParent(); | ||||||||
1538 | return CurScope != TopScope; | ||||||||
1539 | } | ||||||||
1540 | } | ||||||||
1541 | return false; | ||||||||
1542 | } | ||||||||
1543 | |||||||||
1544 | static bool isConstNotMutableType(Sema &SemaRef, QualType Type, | ||||||||
1545 | bool AcceptIfMutable = true, | ||||||||
1546 | bool *IsClassType = nullptr) { | ||||||||
1547 | ASTContext &Context = SemaRef.getASTContext(); | ||||||||
1548 | Type = Type.getNonReferenceType().getCanonicalType(); | ||||||||
1549 | bool IsConstant = Type.isConstant(Context); | ||||||||
1550 | Type = Context.getBaseElementType(Type); | ||||||||
1551 | const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus | ||||||||
1552 | ? Type->getAsCXXRecordDecl() | ||||||||
1553 | : nullptr; | ||||||||
1554 | if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) | ||||||||
1555 | if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) | ||||||||
1556 | RD = CTD->getTemplatedDecl(); | ||||||||
1557 | if (IsClassType) | ||||||||
1558 | *IsClassType = RD; | ||||||||
1559 | return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && | ||||||||
1560 | RD->hasDefinition() && RD->hasMutableFields()); | ||||||||
1561 | } | ||||||||
1562 | |||||||||
1563 | static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, | ||||||||
1564 | QualType Type, OpenMPClauseKind CKind, | ||||||||
1565 | SourceLocation ELoc, | ||||||||
1566 | bool AcceptIfMutable = true, | ||||||||
1567 | bool ListItemNotVar = false) { | ||||||||
1568 | ASTContext &Context = SemaRef.getASTContext(); | ||||||||
1569 | bool IsClassType; | ||||||||
1570 | if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { | ||||||||
1571 | unsigned Diag = ListItemNotVar | ||||||||
1572 | ? diag::err_omp_const_list_item | ||||||||
1573 | : IsClassType ? diag::err_omp_const_not_mutable_variable | ||||||||
1574 | : diag::err_omp_const_variable; | ||||||||
1575 | SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); | ||||||||
1576 | if (!ListItemNotVar && D) { | ||||||||
1577 | const VarDecl *VD = dyn_cast<VarDecl>(D); | ||||||||
1578 | bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == | ||||||||
1579 | VarDecl::DeclarationOnly; | ||||||||
1580 | SemaRef.Diag(D->getLocation(), | ||||||||
1581 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||||
1582 | << D; | ||||||||
1583 | } | ||||||||
1584 | return true; | ||||||||
1585 | } | ||||||||
1586 | return false; | ||||||||
1587 | } | ||||||||
1588 | |||||||||
1589 | const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, | ||||||||
1590 | bool FromParent) { | ||||||||
1591 | D = getCanonicalDecl(D); | ||||||||
1592 | DSAVarData DVar; | ||||||||
1593 | |||||||||
1594 | auto *VD = dyn_cast<VarDecl>(D); | ||||||||
1595 | auto TI = Threadprivates.find(D); | ||||||||
1596 | if (TI != Threadprivates.end()) { | ||||||||
1597 | DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); | ||||||||
1598 | DVar.CKind = OMPC_threadprivate; | ||||||||
1599 | DVar.Modifier = TI->getSecond().Modifier; | ||||||||
1600 | return DVar; | ||||||||
1601 | } | ||||||||
1602 | if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { | ||||||||
1603 | DVar.RefExpr = buildDeclRefExpr( | ||||||||
1604 | SemaRef, VD, D->getType().getNonReferenceType(), | ||||||||
1605 | VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); | ||||||||
1606 | DVar.CKind = OMPC_threadprivate; | ||||||||
1607 | addDSA(D, DVar.RefExpr, OMPC_threadprivate); | ||||||||
1608 | return DVar; | ||||||||
1609 | } | ||||||||
1610 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||||
1611 | // in a Construct, C/C++, predetermined, p.1] | ||||||||
1612 | // Variables appearing in threadprivate directives are threadprivate. | ||||||||
1613 | if ((VD && VD->getTLSKind() != VarDecl::TLS_None && | ||||||||
1614 | !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && | ||||||||
1615 | SemaRef.getLangOpts().OpenMPUseTLS && | ||||||||
1616 | SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || | ||||||||
1617 | (VD && VD->getStorageClass() == SC_Register && | ||||||||
1618 | VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { | ||||||||
1619 | DVar.RefExpr = buildDeclRefExpr( | ||||||||
1620 | SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); | ||||||||
1621 | DVar.CKind = OMPC_threadprivate; | ||||||||
1622 | addDSA(D, DVar.RefExpr, OMPC_threadprivate); | ||||||||
1623 | return DVar; | ||||||||
1624 | } | ||||||||
1625 | if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && | ||||||||
1626 | VD->isLocalVarDeclOrParm() && !isStackEmpty() && | ||||||||
1627 | !isLoopControlVariable(D).first) { | ||||||||
1628 | const_iterator IterTarget = | ||||||||
1629 | std::find_if(begin(), end(), [](const SharingMapTy &Data) { | ||||||||
1630 | return isOpenMPTargetExecutionDirective(Data.Directive); | ||||||||
1631 | }); | ||||||||
1632 | if (IterTarget != end()) { | ||||||||
1633 | const_iterator ParentIterTarget = IterTarget + 1; | ||||||||
1634 | for (const_iterator Iter = begin(); | ||||||||
1635 | Iter != ParentIterTarget; ++Iter) { | ||||||||
1636 | if (isOpenMPLocal(VD, Iter)) { | ||||||||
1637 | DVar.RefExpr = | ||||||||
1638 | buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), | ||||||||
1639 | D->getLocation()); | ||||||||
1640 | DVar.CKind = OMPC_threadprivate; | ||||||||
1641 | return DVar; | ||||||||
1642 | } | ||||||||
1643 | } | ||||||||
1644 | if (!isClauseParsingMode() || IterTarget != begin()) { | ||||||||
1645 | auto DSAIter = IterTarget->SharingMap.find(D); | ||||||||
1646 | if (DSAIter != IterTarget->SharingMap.end() && | ||||||||
1647 | isOpenMPPrivate(DSAIter->getSecond().Attributes)) { | ||||||||
1648 | DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); | ||||||||
1649 | DVar.CKind = OMPC_threadprivate; | ||||||||
1650 | return DVar; | ||||||||
1651 | } | ||||||||
1652 | const_iterator End = end(); | ||||||||
1653 | if (!SemaRef.isOpenMPCapturedByRef( | ||||||||
1654 | D, std::distance(ParentIterTarget, End), | ||||||||
1655 | /*OpenMPCaptureLevel=*/0)) { | ||||||||
1656 | DVar.RefExpr = | ||||||||
1657 | buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), | ||||||||
1658 | IterTarget->ConstructLoc); | ||||||||
1659 | DVar.CKind = OMPC_threadprivate; | ||||||||
1660 | return DVar; | ||||||||
1661 | } | ||||||||
1662 | } | ||||||||
1663 | } | ||||||||
1664 | } | ||||||||
1665 | |||||||||
1666 | if (isStackEmpty()) | ||||||||
1667 | // Not in OpenMP execution region and top scope was already checked. | ||||||||
1668 | return DVar; | ||||||||
1669 | |||||||||
1670 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||||
1671 | // in a Construct, C/C++, predetermined, p.4] | ||||||||
1672 | // Static data members are shared. | ||||||||
1673 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||||
1674 | // in a Construct, C/C++, predetermined, p.7] | ||||||||
1675 | // Variables with static storage duration that are declared in a scope | ||||||||
1676 | // inside the construct are shared. | ||||||||
1677 | if (VD && VD->isStaticDataMember()) { | ||||||||
1678 | // Check for explicitly specified attributes. | ||||||||
1679 | const_iterator I = begin(); | ||||||||
1680 | const_iterator EndI = end(); | ||||||||
1681 | if (FromParent && I != EndI) | ||||||||
1682 | ++I; | ||||||||
1683 | if (I != EndI) { | ||||||||
1684 | auto It = I->SharingMap.find(D); | ||||||||
1685 | if (It != I->SharingMap.end()) { | ||||||||
1686 | const DSAInfo &Data = It->getSecond(); | ||||||||
1687 | DVar.RefExpr = Data.RefExpr.getPointer(); | ||||||||
1688 | DVar.PrivateCopy = Data.PrivateCopy; | ||||||||
1689 | DVar.CKind = Data.Attributes; | ||||||||
1690 | DVar.ImplicitDSALoc = I->DefaultAttrLoc; | ||||||||
1691 | DVar.DKind = I->Directive; | ||||||||
1692 | DVar.Modifier = Data.Modifier; | ||||||||
1693 | DVar.AppliedToPointee = Data.AppliedToPointee; | ||||||||
1694 | return DVar; | ||||||||
1695 | } | ||||||||
1696 | } | ||||||||
1697 | |||||||||
1698 | DVar.CKind = OMPC_shared; | ||||||||
1699 | return DVar; | ||||||||
1700 | } | ||||||||
1701 | |||||||||
1702 | auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; | ||||||||
1703 | // The predetermined shared attribute for const-qualified types having no | ||||||||
1704 | // mutable members was removed after OpenMP 3.1. | ||||||||
1705 | if (SemaRef.LangOpts.OpenMP <= 31) { | ||||||||
1706 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||||
1707 | // in a Construct, C/C++, predetermined, p.6] | ||||||||
1708 | // Variables with const qualified type having no mutable member are | ||||||||
1709 | // shared. | ||||||||
1710 | if (isConstNotMutableType(SemaRef, D->getType())) { | ||||||||
1711 | // Variables with const-qualified type having no mutable member may be | ||||||||
1712 | // listed in a firstprivate clause, even if they are static data members. | ||||||||
1713 | DSAVarData DVarTemp = hasInnermostDSA( | ||||||||
1714 | D, | ||||||||
1715 | [](OpenMPClauseKind C, bool) { | ||||||||
1716 | return C == OMPC_firstprivate || C == OMPC_shared; | ||||||||
1717 | }, | ||||||||
1718 | MatchesAlways, FromParent); | ||||||||
1719 | if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) | ||||||||
1720 | return DVarTemp; | ||||||||
1721 | |||||||||
1722 | DVar.CKind = OMPC_shared; | ||||||||
1723 | return DVar; | ||||||||
1724 | } | ||||||||
1725 | } | ||||||||
1726 | |||||||||
1727 | // Explicitly specified attributes and local variables with predetermined | ||||||||
1728 | // attributes. | ||||||||
1729 | const_iterator I = begin(); | ||||||||
1730 | const_iterator EndI = end(); | ||||||||
1731 | if (FromParent && I != EndI) | ||||||||
1732 | ++I; | ||||||||
1733 | if (I == EndI) | ||||||||
1734 | return DVar; | ||||||||
1735 | auto It = I->SharingMap.find(D); | ||||||||
1736 | if (It != I->SharingMap.end()) { | ||||||||
1737 | const DSAInfo &Data = It->getSecond(); | ||||||||
1738 | DVar.RefExpr = Data.RefExpr.getPointer(); | ||||||||
1739 | DVar.PrivateCopy = Data.PrivateCopy; | ||||||||
1740 | DVar.CKind = Data.Attributes; | ||||||||
1741 | DVar.ImplicitDSALoc = I->DefaultAttrLoc; | ||||||||
1742 | DVar.DKind = I->Directive; | ||||||||
1743 | DVar.Modifier = Data.Modifier; | ||||||||
1744 | DVar.AppliedToPointee = Data.AppliedToPointee; | ||||||||
1745 | } | ||||||||
1746 | |||||||||
1747 | return DVar; | ||||||||
1748 | } | ||||||||
1749 | |||||||||
1750 | const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, | ||||||||
1751 | bool FromParent) const { | ||||||||
1752 | if (isStackEmpty()) { | ||||||||
1753 | const_iterator I; | ||||||||
1754 | return getDSA(I, D); | ||||||||
1755 | } | ||||||||
1756 | D = getCanonicalDecl(D); | ||||||||
1757 | const_iterator StartI = begin(); | ||||||||
1758 | const_iterator EndI = end(); | ||||||||
1759 | if (FromParent && StartI != EndI) | ||||||||
1760 | ++StartI; | ||||||||
1761 | return getDSA(StartI, D); | ||||||||
1762 | } | ||||||||
1763 | |||||||||
1764 | const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, | ||||||||
1765 | unsigned Level) const { | ||||||||
1766 | if (getStackSize() <= Level) | ||||||||
1767 | return DSAVarData(); | ||||||||
1768 | D = getCanonicalDecl(D); | ||||||||
1769 | const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level); | ||||||||
1770 | return getDSA(StartI, D); | ||||||||
1771 | } | ||||||||
1772 | |||||||||
1773 | const DSAStackTy::DSAVarData | ||||||||
1774 | DSAStackTy::hasDSA(ValueDecl *D, | ||||||||
1775 | const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, | ||||||||
1776 | const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, | ||||||||
1777 | bool FromParent) const { | ||||||||
1778 | if (isStackEmpty()) | ||||||||
1779 | return {}; | ||||||||
1780 | D = getCanonicalDecl(D); | ||||||||
1781 | const_iterator I = begin(); | ||||||||
1782 | const_iterator EndI = end(); | ||||||||
1783 | if (FromParent && I != EndI) | ||||||||
1784 | ++I; | ||||||||
1785 | for (; I != EndI; ++I) { | ||||||||
1786 | if (!DPred(I->Directive) && | ||||||||
1787 | !isImplicitOrExplicitTaskingRegion(I->Directive)) | ||||||||
1788 | continue; | ||||||||
1789 | const_iterator NewI = I; | ||||||||
1790 | DSAVarData DVar = getDSA(NewI, D); | ||||||||
1791 | if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee)) | ||||||||
1792 | return DVar; | ||||||||
1793 | } | ||||||||
1794 | return {}; | ||||||||
1795 | } | ||||||||
1796 | |||||||||
1797 | const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( | ||||||||
1798 | ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, | ||||||||
1799 | const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, | ||||||||
1800 | bool FromParent) const { | ||||||||
1801 | if (isStackEmpty()) | ||||||||
1802 | return {}; | ||||||||
1803 | D = getCanonicalDecl(D); | ||||||||
1804 | const_iterator StartI = begin(); | ||||||||
1805 | const_iterator EndI = end(); | ||||||||
1806 | if (FromParent && StartI != EndI) | ||||||||
1807 | ++StartI; | ||||||||
1808 | if (StartI == EndI || !DPred(StartI->Directive)) | ||||||||
1809 | return {}; | ||||||||
1810 | const_iterator NewI = StartI; | ||||||||
1811 | DSAVarData DVar = getDSA(NewI, D); | ||||||||
1812 | return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee)) | ||||||||
1813 | ? DVar | ||||||||
1814 | : DSAVarData(); | ||||||||
1815 | } | ||||||||
1816 | |||||||||
1817 | bool DSAStackTy::hasExplicitDSA( | ||||||||
1818 | const ValueDecl *D, | ||||||||
1819 | const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, | ||||||||
1820 | unsigned Level, bool NotLastprivate) const { | ||||||||
1821 | if (getStackSize() <= Level) | ||||||||
1822 | return false; | ||||||||
1823 | D = getCanonicalDecl(D); | ||||||||
1824 | const SharingMapTy &StackElem = getStackElemAtLevel(Level); | ||||||||
1825 | auto I = StackElem.SharingMap.find(D); | ||||||||
1826 | if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() && | ||||||||
1827 | CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) && | ||||||||
1828 | (!NotLastprivate || !I->getSecond().RefExpr.getInt())) | ||||||||
1829 | return true; | ||||||||
1830 | // Check predetermined rules for the loop control variables. | ||||||||
1831 | auto LI = StackElem.LCVMap.find(D); | ||||||||
1832 | if (LI != StackElem.LCVMap.end()) | ||||||||
1833 | return CPred(OMPC_private, /*AppliedToPointee=*/false); | ||||||||
1834 | return false; | ||||||||
1835 | } | ||||||||
1836 | |||||||||
1837 | bool DSAStackTy::hasExplicitDirective( | ||||||||
1838 | const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, | ||||||||
1839 | unsigned Level) const { | ||||||||
1840 | if (getStackSize() <= Level) | ||||||||
1841 | return false; | ||||||||
1842 | const SharingMapTy &StackElem = getStackElemAtLevel(Level); | ||||||||
1843 | return DPred(StackElem.Directive); | ||||||||
1844 | } | ||||||||
1845 | |||||||||
1846 | bool DSAStackTy::hasDirective( | ||||||||
1847 | const llvm::function_ref<bool(OpenMPDirectiveKind, | ||||||||
1848 | const DeclarationNameInfo &, SourceLocation)> | ||||||||
1849 | DPred, | ||||||||
1850 | bool FromParent) const { | ||||||||
1851 | // We look only in the enclosing region. | ||||||||
1852 | size_t Skip = FromParent ? 2 : 1; | ||||||||
1853 | for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); | ||||||||
1854 | I != E; ++I) { | ||||||||
1855 | if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) | ||||||||
1856 | return true; | ||||||||
1857 | } | ||||||||
1858 | return false; | ||||||||
1859 | } | ||||||||
1860 | |||||||||
1861 | void Sema::InitDataSharingAttributesStack() { | ||||||||
1862 | VarDataSharingAttributesStack = new DSAStackTy(*this); | ||||||||
1863 | } | ||||||||
1864 | |||||||||
1865 | #define DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ) static_cast<DSAStackTy *>(VarDataSharingAttributesStack) | ||||||||
1866 | |||||||||
1867 | void Sema::pushOpenMPFunctionRegion() { | ||||||||
1868 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->pushFunction(); | ||||||||
1869 | } | ||||||||
1870 | |||||||||
1871 | void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { | ||||||||
1872 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->popFunction(OldFSI); | ||||||||
1873 | } | ||||||||
1874 | |||||||||
1875 | static bool isOpenMPDeviceDelayedContext(Sema &S) { | ||||||||
1876 | assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&((S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && "Expected OpenMP device compilation.") ? static_cast<void > (0) : __assert_fail ("S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1877, __PRETTY_FUNCTION__)) | ||||||||
1877 | "Expected OpenMP device compilation.")((S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && "Expected OpenMP device compilation.") ? static_cast<void > (0) : __assert_fail ("S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1877, __PRETTY_FUNCTION__)); | ||||||||
1878 | return !S.isInOpenMPTargetExecutionDirective() && | ||||||||
1879 | !S.isInOpenMPDeclareTargetContext(); | ||||||||
1880 | } | ||||||||
1881 | |||||||||
1882 | namespace { | ||||||||
1883 | /// Status of the function emission on the host/device. | ||||||||
1884 | enum class FunctionEmissionStatus { | ||||||||
1885 | Emitted, | ||||||||
1886 | Discarded, | ||||||||
1887 | Unknown, | ||||||||
1888 | }; | ||||||||
1889 | } // anonymous namespace | ||||||||
1890 | |||||||||
1891 | Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, | ||||||||
1892 | unsigned DiagID) { | ||||||||
1893 | assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&((LangOpts.OpenMP && LangOpts.OpenMPIsDevice && "Expected OpenMP device compilation.") ? static_cast<void > (0) : __assert_fail ("LangOpts.OpenMP && LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1894, __PRETTY_FUNCTION__)) | ||||||||
1894 | "Expected OpenMP device compilation.")((LangOpts.OpenMP && LangOpts.OpenMPIsDevice && "Expected OpenMP device compilation.") ? static_cast<void > (0) : __assert_fail ("LangOpts.OpenMP && LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1894, __PRETTY_FUNCTION__)); | ||||||||
1895 | |||||||||
1896 | FunctionDecl *FD = getCurFunctionDecl(); | ||||||||
1897 | DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; | ||||||||
1898 | if (FD) { | ||||||||
1899 | FunctionEmissionStatus FES = getEmissionStatus(FD); | ||||||||
1900 | switch (FES) { | ||||||||
1901 | case FunctionEmissionStatus::Emitted: | ||||||||
1902 | Kind = DeviceDiagBuilder::K_Immediate; | ||||||||
1903 | break; | ||||||||
1904 | case FunctionEmissionStatus::Unknown: | ||||||||
1905 | Kind = isOpenMPDeviceDelayedContext(*this) | ||||||||
1906 | ? DeviceDiagBuilder::K_Deferred | ||||||||
1907 | : DeviceDiagBuilder::K_Immediate; | ||||||||
1908 | break; | ||||||||
1909 | case FunctionEmissionStatus::TemplateDiscarded: | ||||||||
1910 | case FunctionEmissionStatus::OMPDiscarded: | ||||||||
1911 | Kind = DeviceDiagBuilder::K_Nop; | ||||||||
1912 | break; | ||||||||
1913 | case FunctionEmissionStatus::CUDADiscarded: | ||||||||
1914 | llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation")::llvm::llvm_unreachable_internal("CUDADiscarded unexpected in OpenMP device compilation" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1914); | ||||||||
1915 | break; | ||||||||
1916 | } | ||||||||
1917 | } | ||||||||
1918 | |||||||||
1919 | return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); | ||||||||
1920 | } | ||||||||
1921 | |||||||||
1922 | Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, | ||||||||
1923 | unsigned DiagID) { | ||||||||
1924 | assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&((LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && "Expected OpenMP host compilation.") ? static_cast<void> (0) : __assert_fail ("LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && \"Expected OpenMP host compilation.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1925, __PRETTY_FUNCTION__)) | ||||||||
1925 | "Expected OpenMP host compilation.")((LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && "Expected OpenMP host compilation.") ? static_cast<void> (0) : __assert_fail ("LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && \"Expected OpenMP host compilation.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1925, __PRETTY_FUNCTION__)); | ||||||||
1926 | FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); | ||||||||
1927 | DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; | ||||||||
1928 | switch (FES) { | ||||||||
1929 | case FunctionEmissionStatus::Emitted: | ||||||||
1930 | Kind = DeviceDiagBuilder::K_Immediate; | ||||||||
1931 | break; | ||||||||
1932 | case FunctionEmissionStatus::Unknown: | ||||||||
1933 | Kind = DeviceDiagBuilder::K_Deferred; | ||||||||
1934 | break; | ||||||||
1935 | case FunctionEmissionStatus::TemplateDiscarded: | ||||||||
1936 | case FunctionEmissionStatus::OMPDiscarded: | ||||||||
1937 | case FunctionEmissionStatus::CUDADiscarded: | ||||||||
1938 | Kind = DeviceDiagBuilder::K_Nop; | ||||||||
1939 | break; | ||||||||
1940 | } | ||||||||
1941 | |||||||||
1942 | return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); | ||||||||
1943 | } | ||||||||
1944 | |||||||||
1945 | static OpenMPDefaultmapClauseKind | ||||||||
1946 | getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) { | ||||||||
1947 | if (LO.OpenMP <= 45) { | ||||||||
1948 | if (VD->getType().getNonReferenceType()->isScalarType()) | ||||||||
1949 | return OMPC_DEFAULTMAP_scalar; | ||||||||
1950 | return OMPC_DEFAULTMAP_aggregate; | ||||||||
1951 | } | ||||||||
1952 | if (VD->getType().getNonReferenceType()->isAnyPointerType()) | ||||||||
1953 | return OMPC_DEFAULTMAP_pointer; | ||||||||
1954 | if (VD->getType().getNonReferenceType()->isScalarType()) | ||||||||
1955 | return OMPC_DEFAULTMAP_scalar; | ||||||||
1956 | return OMPC_DEFAULTMAP_aggregate; | ||||||||
1957 | } | ||||||||
1958 | |||||||||
1959 | bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, | ||||||||
1960 | unsigned OpenMPCaptureLevel) const { | ||||||||
1961 | assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast <void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 1961, __PRETTY_FUNCTION__)); | ||||||||
1962 | |||||||||
1963 | ASTContext &Ctx = getASTContext(); | ||||||||
1964 | bool IsByRef = true; | ||||||||
1965 | |||||||||
1966 | // Find the directive that is associated with the provided scope. | ||||||||
1967 | D = cast<ValueDecl>(D->getCanonicalDecl()); | ||||||||
1968 | QualType Ty = D->getType(); | ||||||||
1969 | |||||||||
1970 | bool IsVariableUsedInMapClause = false; | ||||||||
1971 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { | ||||||||
1972 | // This table summarizes how a given variable should be passed to the device | ||||||||
1973 | // given its type and the clauses where it appears. This table is based on | ||||||||
1974 | // the description in OpenMP 4.5 [2.10.4, target Construct] and | ||||||||
1975 | // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. | ||||||||
1976 | // | ||||||||
1977 | // ========================================================================= | ||||||||
1978 | // | type | defaultmap | pvt | first | is_device_ptr | map | res. | | ||||||||
1979 | // | |(tofrom:scalar)| | pvt | | | | | ||||||||
1980 | // ========================================================================= | ||||||||
1981 | // | scl | | | | - | | bycopy| | ||||||||
1982 | // | scl | | - | x | - | - | bycopy| | ||||||||
1983 | // | scl | | x | - | - | - | null | | ||||||||
1984 | // | scl | x | | | - | | byref | | ||||||||
1985 | // | scl | x | - | x | - | - | bycopy| | ||||||||
1986 | // | scl | x | x | - | - | - | null | | ||||||||
1987 | // | scl | | - | - | - | x | byref | | ||||||||
1988 | // | scl | x | - | - | - | x | byref | | ||||||||
1989 | // | ||||||||
1990 | // | agg | n.a. | | | - | | byref | | ||||||||
1991 | // | agg | n.a. | - | x | - | - | byref | | ||||||||
1992 | // | agg | n.a. | x | - | - | - | null | | ||||||||
1993 | // | agg | n.a. | - | - | - | x | byref | | ||||||||
1994 | // | agg | n.a. | - | - | - | x[] | byref | | ||||||||
1995 | // | ||||||||
1996 | // | ptr | n.a. | | | - | | bycopy| | ||||||||
1997 | // | ptr | n.a. | - | x | - | - | bycopy| | ||||||||
1998 | // | ptr | n.a. | x | - | - | - | null | | ||||||||
1999 | // | ptr | n.a. | - | - | - | x | byref | | ||||||||
2000 | // | ptr | n.a. | - | - | - | x[] | bycopy| | ||||||||
2001 | // | ptr | n.a. | - | - | x | | bycopy| | ||||||||
2002 | // | ptr | n.a. | - | - | x | x | bycopy| | ||||||||
2003 | // | ptr | n.a. | - | - | x | x[] | bycopy| | ||||||||
2004 | // ========================================================================= | ||||||||
2005 | // Legend: | ||||||||
2006 | // scl - scalar | ||||||||
2007 | // ptr - pointer | ||||||||
2008 | // agg - aggregate | ||||||||
2009 | // x - applies | ||||||||
2010 | // - - invalid in this combination | ||||||||
2011 | // [] - mapped with an array section | ||||||||
2012 | // byref - should be mapped by reference | ||||||||
2013 | // byval - should be mapped by value | ||||||||
2014 | // null - initialize a local variable to null on the device | ||||||||
2015 | // | ||||||||
2016 | // Observations: | ||||||||
2017 | // - All scalar declarations that show up in a map clause have to be passed | ||||||||
2018 | // by reference, because they may have been mapped in the enclosing data | ||||||||
2019 | // environment. | ||||||||
2020 | // - If the scalar value does not fit the size of uintptr, it has to be | ||||||||
2021 | // passed by reference, regardless the result in the table above. | ||||||||
2022 | // - For pointers mapped by value that have either an implicit map or an | ||||||||
2023 | // array section, the runtime library may pass the NULL value to the | ||||||||
2024 | // device instead of the value passed to it by the compiler. | ||||||||
2025 | |||||||||
2026 | if (Ty->isReferenceType()) | ||||||||
2027 | Ty = Ty->castAs<ReferenceType>()->getPointeeType(); | ||||||||
2028 | |||||||||
2029 | // Locate map clauses and see if the variable being captured is referred to | ||||||||
2030 | // in any of those clauses. Here we only care about variables, not fields, | ||||||||
2031 | // because fields are part of aggregates. | ||||||||
2032 | bool IsVariableAssociatedWithSection = false; | ||||||||
2033 | |||||||||
2034 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->checkMappableExprComponentListsForDeclAtLevel( | ||||||||
2035 | D, Level, | ||||||||
2036 | [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( | ||||||||
2037 | OMPClauseMappableExprCommon::MappableExprComponentListRef | ||||||||
2038 | MapExprComponents, | ||||||||
2039 | OpenMPClauseKind WhereFoundClauseKind) { | ||||||||
2040 | // Only the map clause information influences how a variable is | ||||||||
2041 | // captured. E.g. is_device_ptr does not require changing the default | ||||||||
2042 | // behavior. | ||||||||
2043 | if (WhereFoundClauseKind != OMPC_map) | ||||||||
2044 | return false; | ||||||||
2045 | |||||||||
2046 | auto EI = MapExprComponents.rbegin(); | ||||||||
2047 | auto EE = MapExprComponents.rend(); | ||||||||
2048 | |||||||||
2049 | assert(EI != EE && "Invalid map expression!")((EI != EE && "Invalid map expression!") ? static_cast <void> (0) : __assert_fail ("EI != EE && \"Invalid map expression!\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 2049, __PRETTY_FUNCTION__)); | ||||||||
2050 | |||||||||
2051 | if (isa<DeclRefExpr>(EI->getAssociatedExpression())) | ||||||||
2052 | IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; | ||||||||
2053 | |||||||||
2054 | ++EI; | ||||||||
2055 | if (EI == EE) | ||||||||
2056 | return false; | ||||||||
2057 | |||||||||
2058 | if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || | ||||||||
2059 | isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || | ||||||||
2060 | isa<MemberExpr>(EI->getAssociatedExpression()) || | ||||||||
2061 | isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) { | ||||||||
2062 | IsVariableAssociatedWithSection = true; | ||||||||
2063 | // There is nothing more we need to know about this variable. | ||||||||
2064 | return true; | ||||||||
2065 | } | ||||||||
2066 | |||||||||
2067 | // Keep looking for more map info. | ||||||||
2068 | return false; | ||||||||
2069 | }); | ||||||||
2070 | |||||||||
2071 | if (IsVariableUsedInMapClause) { | ||||||||
2072 | // If variable is identified in a map clause it is always captured by | ||||||||
2073 | // reference except if it is a pointer that is dereferenced somehow. | ||||||||
2074 | IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); | ||||||||
2075 | } else { | ||||||||
2076 | // By default, all the data that has a scalar type is mapped by copy | ||||||||
2077 | // (except for reduction variables). | ||||||||
2078 | // Defaultmap scalar is mutual exclusive to defaultmap pointer | ||||||||
2079 | IsByRef = (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isForceCaptureByReferenceInTargetExecutable() && | ||||||||
2080 | !Ty->isAnyPointerType()) || | ||||||||
2081 | !Ty->isScalarType() || | ||||||||
2082 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isDefaultmapCapturedByRef( | ||||||||
2083 | Level, getVariableCategoryFromDecl(LangOpts, D)) || | ||||||||
2084 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDSA( | ||||||||
2085 | D, | ||||||||
2086 | [](OpenMPClauseKind K, bool AppliedToPointee) { | ||||||||
2087 | return K == OMPC_reduction && !AppliedToPointee; | ||||||||
2088 | }, | ||||||||
2089 | Level); | ||||||||
2090 | } | ||||||||
2091 | } | ||||||||
2092 | |||||||||
2093 | if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { | ||||||||
2094 | IsByRef = | ||||||||
2095 | ((IsVariableUsedInMapClause && | ||||||||
2096 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCaptureRegion(Level, OpenMPCaptureLevel) == | ||||||||
2097 | OMPD_target) || | ||||||||
2098 | !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDSA( | ||||||||
2099 | D, | ||||||||
2100 | [](OpenMPClauseKind K, bool AppliedToPointee) -> bool { | ||||||||
2101 | return K == OMPC_firstprivate || | ||||||||
2102 | (K == OMPC_reduction && AppliedToPointee); | ||||||||
2103 | }, | ||||||||
2104 | Level, /*NotLastprivate=*/true) || | ||||||||
2105 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isUsesAllocatorsDecl(Level, D))) && | ||||||||
2106 | // If the variable is artificial and must be captured by value - try to | ||||||||
2107 | // capture by value. | ||||||||
2108 | !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && | ||||||||
2109 | !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) && | ||||||||
2110 | // If the variable is implicitly firstprivate and scalar - capture by | ||||||||
2111 | // copy | ||||||||
2112 | !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() == DSA_firstprivate && | ||||||||
2113 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDSA( | ||||||||
2114 | D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; }, | ||||||||
2115 | Level) && | ||||||||
2116 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isLoopControlVariable(D, Level).first); | ||||||||
2117 | } | ||||||||
2118 | |||||||||
2119 | // When passing data by copy, we need to make sure it fits the uintptr size | ||||||||
2120 | // and alignment, because the runtime library only deals with uintptr types. | ||||||||
2121 | // If it does not fit the uintptr size, we need to pass the data by reference | ||||||||
2122 | // instead. | ||||||||
2123 | if (!IsByRef && | ||||||||
2124 | (Ctx.getTypeSizeInChars(Ty) > | ||||||||
2125 | Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || | ||||||||
2126 | Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { | ||||||||
2127 | IsByRef = true; | ||||||||
2128 | } | ||||||||
2129 | |||||||||
2130 | return IsByRef; | ||||||||
2131 | } | ||||||||
2132 | |||||||||
2133 | unsigned Sema::getOpenMPNestingLevel() const { | ||||||||
2134 | assert(getLangOpts().OpenMP)((getLangOpts().OpenMP) ? static_cast<void> (0) : __assert_fail ("getLangOpts().OpenMP", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 2134, __PRETTY_FUNCTION__)); | ||||||||
2135 | return DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getNestingLevel(); | ||||||||
2136 | } | ||||||||
2137 | |||||||||
2138 | bool Sema::isInOpenMPTargetExecutionDirective() const { | ||||||||
2139 | return (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()) && | ||||||||
2140 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isClauseParsingMode()) || | ||||||||
2141 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasDirective( | ||||||||
2142 | [](OpenMPDirectiveKind K, const DeclarationNameInfo &, | ||||||||
2143 | SourceLocation) -> bool { | ||||||||
2144 | return isOpenMPTargetExecutionDirective(K); | ||||||||
2145 | }, | ||||||||
2146 | false); | ||||||||
2147 | } | ||||||||
2148 | |||||||||
2149 | VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, | ||||||||
2150 | unsigned StopAt) { | ||||||||
2151 | assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast <void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 2151, __PRETTY_FUNCTION__)); | ||||||||
2152 | D = getCanonicalDecl(D); | ||||||||
2153 | |||||||||
2154 | auto *VD = dyn_cast<VarDecl>(D); | ||||||||
2155 | // Do not capture constexpr variables. | ||||||||
2156 | if (VD
| ||||||||
2157 | return nullptr; | ||||||||
2158 | |||||||||
2159 | // If we want to determine whether the variable should be captured from the | ||||||||
2160 | // perspective of the current capturing scope, and we've already left all the | ||||||||
2161 | // capturing scopes of the top directive on the stack, check from the | ||||||||
2162 | // perspective of its parent directive (if any) instead. | ||||||||
2163 | DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( | ||||||||
2164 | *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), CheckScopeInfo
)->isBodyComplete()); | ||||||||
2165 | |||||||||
2166 | // If we are attempting to capture a global variable in a directive with | ||||||||
2167 | // 'target' we return true so that this global is also mapped to the device. | ||||||||
2168 | // | ||||||||
2169 | if (VD
| ||||||||
2170 | (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { | ||||||||
2171 | if (isInOpenMPDeclareTargetContext()) { | ||||||||
2172 | // Try to mark variable as declare target if it is used in capturing | ||||||||
2173 | // regions. | ||||||||
2174 | if (LangOpts.OpenMP <= 45 && | ||||||||
2175 | !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) | ||||||||
2176 | checkDeclIsAllowedInOpenMPTarget(nullptr, VD); | ||||||||
2177 | return nullptr; | ||||||||
2178 | } | ||||||||
2179 | if (isInOpenMPTargetExecutionDirective()) { | ||||||||
2180 | // If the declaration is enclosed in a 'declare target' directive, | ||||||||
2181 | // then it should not be captured. | ||||||||
2182 | // | ||||||||
2183 | if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) | ||||||||
2184 | return nullptr; | ||||||||
2185 | CapturedRegionScopeInfo *CSI = nullptr; | ||||||||
2186 | for (FunctionScopeInfo *FSI : llvm::drop_begin( | ||||||||
2187 | llvm::reverse(FunctionScopes), | ||||||||
2188 | CheckScopeInfo
| ||||||||
2189 | if (!isa<CapturingScopeInfo>(FSI)) | ||||||||
2190 | return nullptr; | ||||||||
2191 | if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) | ||||||||
2192 | if (RSI->CapRegionKind == CR_OpenMP) { | ||||||||
2193 | CSI = RSI; | ||||||||
2194 | break; | ||||||||
2195 | } | ||||||||
2196 | } | ||||||||
2197 | SmallVector<OpenMPDirectiveKind, 4> Regions; | ||||||||
2198 | getOpenMPCaptureRegions(Regions, | ||||||||
2199 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDirective(CSI->OpenMPLevel)); | ||||||||
| |||||||||
2200 | if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task) | ||||||||
2201 | return VD; | ||||||||
2202 | } | ||||||||
2203 | } | ||||||||
2204 | |||||||||
2205 | if (CheckScopeInfo) { | ||||||||
2206 | bool OpenMPFound = false; | ||||||||
2207 | for (unsigned I = StopAt + 1; I > 0; --I) { | ||||||||
2208 | FunctionScopeInfo *FSI = FunctionScopes[I - 1]; | ||||||||
2209 | if(!isa<CapturingScopeInfo>(FSI)) | ||||||||
2210 | return nullptr; | ||||||||
2211 | if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) | ||||||||
2212 | if (RSI->CapRegionKind == CR_OpenMP) { | ||||||||
2213 | OpenMPFound = true; | ||||||||
2214 | break; | ||||||||
2215 | } | ||||||||
2216 | } | ||||||||
2217 | if (!OpenMPFound) | ||||||||
2218 | return nullptr; | ||||||||
2219 | } | ||||||||
2220 | |||||||||
2221 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() != OMPD_unknown && | ||||||||
2222 | (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isClauseParsingMode() || | ||||||||
2223 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentDirective() != OMPD_unknown)) { | ||||||||
2224 | auto &&Info = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isLoopControlVariable(D); | ||||||||
2225 | if (Info.first || | ||||||||
2226 | (VD && VD->hasLocalStorage() && | ||||||||
2227 | isImplicitOrExplicitTaskingRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective())) || | ||||||||
2228 | (VD && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isForceVarCapturing())) | ||||||||
2229 | return VD ? VD : Info.second; | ||||||||
2230 | DSAStackTy::DSAVarData DVarTop = | ||||||||
2231 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isClauseParsingMode()); | ||||||||
2232 | if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) && | ||||||||
2233 | (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee)) | ||||||||
2234 | return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl()); | ||||||||
2235 | // Threadprivate variables must not be captured. | ||||||||
2236 | if (isOpenMPThreadPrivate(DVarTop.CKind)) | ||||||||
2237 | return nullptr; | ||||||||
2238 | // The variable is not private or it is the variable in the directive with | ||||||||
2239 | // default(none) clause and not used in any clause. | ||||||||
2240 | DSAStackTy::DSAVarData DVarPrivate = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasDSA( | ||||||||
2241 | D, | ||||||||
2242 | [](OpenMPClauseKind C, bool AppliedToPointee) { | ||||||||
2243 | return isOpenMPPrivate(C) && !AppliedToPointee; | ||||||||
2244 | }, | ||||||||
2245 | [](OpenMPDirectiveKind) { return true; }, | ||||||||
2246 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isClauseParsingMode()); | ||||||||
2247 | // Global shared must not be captured. | ||||||||
2248 | if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown && | ||||||||
2249 | ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() != DSA_none && | ||||||||
2250 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() != DSA_firstprivate) || | ||||||||
2251 | DVarTop.CKind == OMPC_shared)) | ||||||||
2252 | return nullptr; | ||||||||
2253 | if (DVarPrivate.CKind != OMPC_unknown || | ||||||||
2254 | (VD && (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() == DSA_none || | ||||||||
2255 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() == DSA_firstprivate))) | ||||||||
2256 | return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); | ||||||||
2257 | } | ||||||||
2258 | return nullptr; | ||||||||
2259 | } | ||||||||
2260 | |||||||||
2261 | void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, | ||||||||
2262 | unsigned Level) const { | ||||||||
2263 | FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDirective(Level)); | ||||||||
2264 | } | ||||||||
2265 | |||||||||
2266 | void Sema::startOpenMPLoop() { | ||||||||
2267 | assert(LangOpts.OpenMP && "OpenMP must be enabled.")((LangOpts.OpenMP && "OpenMP must be enabled.") ? static_cast <void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP must be enabled.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 2267, __PRETTY_FUNCTION__)); | ||||||||
2268 | if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective())) | ||||||||
2269 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->loopInit(); | ||||||||
2270 | } | ||||||||
2271 | |||||||||
2272 | void Sema::startOpenMPCXXRangeFor() { | ||||||||
2273 | assert(LangOpts.OpenMP && "OpenMP must be enabled.")((LangOpts.OpenMP && "OpenMP must be enabled.") ? static_cast <void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP must be enabled.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 2273, __PRETTY_FUNCTION__)); | ||||||||
2274 | if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective())) { | ||||||||
2275 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->resetPossibleLoopCounter(); | ||||||||
2276 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->loopStart(); | ||||||||
2277 | } | ||||||||
2278 | } | ||||||||
2279 | |||||||||
2280 | OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level, | ||||||||
2281 | unsigned CapLevel) const { | ||||||||
2282 | assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast <void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 2282, __PRETTY_FUNCTION__)); | ||||||||
2283 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDirective( | ||||||||
2284 | [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); }, | ||||||||
2285 | Level)) { | ||||||||
2286 | bool IsTriviallyCopyable = | ||||||||
2287 | D->getType().getNonReferenceType().isTriviallyCopyableType(Context) && | ||||||||
2288 | !D->getType() | ||||||||
2289 | .getNonReferenceType() | ||||||||
2290 | .getCanonicalType() | ||||||||
2291 | ->getAsCXXRecordDecl(); | ||||||||
2292 | OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDirective(Level); | ||||||||
2293 | SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; | ||||||||
2294 | getOpenMPCaptureRegions(CaptureRegions, DKind); | ||||||||
2295 | if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) && | ||||||||
2296 | (IsTriviallyCopyable || | ||||||||
2297 | !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) { | ||||||||
2298 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDSA( | ||||||||
2299 | D, | ||||||||
2300 | [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; }, | ||||||||
2301 | Level, /*NotLastprivate=*/true)) | ||||||||
2302 | return OMPC_firstprivate; | ||||||||
2303 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getImplicitDSA(D, Level); | ||||||||
2304 | if (DVar.CKind != OMPC_shared && | ||||||||
2305 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isLoopControlVariable(D, Level).first && !DVar.RefExpr) { | ||||||||
2306 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addImplicitTaskFirstprivate(Level, D); | ||||||||
2307 | return OMPC_firstprivate; | ||||||||
2308 | } | ||||||||
2309 | } | ||||||||
2310 | } | ||||||||
2311 | if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective())) { | ||||||||
2312 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getAssociatedLoops() > 0 && | ||||||||
2313 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isLoopStarted()) { | ||||||||
2314 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->resetPossibleLoopCounter(D); | ||||||||
2315 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->loopStart(); | ||||||||
2316 | return OMPC_private; | ||||||||
2317 | } | ||||||||
2318 | if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getPossiblyLoopCunter() == D->getCanonicalDecl() || | ||||||||
2319 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isLoopControlVariable(D).first) && | ||||||||
2320 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDSA( | ||||||||
2321 | D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; }, | ||||||||
2322 | Level) && | ||||||||
2323 | !isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective())) | ||||||||
2324 | return OMPC_private; | ||||||||
2325 | } | ||||||||
2326 | if (const auto *VD = dyn_cast<VarDecl>(D)) { | ||||||||
2327 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isThreadPrivate(const_cast<VarDecl *>(VD)) && | ||||||||
2328 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isForceVarCapturing() && | ||||||||
2329 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDSA( | ||||||||
2330 | D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; }, | ||||||||
2331 | Level)) | ||||||||
2332 | return OMPC_private; | ||||||||
2333 | } | ||||||||
2334 | // User-defined allocators are private since they must be defined in the | ||||||||
2335 | // context of target region. | ||||||||
2336 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) && | ||||||||
2337 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isUsesAllocatorsDecl(Level, D).getValueOr( | ||||||||
2338 | DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == | ||||||||
2339 | DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator) | ||||||||
2340 | return OMPC_private; | ||||||||
2341 | return (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDSA( | ||||||||
2342 | D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; }, | ||||||||
2343 | Level) || | ||||||||
2344 | (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isClauseParsingMode() && | ||||||||
2345 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getClauseParsingMode() == OMPC_private) || | ||||||||
2346 | // Consider taskgroup reduction descriptor variable a private | ||||||||
2347 | // to avoid possible capture in the region. | ||||||||
2348 | (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDirective( | ||||||||
2349 | [](OpenMPDirectiveKind K) { | ||||||||
2350 | return K == OMPD_taskgroup || | ||||||||
2351 | ((isOpenMPParallelDirective(K) || | ||||||||
2352 | isOpenMPWorksharingDirective(K)) && | ||||||||
2353 | !isOpenMPSimdDirective(K)); | ||||||||
2354 | }, | ||||||||
2355 | Level) && | ||||||||
2356 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isTaskgroupReductionRef(D, Level))) | ||||||||
2357 | ? OMPC_private | ||||||||
2358 | : OMPC_unknown; | ||||||||
2359 | } | ||||||||
2360 | |||||||||
2361 | void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, | ||||||||
2362 | unsigned Level) { | ||||||||
2363 | assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast <void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 2363, __PRETTY_FUNCTION__)); | ||||||||
2364 | D = getCanonicalDecl(D); | ||||||||
2365 | OpenMPClauseKind OMPC = OMPC_unknown; | ||||||||
2366 | for (unsigned I = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getNestingLevel() + 1; I > Level; --I) { | ||||||||
2367 | const unsigned NewLevel = I - 1; | ||||||||
2368 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDSA( | ||||||||
2369 | D, | ||||||||
2370 | [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) { | ||||||||
2371 | if (isOpenMPPrivate(K) && !AppliedToPointee) { | ||||||||
2372 | OMPC = K; | ||||||||
2373 | return true; | ||||||||
2374 | } | ||||||||
2375 | return false; | ||||||||
2376 | }, | ||||||||
2377 | NewLevel)) | ||||||||
2378 | break; | ||||||||
2379 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->checkMappableExprComponentListsForDeclAtLevel( | ||||||||
2380 | D, NewLevel, | ||||||||
2381 | [](OMPClauseMappableExprCommon::MappableExprComponentListRef, | ||||||||
2382 | OpenMPClauseKind) { return true; })) { | ||||||||
2383 | OMPC = OMPC_map; | ||||||||
2384 | break; | ||||||||
2385 | } | ||||||||
2386 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDirective(isOpenMPTargetExecutionDirective, | ||||||||
2387 | NewLevel)) { | ||||||||
2388 | OMPC = OMPC_map; | ||||||||
2389 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->mustBeFirstprivateAtLevel( | ||||||||
2390 | NewLevel, getVariableCategoryFromDecl(LangOpts, D))) | ||||||||
2391 | OMPC = OMPC_firstprivate; | ||||||||
2392 | break; | ||||||||
2393 | } | ||||||||
2394 | } | ||||||||
2395 | if (OMPC != OMPC_unknown) | ||||||||
2396 | FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC))); | ||||||||
2397 | } | ||||||||
2398 | |||||||||
2399 | bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, | ||||||||
2400 | unsigned CaptureLevel) const { | ||||||||
2401 | assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast <void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 2401, __PRETTY_FUNCTION__)); | ||||||||
2402 | // Return true if the current level is no longer enclosed in a target region. | ||||||||
2403 | |||||||||
2404 | SmallVector<OpenMPDirectiveKind, 4> Regions; | ||||||||
2405 | getOpenMPCaptureRegions(Regions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDirective(Level)); | ||||||||
2406 | const auto *VD = dyn_cast<VarDecl>(D); | ||||||||
2407 | return VD && !VD->hasLocalStorage() && | ||||||||
2408 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDirective(isOpenMPTargetExecutionDirective, | ||||||||
2409 | Level) && | ||||||||
2410 | Regions[CaptureLevel] != OMPD_task; | ||||||||
2411 | } | ||||||||
2412 | |||||||||
2413 | bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, | ||||||||
2414 | unsigned CaptureLevel) const { | ||||||||
2415 | assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast <void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 2415, __PRETTY_FUNCTION__)); | ||||||||
2416 | // Return true if the current level is no longer enclosed in a target region. | ||||||||
2417 | |||||||||
2418 | if (const auto *VD = dyn_cast<VarDecl>(D)) { | ||||||||
2419 | if (!VD->hasLocalStorage()) { | ||||||||
2420 | if (isInOpenMPTargetExecutionDirective()) | ||||||||
2421 | return true; | ||||||||
2422 | DSAStackTy::DSAVarData TopDVar = | ||||||||
2423 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); | ||||||||
2424 | unsigned NumLevels = | ||||||||
2425 | getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDirective(Level)); | ||||||||
2426 | if (Level == 0) | ||||||||
2427 | return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared; | ||||||||
2428 | do { | ||||||||
2429 | --Level; | ||||||||
2430 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getImplicitDSA(D, Level); | ||||||||
2431 | if (DVar.CKind != OMPC_shared) | ||||||||
2432 | return true; | ||||||||
2433 | } while (Level > 0); | ||||||||
2434 | } | ||||||||
2435 | } | ||||||||
2436 | return true; | ||||||||
2437 | } | ||||||||
2438 | |||||||||
2439 | void Sema::DestroyDataSharingAttributesStack() { delete DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ); } | ||||||||
2440 | |||||||||
2441 | void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, | ||||||||
2442 | OMPTraitInfo &TI) { | ||||||||
2443 | if (!OMPDeclareVariantScopes.empty()) { | ||||||||
2444 | Diag(Loc, diag::warn_nested_declare_variant); | ||||||||
2445 | return; | ||||||||
2446 | } | ||||||||
2447 | OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI)); | ||||||||
2448 | } | ||||||||
2449 | |||||||||
2450 | void Sema::ActOnOpenMPEndDeclareVariant() { | ||||||||
2451 | assert(isInOpenMPDeclareVariantScope() &&((isInOpenMPDeclareVariantScope() && "Not in OpenMP declare variant scope!" ) ? static_cast<void> (0) : __assert_fail ("isInOpenMPDeclareVariantScope() && \"Not in OpenMP declare variant scope!\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 2452, __PRETTY_FUNCTION__)) | ||||||||
2452 | "Not in OpenMP declare variant scope!")((isInOpenMPDeclareVariantScope() && "Not in OpenMP declare variant scope!" ) ? static_cast<void> (0) : __assert_fail ("isInOpenMPDeclareVariantScope() && \"Not in OpenMP declare variant scope!\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 2452, __PRETTY_FUNCTION__)); | ||||||||
2453 | |||||||||
2454 | OMPDeclareVariantScopes.pop_back(); | ||||||||
2455 | } | ||||||||
2456 | |||||||||
2457 | void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, | ||||||||
2458 | const FunctionDecl *Callee, | ||||||||
2459 | SourceLocation Loc) { | ||||||||
2460 | assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.")((LangOpts.OpenMP && "Expected OpenMP compilation mode." ) ? static_cast<void> (0) : __assert_fail ("LangOpts.OpenMP && \"Expected OpenMP compilation mode.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 2460, __PRETTY_FUNCTION__)); | ||||||||
2461 | Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = | ||||||||
2462 | OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl()); | ||||||||
2463 | // Ignore host functions during device analyzis. | ||||||||
2464 | if (LangOpts.OpenMPIsDevice && DevTy && | ||||||||
2465 | *DevTy == OMPDeclareTargetDeclAttr::DT_Host) | ||||||||
2466 | return; | ||||||||
2467 | // Ignore nohost functions during host analyzis. | ||||||||
2468 | if (!LangOpts.OpenMPIsDevice && DevTy && | ||||||||
2469 | *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) | ||||||||
2470 | return; | ||||||||
2471 | const FunctionDecl *FD = Callee->getMostRecentDecl(); | ||||||||
2472 | DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD); | ||||||||
2473 | if (LangOpts.OpenMPIsDevice && DevTy && | ||||||||
2474 | *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { | ||||||||
2475 | // Diagnose host function called during device codegen. | ||||||||
2476 | StringRef HostDevTy = | ||||||||
2477 | getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host); | ||||||||
2478 | Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; | ||||||||
2479 | Diag(*OMPDeclareTargetDeclAttr::getLocation(FD), | ||||||||
2480 | diag::note_omp_marked_device_type_here) | ||||||||
2481 | << HostDevTy; | ||||||||
2482 | return; | ||||||||
2483 | } | ||||||||
2484 | if (!LangOpts.OpenMPIsDevice && DevTy && | ||||||||
2485 | *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { | ||||||||
2486 | // Diagnose nohost function called during host codegen. | ||||||||
2487 | StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( | ||||||||
2488 | OMPC_device_type, OMPC_DEVICE_TYPE_nohost); | ||||||||
2489 | Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; | ||||||||
2490 | Diag(*OMPDeclareTargetDeclAttr::getLocation(FD), | ||||||||
2491 | diag::note_omp_marked_device_type_here) | ||||||||
2492 | << NoHostDevTy; | ||||||||
2493 | } | ||||||||
2494 | } | ||||||||
2495 | |||||||||
2496 | void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, | ||||||||
2497 | const DeclarationNameInfo &DirName, | ||||||||
2498 | Scope *CurScope, SourceLocation Loc) { | ||||||||
2499 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->push(DKind, DirName, CurScope, Loc); | ||||||||
2500 | PushExpressionEvaluationContext( | ||||||||
2501 | ExpressionEvaluationContext::PotentiallyEvaluated); | ||||||||
2502 | } | ||||||||
2503 | |||||||||
2504 | void Sema::StartOpenMPClause(OpenMPClauseKind K) { | ||||||||
2505 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setClauseParsingMode(K); | ||||||||
2506 | } | ||||||||
2507 | |||||||||
2508 | void Sema::EndOpenMPClause() { | ||||||||
2509 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setClauseParsingMode(/*K=*/OMPC_unknown); | ||||||||
2510 | } | ||||||||
2511 | |||||||||
2512 | static std::pair<ValueDecl *, bool> | ||||||||
2513 | getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, | ||||||||
2514 | SourceRange &ERange, bool AllowArraySection = false); | ||||||||
2515 | |||||||||
2516 | /// Check consistency of the reduction clauses. | ||||||||
2517 | static void checkReductionClauses(Sema &S, DSAStackTy *Stack, | ||||||||
2518 | ArrayRef<OMPClause *> Clauses) { | ||||||||
2519 | bool InscanFound = false; | ||||||||
2520 | SourceLocation InscanLoc; | ||||||||
2521 | // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions. | ||||||||
2522 | // A reduction clause without the inscan reduction-modifier may not appear on | ||||||||
2523 | // a construct on which a reduction clause with the inscan reduction-modifier | ||||||||
2524 | // appears. | ||||||||
2525 | for (OMPClause *C : Clauses) { | ||||||||
2526 | if (C->getClauseKind() != OMPC_reduction) | ||||||||
2527 | continue; | ||||||||
2528 | auto *RC = cast<OMPReductionClause>(C); | ||||||||
2529 | if (RC->getModifier() == OMPC_REDUCTION_inscan) { | ||||||||
2530 | InscanFound = true; | ||||||||
2531 | InscanLoc = RC->getModifierLoc(); | ||||||||
2532 | continue; | ||||||||
2533 | } | ||||||||
2534 | if (RC->getModifier() == OMPC_REDUCTION_task) { | ||||||||
2535 | // OpenMP 5.0, 2.19.5.4 reduction Clause. | ||||||||
2536 | // A reduction clause with the task reduction-modifier may only appear on | ||||||||
2537 | // a parallel construct, a worksharing construct or a combined or | ||||||||
2538 | // composite construct for which any of the aforementioned constructs is a | ||||||||
2539 | // constituent construct and simd or loop are not constituent constructs. | ||||||||
2540 | OpenMPDirectiveKind CurDir = Stack->getCurrentDirective(); | ||||||||
2541 | if (!(isOpenMPParallelDirective(CurDir) || | ||||||||
2542 | isOpenMPWorksharingDirective(CurDir)) || | ||||||||
2543 | isOpenMPSimdDirective(CurDir)) | ||||||||
2544 | S.Diag(RC->getModifierLoc(), | ||||||||
2545 | diag::err_omp_reduction_task_not_parallel_or_worksharing); | ||||||||
2546 | continue; | ||||||||
2547 | } | ||||||||
2548 | } | ||||||||
2549 | if (InscanFound) { | ||||||||
2550 | for (OMPClause *C : Clauses) { | ||||||||
2551 | if (C->getClauseKind() != OMPC_reduction) | ||||||||
2552 | continue; | ||||||||
2553 | auto *RC = cast<OMPReductionClause>(C); | ||||||||
2554 | if (RC->getModifier() != OMPC_REDUCTION_inscan) { | ||||||||
2555 | S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown | ||||||||
2556 | ? RC->getBeginLoc() | ||||||||
2557 | : RC->getModifierLoc(), | ||||||||
2558 | diag::err_omp_inscan_reduction_expected); | ||||||||
2559 | S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction); | ||||||||
2560 | continue; | ||||||||
2561 | } | ||||||||
2562 | for (Expr *Ref : RC->varlists()) { | ||||||||
2563 | assert(Ref && "NULL expr in OpenMP nontemporal clause.")((Ref && "NULL expr in OpenMP nontemporal clause.") ? static_cast<void> (0) : __assert_fail ("Ref && \"NULL expr in OpenMP nontemporal clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 2563, __PRETTY_FUNCTION__)); | ||||||||
2564 | SourceLocation ELoc; | ||||||||
2565 | SourceRange ERange; | ||||||||
2566 | Expr *SimpleRefExpr = Ref; | ||||||||
2567 | auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, | ||||||||
2568 | /*AllowArraySection=*/true); | ||||||||
2569 | ValueDecl *D = Res.first; | ||||||||
2570 | if (!D) | ||||||||
2571 | continue; | ||||||||
2572 | if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) { | ||||||||
2573 | S.Diag(Ref->getExprLoc(), | ||||||||
2574 | diag::err_omp_reduction_not_inclusive_exclusive) | ||||||||
2575 | << Ref->getSourceRange(); | ||||||||
2576 | } | ||||||||
2577 | } | ||||||||
2578 | } | ||||||||
2579 | } | ||||||||
2580 | } | ||||||||
2581 | |||||||||
2582 | static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, | ||||||||
2583 | ArrayRef<OMPClause *> Clauses); | ||||||||
2584 | static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, | ||||||||
2585 | bool WithInit); | ||||||||
2586 | |||||||||
2587 | static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, | ||||||||
2588 | const ValueDecl *D, | ||||||||
2589 | const DSAStackTy::DSAVarData &DVar, | ||||||||
2590 | bool IsLoopIterVar = false); | ||||||||
2591 | |||||||||
2592 | void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { | ||||||||
2593 | // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] | ||||||||
2594 | // A variable of class type (or array thereof) that appears in a lastprivate | ||||||||
2595 | // clause requires an accessible, unambiguous default constructor for the | ||||||||
2596 | // class type, unless the list item is also specified in a firstprivate | ||||||||
2597 | // clause. | ||||||||
2598 | if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { | ||||||||
2599 | for (OMPClause *C : D->clauses()) { | ||||||||
2600 | if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { | ||||||||
2601 | SmallVector<Expr *, 8> PrivateCopies; | ||||||||
2602 | for (Expr *DE : Clause->varlists()) { | ||||||||
2603 | if (DE->isValueDependent() || DE->isTypeDependent()) { | ||||||||
2604 | PrivateCopies.push_back(nullptr); | ||||||||
2605 | continue; | ||||||||
2606 | } | ||||||||
2607 | auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); | ||||||||
2608 | auto *VD = cast<VarDecl>(DRE->getDecl()); | ||||||||
2609 | QualType Type = VD->getType().getNonReferenceType(); | ||||||||
2610 | const DSAStackTy::DSAVarData DVar = | ||||||||
2611 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(VD, /*FromParent=*/false); | ||||||||
2612 | if (DVar.CKind == OMPC_lastprivate) { | ||||||||
2613 | // Generate helper private variable and initialize it with the | ||||||||
2614 | // default value. The address of the original variable is replaced | ||||||||
2615 | // by the address of the new private variable in CodeGen. This new | ||||||||
2616 | // variable is not added to IdResolver, so the code in the OpenMP | ||||||||
2617 | // region uses original variable for proper diagnostics. | ||||||||
2618 | VarDecl *VDPrivate = buildVarDecl( | ||||||||
2619 | *this, DE->getExprLoc(), Type.getUnqualifiedType(), | ||||||||
2620 | VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); | ||||||||
2621 | ActOnUninitializedDecl(VDPrivate); | ||||||||
2622 | if (VDPrivate->isInvalidDecl()) { | ||||||||
2623 | PrivateCopies.push_back(nullptr); | ||||||||
2624 | continue; | ||||||||
2625 | } | ||||||||
2626 | PrivateCopies.push_back(buildDeclRefExpr( | ||||||||
2627 | *this, VDPrivate, DE->getType(), DE->getExprLoc())); | ||||||||
2628 | } else { | ||||||||
2629 | // The variable is also a firstprivate, so initialization sequence | ||||||||
2630 | // for private copy is generated already. | ||||||||
2631 | PrivateCopies.push_back(nullptr); | ||||||||
2632 | } | ||||||||
2633 | } | ||||||||
2634 | Clause->setPrivateCopies(PrivateCopies); | ||||||||
2635 | continue; | ||||||||
2636 | } | ||||||||
2637 | // Finalize nontemporal clause by handling private copies, if any. | ||||||||
2638 | if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) { | ||||||||
2639 | SmallVector<Expr *, 8> PrivateRefs; | ||||||||
2640 | for (Expr *RefExpr : Clause->varlists()) { | ||||||||
2641 | assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")((RefExpr && "NULL expr in OpenMP nontemporal clause." ) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP nontemporal clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 2641, __PRETTY_FUNCTION__)); | ||||||||
2642 | SourceLocation ELoc; | ||||||||
2643 | SourceRange ERange; | ||||||||
2644 | Expr *SimpleRefExpr = RefExpr; | ||||||||
2645 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||||||
2646 | if (Res.second) | ||||||||
2647 | // It will be analyzed later. | ||||||||
2648 | PrivateRefs.push_back(RefExpr); | ||||||||
2649 | ValueDecl *D = Res.first; | ||||||||
2650 | if (!D) | ||||||||
2651 | continue; | ||||||||
2652 | |||||||||
2653 | const DSAStackTy::DSAVarData DVar = | ||||||||
2654 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); | ||||||||
2655 | PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy | ||||||||
2656 | : SimpleRefExpr); | ||||||||
2657 | } | ||||||||
2658 | Clause->setPrivateRefs(PrivateRefs); | ||||||||
2659 | continue; | ||||||||
2660 | } | ||||||||
2661 | if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) { | ||||||||
2662 | for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) { | ||||||||
2663 | OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I); | ||||||||
2664 | auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts()); | ||||||||
2665 | if (!DRE) | ||||||||
2666 | continue; | ||||||||
2667 | ValueDecl *VD = DRE->getDecl(); | ||||||||
2668 | if (!VD || !isa<VarDecl>(VD)) | ||||||||
2669 | continue; | ||||||||
2670 | DSAStackTy::DSAVarData DVar = | ||||||||
2671 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(VD, /*FromParent=*/false); | ||||||||
2672 | // OpenMP [2.12.5, target Construct] | ||||||||
2673 | // Memory allocators that appear in a uses_allocators clause cannot | ||||||||
2674 | // appear in other data-sharing attribute clauses or data-mapping | ||||||||
2675 | // attribute clauses in the same construct. | ||||||||
2676 | Expr *MapExpr = nullptr; | ||||||||
2677 | if (DVar.RefExpr || | ||||||||
2678 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->checkMappableExprComponentListsForDecl( | ||||||||
2679 | VD, /*CurrentRegionOnly=*/true, | ||||||||
2680 | [VD, &MapExpr]( | ||||||||
2681 | OMPClauseMappableExprCommon::MappableExprComponentListRef | ||||||||
2682 | MapExprComponents, | ||||||||
2683 | OpenMPClauseKind C) { | ||||||||
2684 | auto MI = MapExprComponents.rbegin(); | ||||||||
2685 | auto ME = MapExprComponents.rend(); | ||||||||
2686 | if (MI != ME && | ||||||||
2687 | MI->getAssociatedDeclaration()->getCanonicalDecl() == | ||||||||
2688 | VD->getCanonicalDecl()) { | ||||||||
2689 | MapExpr = MI->getAssociatedExpression(); | ||||||||
2690 | return true; | ||||||||
2691 | } | ||||||||
2692 | return false; | ||||||||
2693 | })) { | ||||||||
2694 | Diag(D.Allocator->getExprLoc(), | ||||||||
2695 | diag::err_omp_allocator_used_in_clauses) | ||||||||
2696 | << D.Allocator->getSourceRange(); | ||||||||
2697 | if (DVar.RefExpr) | ||||||||
2698 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VD, DVar); | ||||||||
2699 | else | ||||||||
2700 | Diag(MapExpr->getExprLoc(), diag::note_used_here) | ||||||||
2701 | << MapExpr->getSourceRange(); | ||||||||
2702 | } | ||||||||
2703 | } | ||||||||
2704 | continue; | ||||||||
2705 | } | ||||||||
2706 | } | ||||||||
2707 | // Check allocate clauses. | ||||||||
2708 | if (!CurContext->isDependentContext()) | ||||||||
2709 | checkAllocateClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D->clauses()); | ||||||||
2710 | checkReductionClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D->clauses()); | ||||||||
2711 | } | ||||||||
2712 | |||||||||
2713 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->pop(); | ||||||||
2714 | DiscardCleanupsInEvaluationContext(); | ||||||||
2715 | PopExpressionEvaluationContext(); | ||||||||
2716 | } | ||||||||
2717 | |||||||||
2718 | static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, | ||||||||
2719 | Expr *NumIterations, Sema &SemaRef, | ||||||||
2720 | Scope *S, DSAStackTy *Stack); | ||||||||
2721 | |||||||||
2722 | namespace { | ||||||||
2723 | |||||||||
2724 | class VarDeclFilterCCC final : public CorrectionCandidateCallback { | ||||||||
2725 | private: | ||||||||
2726 | Sema &SemaRef; | ||||||||
2727 | |||||||||
2728 | public: | ||||||||
2729 | explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} | ||||||||
2730 | bool ValidateCandidate(const TypoCorrection &Candidate) override { | ||||||||
2731 | NamedDecl *ND = Candidate.getCorrectionDecl(); | ||||||||
2732 | if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { | ||||||||
2733 | return VD->hasGlobalStorage() && | ||||||||
2734 | SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), | ||||||||
2735 | SemaRef.getCurScope()); | ||||||||
2736 | } | ||||||||
2737 | return false; | ||||||||
2738 | } | ||||||||
2739 | |||||||||
2740 | std::unique_ptr<CorrectionCandidateCallback> clone() override { | ||||||||
2741 | return std::make_unique<VarDeclFilterCCC>(*this); | ||||||||
2742 | } | ||||||||
2743 | |||||||||
2744 | }; | ||||||||
2745 | |||||||||
2746 | class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { | ||||||||
2747 | private: | ||||||||
2748 | Sema &SemaRef; | ||||||||
2749 | |||||||||
2750 | public: | ||||||||
2751 | explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} | ||||||||
2752 | bool ValidateCandidate(const TypoCorrection &Candidate) override { | ||||||||
2753 | NamedDecl *ND = Candidate.getCorrectionDecl(); | ||||||||
2754 | if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || | ||||||||
2755 | isa<FunctionDecl>(ND))) { | ||||||||
2756 | return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), | ||||||||
2757 | SemaRef.getCurScope()); | ||||||||
2758 | } | ||||||||
2759 | return false; | ||||||||
2760 | } | ||||||||
2761 | |||||||||
2762 | std::unique_ptr<CorrectionCandidateCallback> clone() override { | ||||||||
2763 | return std::make_unique<VarOrFuncDeclFilterCCC>(*this); | ||||||||
2764 | } | ||||||||
2765 | }; | ||||||||
2766 | |||||||||
2767 | } // namespace | ||||||||
2768 | |||||||||
2769 | ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, | ||||||||
2770 | CXXScopeSpec &ScopeSpec, | ||||||||
2771 | const DeclarationNameInfo &Id, | ||||||||
2772 | OpenMPDirectiveKind Kind) { | ||||||||
2773 | LookupResult Lookup(*this, Id, LookupOrdinaryName); | ||||||||
2774 | LookupParsedName(Lookup, CurScope, &ScopeSpec, true); | ||||||||
2775 | |||||||||
2776 | if (Lookup.isAmbiguous()) | ||||||||
2777 | return ExprError(); | ||||||||
2778 | |||||||||
2779 | VarDecl *VD; | ||||||||
2780 | if (!Lookup.isSingleResult()) { | ||||||||
2781 | VarDeclFilterCCC CCC(*this); | ||||||||
2782 | if (TypoCorrection Corrected = | ||||||||
2783 | CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, | ||||||||
2784 | CTK_ErrorRecovery)) { | ||||||||
2785 | diagnoseTypo(Corrected, | ||||||||
2786 | PDiag(Lookup.empty() | ||||||||
2787 | ? diag::err_undeclared_var_use_suggest | ||||||||
2788 | : diag::err_omp_expected_var_arg_suggest) | ||||||||
2789 | << Id.getName()); | ||||||||
2790 | VD = Corrected.getCorrectionDeclAs<VarDecl>(); | ||||||||
2791 | } else { | ||||||||
2792 | Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use | ||||||||
2793 | : diag::err_omp_expected_var_arg) | ||||||||
2794 | << Id.getName(); | ||||||||
2795 | return ExprError(); | ||||||||
2796 | } | ||||||||
2797 | } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { | ||||||||
2798 | Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); | ||||||||
2799 | Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); | ||||||||
2800 | return ExprError(); | ||||||||
2801 | } | ||||||||
2802 | Lookup.suppressDiagnostics(); | ||||||||
2803 | |||||||||
2804 | // OpenMP [2.9.2, Syntax, C/C++] | ||||||||
2805 | // Variables must be file-scope, namespace-scope, or static block-scope. | ||||||||
2806 | if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { | ||||||||
2807 | Diag(Id.getLoc(), diag::err_omp_global_var_arg) | ||||||||
2808 | << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); | ||||||||
2809 | bool IsDecl = | ||||||||
2810 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||||||
2811 | Diag(VD->getLocation(), | ||||||||
2812 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||||
2813 | << VD; | ||||||||
2814 | return ExprError(); | ||||||||
2815 | } | ||||||||
2816 | |||||||||
2817 | VarDecl *CanonicalVD = VD->getCanonicalDecl(); | ||||||||
2818 | NamedDecl *ND = CanonicalVD; | ||||||||
2819 | // OpenMP [2.9.2, Restrictions, C/C++, p.2] | ||||||||
2820 | // A threadprivate directive for file-scope variables must appear outside | ||||||||
2821 | // any definition or declaration. | ||||||||
2822 | if (CanonicalVD->getDeclContext()->isTranslationUnit() && | ||||||||
2823 | !getCurLexicalContext()->isTranslationUnit()) { | ||||||||
2824 | Diag(Id.getLoc(), diag::err_omp_var_scope) | ||||||||
2825 | << getOpenMPDirectiveName(Kind) << VD; | ||||||||
2826 | bool IsDecl = | ||||||||
2827 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||||||
2828 | Diag(VD->getLocation(), | ||||||||
2829 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||||
2830 | << VD; | ||||||||
2831 | return ExprError(); | ||||||||
2832 | } | ||||||||
2833 | // OpenMP [2.9.2, Restrictions, C/C++, p.3] | ||||||||
2834 | // A threadprivate directive for static class member variables must appear | ||||||||
2835 | // in the class definition, in the same scope in which the member | ||||||||
2836 | // variables are declared. | ||||||||
2837 | if (CanonicalVD->isStaticDataMember() && | ||||||||
2838 | !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { | ||||||||
2839 | Diag(Id.getLoc(), diag::err_omp_var_scope) | ||||||||
2840 | << getOpenMPDirectiveName(Kind) << VD; | ||||||||
2841 | bool IsDecl = | ||||||||
2842 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||||||
2843 | Diag(VD->getLocation(), | ||||||||
2844 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||||
2845 | << VD; | ||||||||
2846 | return ExprError(); | ||||||||
2847 | } | ||||||||
2848 | // OpenMP [2.9.2, Restrictions, C/C++, p.4] | ||||||||
2849 | // A threadprivate directive for namespace-scope variables must appear | ||||||||
2850 | // outside any definition or declaration other than the namespace | ||||||||
2851 | // definition itself. | ||||||||
2852 | if (CanonicalVD->getDeclContext()->isNamespace() && | ||||||||
2853 | (!getCurLexicalContext()->isFileContext() || | ||||||||
2854 | !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { | ||||||||
2855 | Diag(Id.getLoc(), diag::err_omp_var_scope) | ||||||||
2856 | << getOpenMPDirectiveName(Kind) << VD; | ||||||||
2857 | bool IsDecl = | ||||||||
2858 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||||||
2859 | Diag(VD->getLocation(), | ||||||||
2860 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||||
2861 | << VD; | ||||||||
2862 | return ExprError(); | ||||||||
2863 | } | ||||||||
2864 | // OpenMP [2.9.2, Restrictions, C/C++, p.6] | ||||||||
2865 | // A threadprivate directive for static block-scope variables must appear | ||||||||
2866 | // in the scope of the variable and not in a nested scope. | ||||||||
2867 | if (CanonicalVD->isLocalVarDecl() && CurScope && | ||||||||
2868 | !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { | ||||||||
2869 | Diag(Id.getLoc(), diag::err_omp_var_scope) | ||||||||
2870 | << getOpenMPDirectiveName(Kind) << VD; | ||||||||
2871 | bool IsDecl = | ||||||||
2872 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||||||
2873 | Diag(VD->getLocation(), | ||||||||
2874 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||||
2875 | << VD; | ||||||||
2876 | return ExprError(); | ||||||||
2877 | } | ||||||||
2878 | |||||||||
2879 | // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] | ||||||||
2880 | // A threadprivate directive must lexically precede all references to any | ||||||||
2881 | // of the variables in its list. | ||||||||
2882 | if (Kind == OMPD_threadprivate && VD->isUsed() && | ||||||||
2883 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isThreadPrivate(VD)) { | ||||||||
2884 | Diag(Id.getLoc(), diag::err_omp_var_used) | ||||||||
2885 | << getOpenMPDirectiveName(Kind) << VD; | ||||||||
2886 | return ExprError(); | ||||||||
2887 | } | ||||||||
2888 | |||||||||
2889 | QualType ExprType = VD->getType().getNonReferenceType(); | ||||||||
2890 | return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), | ||||||||
2891 | SourceLocation(), VD, | ||||||||
2892 | /*RefersToEnclosingVariableOrCapture=*/false, | ||||||||
2893 | Id.getLoc(), ExprType, VK_LValue); | ||||||||
2894 | } | ||||||||
2895 | |||||||||
2896 | Sema::DeclGroupPtrTy | ||||||||
2897 | Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, | ||||||||
2898 | ArrayRef<Expr *> VarList) { | ||||||||
2899 | if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { | ||||||||
2900 | CurContext->addDecl(D); | ||||||||
2901 | return DeclGroupPtrTy::make(DeclGroupRef(D)); | ||||||||
2902 | } | ||||||||
2903 | return nullptr; | ||||||||
2904 | } | ||||||||
2905 | |||||||||
2906 | namespace { | ||||||||
2907 | class LocalVarRefChecker final | ||||||||
2908 | : public ConstStmtVisitor<LocalVarRefChecker, bool> { | ||||||||
2909 | Sema &SemaRef; | ||||||||
2910 | |||||||||
2911 | public: | ||||||||
2912 | bool VisitDeclRefExpr(const DeclRefExpr *E) { | ||||||||
2913 | if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { | ||||||||
2914 | if (VD->hasLocalStorage()) { | ||||||||
2915 | SemaRef.Diag(E->getBeginLoc(), | ||||||||
2916 | diag::err_omp_local_var_in_threadprivate_init) | ||||||||
2917 | << E->getSourceRange(); | ||||||||
2918 | SemaRef.Diag(VD->getLocation(), diag::note_defined_here) | ||||||||
2919 | << VD << VD->getSourceRange(); | ||||||||
2920 | return true; | ||||||||
2921 | } | ||||||||
2922 | } | ||||||||
2923 | return false; | ||||||||
2924 | } | ||||||||
2925 | bool VisitStmt(const Stmt *S) { | ||||||||
2926 | for (const Stmt *Child : S->children()) { | ||||||||
2927 | if (Child && Visit(Child)) | ||||||||
2928 | return true; | ||||||||
2929 | } | ||||||||
2930 | return false; | ||||||||
2931 | } | ||||||||
2932 | explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} | ||||||||
2933 | }; | ||||||||
2934 | } // namespace | ||||||||
2935 | |||||||||
2936 | OMPThreadPrivateDecl * | ||||||||
2937 | Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { | ||||||||
2938 | SmallVector<Expr *, 8> Vars; | ||||||||
2939 | for (Expr *RefExpr : VarList) { | ||||||||
2940 | auto *DE = cast<DeclRefExpr>(RefExpr); | ||||||||
2941 | auto *VD = cast<VarDecl>(DE->getDecl()); | ||||||||
2942 | SourceLocation ILoc = DE->getExprLoc(); | ||||||||
2943 | |||||||||
2944 | // Mark variable as used. | ||||||||
2945 | VD->setReferenced(); | ||||||||
2946 | VD->markUsed(Context); | ||||||||
2947 | |||||||||
2948 | QualType QType = VD->getType(); | ||||||||
2949 | if (QType->isDependentType() || QType->isInstantiationDependentType()) { | ||||||||
2950 | // It will be analyzed later. | ||||||||
2951 | Vars.push_back(DE); | ||||||||
2952 | continue; | ||||||||
2953 | } | ||||||||
2954 | |||||||||
2955 | // OpenMP [2.9.2, Restrictions, C/C++, p.10] | ||||||||
2956 | // A threadprivate variable must not have an incomplete type. | ||||||||
2957 | if (RequireCompleteType(ILoc, VD->getType(), | ||||||||
2958 | diag::err_omp_threadprivate_incomplete_type)) { | ||||||||
2959 | continue; | ||||||||
2960 | } | ||||||||
2961 | |||||||||
2962 | // OpenMP [2.9.2, Restrictions, C/C++, p.10] | ||||||||
2963 | // A threadprivate variable must not have a reference type. | ||||||||
2964 | if (VD->getType()->isReferenceType()) { | ||||||||
2965 | Diag(ILoc, diag::err_omp_ref_type_arg) | ||||||||
2966 | << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); | ||||||||
2967 | bool IsDecl = | ||||||||
2968 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||||||
2969 | Diag(VD->getLocation(), | ||||||||
2970 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||||
2971 | << VD; | ||||||||
2972 | continue; | ||||||||
2973 | } | ||||||||
2974 | |||||||||
2975 | // Check if this is a TLS variable. If TLS is not being supported, produce | ||||||||
2976 | // the corresponding diagnostic. | ||||||||
2977 | if ((VD->getTLSKind() != VarDecl::TLS_None && | ||||||||
2978 | !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && | ||||||||
2979 | getLangOpts().OpenMPUseTLS && | ||||||||
2980 | getASTContext().getTargetInfo().isTLSSupported())) || | ||||||||
2981 | (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && | ||||||||
2982 | !VD->isLocalVarDecl())) { | ||||||||
2983 | Diag(ILoc, diag::err_omp_var_thread_local) | ||||||||
2984 | << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); | ||||||||
2985 | bool IsDecl = | ||||||||
2986 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||||||
2987 | Diag(VD->getLocation(), | ||||||||
2988 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||||
2989 | << VD; | ||||||||
2990 | continue; | ||||||||
2991 | } | ||||||||
2992 | |||||||||
2993 | // Check if initial value of threadprivate variable reference variable with | ||||||||
2994 | // local storage (it is not supported by runtime). | ||||||||
2995 | if (const Expr *Init = VD->getAnyInitializer()) { | ||||||||
2996 | LocalVarRefChecker Checker(*this); | ||||||||
2997 | if (Checker.Visit(Init)) | ||||||||
2998 | continue; | ||||||||
2999 | } | ||||||||
3000 | |||||||||
3001 | Vars.push_back(RefExpr); | ||||||||
3002 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(VD, DE, OMPC_threadprivate); | ||||||||
3003 | VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( | ||||||||
3004 | Context, SourceRange(Loc, Loc))); | ||||||||
3005 | if (ASTMutationListener *ML = Context.getASTMutationListener()) | ||||||||
3006 | ML->DeclarationMarkedOpenMPThreadPrivate(VD); | ||||||||
3007 | } | ||||||||
3008 | OMPThreadPrivateDecl *D = nullptr; | ||||||||
3009 | if (!Vars.empty()) { | ||||||||
3010 | D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, | ||||||||
3011 | Vars); | ||||||||
3012 | D->setAccess(AS_public); | ||||||||
3013 | } | ||||||||
3014 | return D; | ||||||||
3015 | } | ||||||||
3016 | |||||||||
3017 | static OMPAllocateDeclAttr::AllocatorTypeTy | ||||||||
3018 | getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { | ||||||||
3019 | if (!Allocator) | ||||||||
3020 | return OMPAllocateDeclAttr::OMPNullMemAlloc; | ||||||||
3021 | if (Allocator->isTypeDependent() || Allocator->isValueDependent() || | ||||||||
3022 | Allocator->isInstantiationDependent() || | ||||||||
3023 | Allocator->containsUnexpandedParameterPack()) | ||||||||
3024 | return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; | ||||||||
3025 | auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; | ||||||||
3026 | const Expr *AE = Allocator->IgnoreParenImpCasts(); | ||||||||
3027 | for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { | ||||||||
3028 | auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); | ||||||||
3029 | const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); | ||||||||
3030 | llvm::FoldingSetNodeID AEId, DAEId; | ||||||||
3031 | AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); | ||||||||
3032 | DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); | ||||||||
3033 | if (AEId == DAEId) { | ||||||||
3034 | AllocatorKindRes = AllocatorKind; | ||||||||
3035 | break; | ||||||||
3036 | } | ||||||||
3037 | } | ||||||||
3038 | return AllocatorKindRes; | ||||||||
3039 | } | ||||||||
3040 | |||||||||
3041 | static bool checkPreviousOMPAllocateAttribute( | ||||||||
3042 | Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, | ||||||||
3043 | OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { | ||||||||
3044 | if (!VD->hasAttr<OMPAllocateDeclAttr>()) | ||||||||
3045 | return false; | ||||||||
3046 | const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); | ||||||||
3047 | Expr *PrevAllocator = A->getAllocator(); | ||||||||
3048 | OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = | ||||||||
3049 | getAllocatorKind(S, Stack, PrevAllocator); | ||||||||
3050 | bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; | ||||||||
3051 | if (AllocatorsMatch && | ||||||||
3052 | AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && | ||||||||
3053 | Allocator && PrevAllocator) { | ||||||||
3054 | const Expr *AE = Allocator->IgnoreParenImpCasts(); | ||||||||
3055 | const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); | ||||||||
3056 | llvm::FoldingSetNodeID AEId, PAEId; | ||||||||
3057 | AE->Profile(AEId, S.Context, /*Canonical=*/true); | ||||||||
3058 | PAE->Profile(PAEId, S.Context, /*Canonical=*/true); | ||||||||
3059 | AllocatorsMatch = AEId == PAEId; | ||||||||
3060 | } | ||||||||
3061 | if (!AllocatorsMatch) { | ||||||||
3062 | SmallString<256> AllocatorBuffer; | ||||||||
3063 | llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); | ||||||||
3064 | if (Allocator) | ||||||||
3065 | Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); | ||||||||
3066 | SmallString<256> PrevAllocatorBuffer; | ||||||||
3067 | llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); | ||||||||
3068 | if (PrevAllocator) | ||||||||
3069 | PrevAllocator->printPretty(PrevAllocatorStream, nullptr, | ||||||||
3070 | S.getPrintingPolicy()); | ||||||||
3071 | |||||||||
3072 | SourceLocation AllocatorLoc = | ||||||||
3073 | Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); | ||||||||
3074 | SourceRange AllocatorRange = | ||||||||
3075 | Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); | ||||||||
3076 | SourceLocation PrevAllocatorLoc = | ||||||||
3077 | PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); | ||||||||
3078 | SourceRange PrevAllocatorRange = | ||||||||
3079 | PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); | ||||||||
3080 | S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) | ||||||||
3081 | << (Allocator ? 1 : 0) << AllocatorStream.str() | ||||||||
3082 | << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() | ||||||||
3083 | << AllocatorRange; | ||||||||
3084 | S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) | ||||||||
3085 | << PrevAllocatorRange; | ||||||||
3086 | return true; | ||||||||
3087 | } | ||||||||
3088 | return false; | ||||||||
3089 | } | ||||||||
3090 | |||||||||
3091 | static void | ||||||||
3092 | applyOMPAllocateAttribute(Sema &S, VarDecl *VD, | ||||||||
3093 | OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, | ||||||||
3094 | Expr *Allocator, SourceRange SR) { | ||||||||
3095 | if (VD->hasAttr<OMPAllocateDeclAttr>()) | ||||||||
3096 | return; | ||||||||
3097 | if (Allocator && | ||||||||
3098 | (Allocator->isTypeDependent() || Allocator->isValueDependent() || | ||||||||
3099 | Allocator->isInstantiationDependent() || | ||||||||
3100 | Allocator->containsUnexpandedParameterPack())) | ||||||||
3101 | return; | ||||||||
3102 | auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, | ||||||||
3103 | Allocator, SR); | ||||||||
3104 | VD->addAttr(A); | ||||||||
3105 | if (ASTMutationListener *ML = S.Context.getASTMutationListener()) | ||||||||
3106 | ML->DeclarationMarkedOpenMPAllocate(VD, A); | ||||||||
3107 | } | ||||||||
3108 | |||||||||
3109 | Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( | ||||||||
3110 | SourceLocation Loc, ArrayRef<Expr *> VarList, | ||||||||
3111 | ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { | ||||||||
3112 | assert(Clauses.size() <= 1 && "Expected at most one clause.")((Clauses.size() <= 1 && "Expected at most one clause." ) ? static_cast<void> (0) : __assert_fail ("Clauses.size() <= 1 && \"Expected at most one clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 3112, __PRETTY_FUNCTION__)); | ||||||||
3113 | Expr *Allocator = nullptr; | ||||||||
3114 | if (Clauses.empty()) { | ||||||||
3115 | // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. | ||||||||
3116 | // allocate directives that appear in a target region must specify an | ||||||||
3117 | // allocator clause unless a requires directive with the dynamic_allocators | ||||||||
3118 | // clause is present in the same compilation unit. | ||||||||
3119 | if (LangOpts.OpenMPIsDevice && | ||||||||
3120 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) | ||||||||
3121 | targetDiag(Loc, diag::err_expected_allocator_clause); | ||||||||
3122 | } else { | ||||||||
3123 | Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); | ||||||||
3124 | } | ||||||||
3125 | OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = | ||||||||
3126 | getAllocatorKind(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), Allocator); | ||||||||
3127 | SmallVector<Expr *, 8> Vars; | ||||||||
3128 | for (Expr *RefExpr : VarList) { | ||||||||
3129 | auto *DE = cast<DeclRefExpr>(RefExpr); | ||||||||
3130 | auto *VD = cast<VarDecl>(DE->getDecl()); | ||||||||
3131 | |||||||||
3132 | // Check if this is a TLS variable or global register. | ||||||||
3133 | if (VD->getTLSKind() != VarDecl::TLS_None || | ||||||||
3134 | VD->hasAttr<OMPThreadPrivateDeclAttr>() || | ||||||||
3135 | (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && | ||||||||
3136 | !VD->isLocalVarDecl())) | ||||||||
3137 | continue; | ||||||||
3138 | |||||||||
3139 | // If the used several times in the allocate directive, the same allocator | ||||||||
3140 | // must be used. | ||||||||
3141 | if (checkPreviousOMPAllocateAttribute(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), RefExpr, VD, | ||||||||
3142 | AllocatorKind, Allocator)) | ||||||||
3143 | continue; | ||||||||
3144 | |||||||||
3145 | // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ | ||||||||
3146 | // If a list item has a static storage type, the allocator expression in the | ||||||||
3147 | // allocator clause must be a constant expression that evaluates to one of | ||||||||
3148 | // the predefined memory allocator values. | ||||||||
3149 | if (Allocator && VD->hasGlobalStorage()) { | ||||||||
3150 | if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { | ||||||||
3151 | Diag(Allocator->getExprLoc(), | ||||||||
3152 | diag::err_omp_expected_predefined_allocator) | ||||||||
3153 | << Allocator->getSourceRange(); | ||||||||
3154 | bool IsDecl = VD->isThisDeclarationADefinition(Context) == | ||||||||
3155 | VarDecl::DeclarationOnly; | ||||||||
3156 | Diag(VD->getLocation(), | ||||||||
3157 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||||
3158 | << VD; | ||||||||
3159 | continue; | ||||||||
3160 | } | ||||||||
3161 | } | ||||||||
3162 | |||||||||
3163 | Vars.push_back(RefExpr); | ||||||||
3164 | applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, | ||||||||
3165 | DE->getSourceRange()); | ||||||||
3166 | } | ||||||||
3167 | if (Vars.empty()) | ||||||||
3168 | return nullptr; | ||||||||
3169 | if (!Owner) | ||||||||
3170 | Owner = getCurLexicalContext(); | ||||||||
3171 | auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); | ||||||||
3172 | D->setAccess(AS_public); | ||||||||
3173 | Owner->addDecl(D); | ||||||||
3174 | return DeclGroupPtrTy::make(DeclGroupRef(D)); | ||||||||
3175 | } | ||||||||
3176 | |||||||||
3177 | Sema::DeclGroupPtrTy | ||||||||
3178 | Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, | ||||||||
3179 | ArrayRef<OMPClause *> ClauseList) { | ||||||||
3180 | OMPRequiresDecl *D = nullptr; | ||||||||
3181 | if (!CurContext->isFileContext()) { | ||||||||
3182 | Diag(Loc, diag::err_omp_invalid_scope) << "requires"; | ||||||||
3183 | } else { | ||||||||
3184 | D = CheckOMPRequiresDecl(Loc, ClauseList); | ||||||||
3185 | if (D) { | ||||||||
3186 | CurContext->addDecl(D); | ||||||||
3187 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addRequiresDecl(D); | ||||||||
3188 | } | ||||||||
3189 | } | ||||||||
3190 | return DeclGroupPtrTy::make(DeclGroupRef(D)); | ||||||||
3191 | } | ||||||||
3192 | |||||||||
3193 | OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, | ||||||||
3194 | ArrayRef<OMPClause *> ClauseList) { | ||||||||
3195 | /// For target specific clauses, the requires directive cannot be | ||||||||
3196 | /// specified after the handling of any of the target regions in the | ||||||||
3197 | /// current compilation unit. | ||||||||
3198 | ArrayRef<SourceLocation> TargetLocations = | ||||||||
3199 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getEncounteredTargetLocs(); | ||||||||
3200 | SourceLocation AtomicLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getAtomicDirectiveLoc(); | ||||||||
3201 | if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) { | ||||||||
3202 | for (const OMPClause *CNew : ClauseList) { | ||||||||
3203 | // Check if any of the requires clauses affect target regions. | ||||||||
3204 | if (isa<OMPUnifiedSharedMemoryClause>(CNew) || | ||||||||
3205 | isa<OMPUnifiedAddressClause>(CNew) || | ||||||||
3206 | isa<OMPReverseOffloadClause>(CNew) || | ||||||||
3207 | isa<OMPDynamicAllocatorsClause>(CNew)) { | ||||||||
3208 | Diag(Loc, diag::err_omp_directive_before_requires) | ||||||||
3209 | << "target" << getOpenMPClauseName(CNew->getClauseKind()); | ||||||||
3210 | for (SourceLocation TargetLoc : TargetLocations) { | ||||||||
3211 | Diag(TargetLoc, diag::note_omp_requires_encountered_directive) | ||||||||
3212 | << "target"; | ||||||||
3213 | } | ||||||||
3214 | } else if (!AtomicLoc.isInvalid() && | ||||||||
3215 | isa<OMPAtomicDefaultMemOrderClause>(CNew)) { | ||||||||
3216 | Diag(Loc, diag::err_omp_directive_before_requires) | ||||||||
3217 | << "atomic" << getOpenMPClauseName(CNew->getClauseKind()); | ||||||||
3218 | Diag(AtomicLoc, diag::note_omp_requires_encountered_directive) | ||||||||
3219 | << "atomic"; | ||||||||
3220 | } | ||||||||
3221 | } | ||||||||
3222 | } | ||||||||
3223 | |||||||||
3224 | if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasDuplicateRequiresClause(ClauseList)) | ||||||||
3225 | return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, | ||||||||
3226 | ClauseList); | ||||||||
3227 | return nullptr; | ||||||||
3228 | } | ||||||||
3229 | |||||||||
3230 | static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, | ||||||||
3231 | const ValueDecl *D, | ||||||||
3232 | const DSAStackTy::DSAVarData &DVar, | ||||||||
3233 | bool IsLoopIterVar) { | ||||||||
3234 | if (DVar.RefExpr) { | ||||||||
3235 | SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) | ||||||||
3236 | << getOpenMPClauseName(DVar.CKind); | ||||||||
3237 | return; | ||||||||
3238 | } | ||||||||
3239 | enum { | ||||||||
3240 | PDSA_StaticMemberShared, | ||||||||
3241 | PDSA_StaticLocalVarShared, | ||||||||
3242 | PDSA_LoopIterVarPrivate, | ||||||||
3243 | PDSA_LoopIterVarLinear, | ||||||||
3244 | PDSA_LoopIterVarLastprivate, | ||||||||
3245 | PDSA_ConstVarShared, | ||||||||
3246 | PDSA_GlobalVarShared, | ||||||||
3247 | PDSA_TaskVarFirstprivate, | ||||||||
3248 | PDSA_LocalVarPrivate, | ||||||||
3249 | PDSA_Implicit | ||||||||
3250 | } Reason = PDSA_Implicit; | ||||||||
3251 | bool ReportHint = false; | ||||||||
3252 | auto ReportLoc = D->getLocation(); | ||||||||
3253 | auto *VD = dyn_cast<VarDecl>(D); | ||||||||
3254 | if (IsLoopIterVar) { | ||||||||
3255 | if (DVar.CKind == OMPC_private) | ||||||||
3256 | Reason = PDSA_LoopIterVarPrivate; | ||||||||
3257 | else if (DVar.CKind == OMPC_lastprivate) | ||||||||
3258 | Reason = PDSA_LoopIterVarLastprivate; | ||||||||
3259 | else | ||||||||
3260 | Reason = PDSA_LoopIterVarLinear; | ||||||||
3261 | } else if (isOpenMPTaskingDirective(DVar.DKind) && | ||||||||
3262 | DVar.CKind == OMPC_firstprivate) { | ||||||||
3263 | Reason = PDSA_TaskVarFirstprivate; | ||||||||
3264 | ReportLoc = DVar.ImplicitDSALoc; | ||||||||
3265 | } else if (VD && VD->isStaticLocal()) | ||||||||
3266 | Reason = PDSA_StaticLocalVarShared; | ||||||||
3267 | else if (VD && VD->isStaticDataMember()) | ||||||||
3268 | Reason = PDSA_StaticMemberShared; | ||||||||
3269 | else if (VD && VD->isFileVarDecl()) | ||||||||
3270 | Reason = PDSA_GlobalVarShared; | ||||||||
3271 | else if (D->getType().isConstant(SemaRef.getASTContext())) | ||||||||
3272 | Reason = PDSA_ConstVarShared; | ||||||||
3273 | else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { | ||||||||
3274 | ReportHint = true; | ||||||||
3275 | Reason = PDSA_LocalVarPrivate; | ||||||||
3276 | } | ||||||||
3277 | if (Reason != PDSA_Implicit) { | ||||||||
3278 | SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) | ||||||||
3279 | << Reason << ReportHint | ||||||||
3280 | << getOpenMPDirectiveName(Stack->getCurrentDirective()); | ||||||||
3281 | } else if (DVar.ImplicitDSALoc.isValid()) { | ||||||||
3282 | SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) | ||||||||
3283 | << getOpenMPClauseName(DVar.CKind); | ||||||||
3284 | } | ||||||||
3285 | } | ||||||||
3286 | |||||||||
3287 | static OpenMPMapClauseKind | ||||||||
3288 | getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, | ||||||||
3289 | bool IsAggregateOrDeclareTarget) { | ||||||||
3290 | OpenMPMapClauseKind Kind = OMPC_MAP_unknown; | ||||||||
3291 | switch (M) { | ||||||||
3292 | case OMPC_DEFAULTMAP_MODIFIER_alloc: | ||||||||
3293 | Kind = OMPC_MAP_alloc; | ||||||||
3294 | break; | ||||||||
3295 | case OMPC_DEFAULTMAP_MODIFIER_to: | ||||||||
3296 | Kind = OMPC_MAP_to; | ||||||||
3297 | break; | ||||||||
3298 | case OMPC_DEFAULTMAP_MODIFIER_from: | ||||||||
3299 | Kind = OMPC_MAP_from; | ||||||||
3300 | break; | ||||||||
3301 | case OMPC_DEFAULTMAP_MODIFIER_tofrom: | ||||||||
3302 | Kind = OMPC_MAP_tofrom; | ||||||||
3303 | break; | ||||||||
3304 | case OMPC_DEFAULTMAP_MODIFIER_firstprivate: | ||||||||
3305 | case OMPC_DEFAULTMAP_MODIFIER_last: | ||||||||
3306 | llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 3306); | ||||||||
3307 | case OMPC_DEFAULTMAP_MODIFIER_none: | ||||||||
3308 | case OMPC_DEFAULTMAP_MODIFIER_default: | ||||||||
3309 | case OMPC_DEFAULTMAP_MODIFIER_unknown: | ||||||||
3310 | // IsAggregateOrDeclareTarget could be true if: | ||||||||
3311 | // 1. the implicit behavior for aggregate is tofrom | ||||||||
3312 | // 2. it's a declare target link | ||||||||
3313 | if (IsAggregateOrDeclareTarget) { | ||||||||
3314 | Kind = OMPC_MAP_tofrom; | ||||||||
3315 | break; | ||||||||
3316 | } | ||||||||
3317 | llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 3317); | ||||||||
3318 | } | ||||||||
3319 | assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known")((Kind != OMPC_MAP_unknown && "Expect map kind to be known" ) ? static_cast<void> (0) : __assert_fail ("Kind != OMPC_MAP_unknown && \"Expect map kind to be known\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 3319, __PRETTY_FUNCTION__)); | ||||||||
3320 | return Kind; | ||||||||
3321 | } | ||||||||
3322 | |||||||||
3323 | namespace { | ||||||||
3324 | class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { | ||||||||
3325 | DSAStackTy *Stack; | ||||||||
3326 | Sema &SemaRef; | ||||||||
3327 | bool ErrorFound = false; | ||||||||
3328 | bool TryCaptureCXXThisMembers = false; | ||||||||
3329 | CapturedStmt *CS = nullptr; | ||||||||
3330 | llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; | ||||||||
3331 | llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete]; | ||||||||
3332 | Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; | ||||||||
3333 | llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; | ||||||||
3334 | |||||||||
3335 | void VisitSubCaptures(OMPExecutableDirective *S) { | ||||||||
3336 | // Check implicitly captured variables. | ||||||||
3337 | if (!S->hasAssociatedStmt() || !S->getAssociatedStmt() || | ||||||||
3338 | S->getDirectiveKind() == OMPD_atomic || | ||||||||
3339 | S->getDirectiveKind() == OMPD_critical || | ||||||||
3340 | S->getDirectiveKind() == OMPD_section || | ||||||||
3341 | S->getDirectiveKind() == OMPD_master) | ||||||||
3342 | return; | ||||||||
3343 | visitSubCaptures(S->getInnermostCapturedStmt()); | ||||||||
3344 | // Try to capture inner this->member references to generate correct mappings | ||||||||
3345 | // and diagnostics. | ||||||||
3346 | if (TryCaptureCXXThisMembers || | ||||||||
3347 | (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && | ||||||||
3348 | llvm::any_of(S->getInnermostCapturedStmt()->captures(), | ||||||||
3349 | [](const CapturedStmt::Capture &C) { | ||||||||
3350 | return C.capturesThis(); | ||||||||
3351 | }))) { | ||||||||
3352 | bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; | ||||||||
3353 | TryCaptureCXXThisMembers = true; | ||||||||
3354 | Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); | ||||||||
3355 | TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; | ||||||||
3356 | } | ||||||||
3357 | // In tasks firstprivates are not captured anymore, need to analyze them | ||||||||
3358 | // explicitly. | ||||||||
3359 | if (isOpenMPTaskingDirective(S->getDirectiveKind()) && | ||||||||
3360 | !isOpenMPTaskLoopDirective(S->getDirectiveKind())) { | ||||||||
3361 | for (OMPClause *C : S->clauses()) | ||||||||
3362 | if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) { | ||||||||
3363 | for (Expr *Ref : FC->varlists()) | ||||||||
3364 | Visit(Ref); | ||||||||
3365 | } | ||||||||
3366 | } | ||||||||
3367 | } | ||||||||
3368 | |||||||||
3369 | public: | ||||||||
3370 | void VisitDeclRefExpr(DeclRefExpr *E) { | ||||||||
3371 | if (TryCaptureCXXThisMembers || E->isTypeDependent() || | ||||||||
3372 | E->isValueDependent() || E->containsUnexpandedParameterPack() || | ||||||||
3373 | E->isInstantiationDependent()) | ||||||||
3374 | return; | ||||||||
3375 | if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { | ||||||||
3376 | // Check the datasharing rules for the expressions in the clauses. | ||||||||
3377 | if (!CS) { | ||||||||
3378 | if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) | ||||||||
3379 | if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { | ||||||||
3380 | Visit(CED->getInit()); | ||||||||
3381 | return; | ||||||||
3382 | } | ||||||||
3383 | } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) | ||||||||
3384 | // Do not analyze internal variables and do not enclose them into | ||||||||
3385 | // implicit clauses. | ||||||||
3386 | return; | ||||||||
3387 | VD = VD->getCanonicalDecl(); | ||||||||
3388 | // Skip internally declared variables. | ||||||||
3389 | if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) && | ||||||||
3390 | !Stack->isImplicitTaskFirstprivate(VD)) | ||||||||
3391 | return; | ||||||||
3392 | // Skip allocators in uses_allocators clauses. | ||||||||
3393 | if (Stack->isUsesAllocatorsDecl(VD).hasValue()) | ||||||||
3394 | return; | ||||||||
3395 | |||||||||
3396 | DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); | ||||||||
3397 | // Check if the variable has explicit DSA set and stop analysis if it so. | ||||||||
3398 | if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) | ||||||||
3399 | return; | ||||||||
3400 | |||||||||
3401 | // Skip internally declared static variables. | ||||||||
3402 | llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = | ||||||||
3403 | OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); | ||||||||
3404 | if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && | ||||||||
3405 | (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || | ||||||||
3406 | !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) && | ||||||||
3407 | !Stack->isImplicitTaskFirstprivate(VD)) | ||||||||
3408 | return; | ||||||||
3409 | |||||||||
3410 | SourceLocation ELoc = E->getExprLoc(); | ||||||||
3411 | OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); | ||||||||
3412 | // The default(none) clause requires that each variable that is referenced | ||||||||
3413 | // in the construct, and does not have a predetermined data-sharing | ||||||||
3414 | // attribute, must have its data-sharing attribute explicitly determined | ||||||||
3415 | // by being listed in a data-sharing attribute clause. | ||||||||
3416 | if (DVar.CKind == OMPC_unknown && | ||||||||
3417 | (Stack->getDefaultDSA() == DSA_none || | ||||||||
3418 | Stack->getDefaultDSA() == DSA_firstprivate) && | ||||||||
3419 | isImplicitOrExplicitTaskingRegion(DKind) && | ||||||||
3420 | VarsWithInheritedDSA.count(VD) == 0) { | ||||||||
3421 | bool InheritedDSA = Stack->getDefaultDSA() == DSA_none; | ||||||||
3422 | if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) { | ||||||||
3423 | DSAStackTy::DSAVarData DVar = | ||||||||
3424 | Stack->getImplicitDSA(VD, /*FromParent=*/false); | ||||||||
3425 | InheritedDSA = DVar.CKind == OMPC_unknown; | ||||||||
3426 | } | ||||||||
3427 | if (InheritedDSA) | ||||||||
3428 | VarsWithInheritedDSA[VD] = E; | ||||||||
3429 | return; | ||||||||
3430 | } | ||||||||
3431 | |||||||||
3432 | // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] | ||||||||
3433 | // If implicit-behavior is none, each variable referenced in the | ||||||||
3434 | // construct that does not have a predetermined data-sharing attribute | ||||||||
3435 | // and does not appear in a to or link clause on a declare target | ||||||||
3436 | // directive must be listed in a data-mapping attribute clause, a | ||||||||
3437 | // data-haring attribute clause (including a data-sharing attribute | ||||||||
3438 | // clause on a combined construct where target. is one of the | ||||||||
3439 | // constituent constructs), or an is_device_ptr clause. | ||||||||
3440 | OpenMPDefaultmapClauseKind ClauseKind = | ||||||||
3441 | getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); | ||||||||
3442 | if (SemaRef.getLangOpts().OpenMP >= 50) { | ||||||||
3443 | bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == | ||||||||
3444 | OMPC_DEFAULTMAP_MODIFIER_none; | ||||||||
3445 | if (DVar.CKind == OMPC_unknown && IsModifierNone && | ||||||||
3446 | VarsWithInheritedDSA.count(VD) == 0 && !Res) { | ||||||||
3447 | // Only check for data-mapping attribute and is_device_ptr here | ||||||||
3448 | // since we have already make sure that the declaration does not | ||||||||
3449 | // have a data-sharing attribute above | ||||||||
3450 | if (!Stack->checkMappableExprComponentListsForDecl( | ||||||||
3451 | VD, /*CurrentRegionOnly=*/true, | ||||||||
3452 | [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef | ||||||||
3453 | MapExprComponents, | ||||||||
3454 | OpenMPClauseKind) { | ||||||||
3455 | auto MI = MapExprComponents.rbegin(); | ||||||||
3456 | auto ME = MapExprComponents.rend(); | ||||||||
3457 | return MI != ME && MI->getAssociatedDeclaration() == VD; | ||||||||
3458 | })) { | ||||||||
3459 | VarsWithInheritedDSA[VD] = E; | ||||||||
3460 | return; | ||||||||
3461 | } | ||||||||
3462 | } | ||||||||
3463 | } | ||||||||
3464 | |||||||||
3465 | if (isOpenMPTargetExecutionDirective(DKind) && | ||||||||
3466 | !Stack->isLoopControlVariable(VD).first) { | ||||||||
3467 | if (!Stack->checkMappableExprComponentListsForDecl( | ||||||||
3468 | VD, /*CurrentRegionOnly=*/true, | ||||||||
3469 | [](OMPClauseMappableExprCommon::MappableExprComponentListRef | ||||||||
3470 | StackComponents, | ||||||||
3471 | OpenMPClauseKind) { | ||||||||
3472 | // Variable is used if it has been marked as an array, array | ||||||||
3473 | // section, array shaping or the variable iself. | ||||||||
3474 | return StackComponents.size() == 1 || | ||||||||
3475 | std::all_of( | ||||||||
3476 | std::next(StackComponents.rbegin()), | ||||||||
3477 | StackComponents.rend(), | ||||||||
3478 | [](const OMPClauseMappableExprCommon:: | ||||||||
3479 | MappableComponent &MC) { | ||||||||
3480 | return MC.getAssociatedDeclaration() == | ||||||||
3481 | nullptr && | ||||||||
3482 | (isa<OMPArraySectionExpr>( | ||||||||
3483 | MC.getAssociatedExpression()) || | ||||||||
3484 | isa<OMPArrayShapingExpr>( | ||||||||
3485 | MC.getAssociatedExpression()) || | ||||||||
3486 | isa<ArraySubscriptExpr>( | ||||||||
3487 | MC.getAssociatedExpression())); | ||||||||
3488 | }); | ||||||||
3489 | })) { | ||||||||
3490 | bool IsFirstprivate = false; | ||||||||
3491 | // By default lambdas are captured as firstprivates. | ||||||||
3492 | if (const auto *RD = | ||||||||
3493 | VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) | ||||||||
3494 | IsFirstprivate = RD->isLambda(); | ||||||||
3495 | IsFirstprivate = | ||||||||
3496 | IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); | ||||||||
3497 | if (IsFirstprivate) { | ||||||||
3498 | ImplicitFirstprivate.emplace_back(E); | ||||||||
3499 | } else { | ||||||||
3500 | OpenMPDefaultmapClauseModifier M = | ||||||||
3501 | Stack->getDefaultmapModifier(ClauseKind); | ||||||||
3502 | OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( | ||||||||
3503 | M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); | ||||||||
3504 | ImplicitMap[Kind].emplace_back(E); | ||||||||
3505 | } | ||||||||
3506 | return; | ||||||||
3507 | } | ||||||||
3508 | } | ||||||||
3509 | |||||||||
3510 | // OpenMP [2.9.3.6, Restrictions, p.2] | ||||||||
3511 | // A list item that appears in a reduction clause of the innermost | ||||||||
3512 | // enclosing worksharing or parallel construct may not be accessed in an | ||||||||
3513 | // explicit task. | ||||||||
3514 | DVar = Stack->hasInnermostDSA( | ||||||||
3515 | VD, | ||||||||
3516 | [](OpenMPClauseKind C, bool AppliedToPointee) { | ||||||||
3517 | return C == OMPC_reduction && !AppliedToPointee; | ||||||||
3518 | }, | ||||||||
3519 | [](OpenMPDirectiveKind K) { | ||||||||
3520 | return isOpenMPParallelDirective(K) || | ||||||||
3521 | isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); | ||||||||
3522 | }, | ||||||||
3523 | /*FromParent=*/true); | ||||||||
3524 | if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { | ||||||||
3525 | ErrorFound = true; | ||||||||
3526 | SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); | ||||||||
3527 | reportOriginalDsa(SemaRef, Stack, VD, DVar); | ||||||||
3528 | return; | ||||||||
3529 | } | ||||||||
3530 | |||||||||
3531 | // Define implicit data-sharing attributes for task. | ||||||||
3532 | DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); | ||||||||
3533 | if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) || | ||||||||
3534 | (Stack->getDefaultDSA() == DSA_firstprivate && | ||||||||
3535 | DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) && | ||||||||
3536 | !Stack->isLoopControlVariable(VD).first) { | ||||||||
3537 | ImplicitFirstprivate.push_back(E); | ||||||||
3538 | return; | ||||||||
3539 | } | ||||||||
3540 | |||||||||
3541 | // Store implicitly used globals with declare target link for parent | ||||||||
3542 | // target. | ||||||||
3543 | if (!isOpenMPTargetExecutionDirective(DKind) && Res && | ||||||||
3544 | *Res == OMPDeclareTargetDeclAttr::MT_Link) { | ||||||||
3545 | Stack->addToParentTargetRegionLinkGlobals(E); | ||||||||
3546 | return; | ||||||||
3547 | } | ||||||||
3548 | } | ||||||||
3549 | } | ||||||||
3550 | void VisitMemberExpr(MemberExpr *E) { | ||||||||
3551 | if (E->isTypeDependent() || E->isValueDependent() || | ||||||||
3552 | E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) | ||||||||
3553 | return; | ||||||||
3554 | auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); | ||||||||
3555 | OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); | ||||||||
3556 | if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) { | ||||||||
3557 | if (!FD) | ||||||||
3558 | return; | ||||||||
3559 | DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); | ||||||||
3560 | // Check if the variable has explicit DSA set and stop analysis if it | ||||||||
3561 | // so. | ||||||||
3562 | if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) | ||||||||
3563 | return; | ||||||||
3564 | |||||||||
3565 | if (isOpenMPTargetExecutionDirective(DKind) && | ||||||||
3566 | !Stack->isLoopControlVariable(FD).first && | ||||||||
3567 | !Stack->checkMappableExprComponentListsForDecl( | ||||||||
3568 | FD, /*CurrentRegionOnly=*/true, | ||||||||
3569 | [](OMPClauseMappableExprCommon::MappableExprComponentListRef | ||||||||
3570 | StackComponents, | ||||||||
3571 | OpenMPClauseKind) { | ||||||||
3572 | return isa<CXXThisExpr>( | ||||||||
3573 | cast<MemberExpr>( | ||||||||
3574 | StackComponents.back().getAssociatedExpression()) | ||||||||
3575 | ->getBase() | ||||||||
3576 | ->IgnoreParens()); | ||||||||
3577 | })) { | ||||||||
3578 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] | ||||||||
3579 | // A bit-field cannot appear in a map clause. | ||||||||
3580 | // | ||||||||
3581 | if (FD->isBitField()) | ||||||||
3582 | return; | ||||||||
3583 | |||||||||
3584 | // Check to see if the member expression is referencing a class that | ||||||||
3585 | // has already been explicitly mapped | ||||||||
3586 | if (Stack->isClassPreviouslyMapped(TE->getType())) | ||||||||
3587 | return; | ||||||||
3588 | |||||||||
3589 | OpenMPDefaultmapClauseModifier Modifier = | ||||||||
3590 | Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); | ||||||||
3591 | OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( | ||||||||
3592 | Modifier, /*IsAggregateOrDeclareTarget*/ true); | ||||||||
3593 | ImplicitMap[Kind].emplace_back(E); | ||||||||
3594 | return; | ||||||||
3595 | } | ||||||||
3596 | |||||||||
3597 | SourceLocation ELoc = E->getExprLoc(); | ||||||||
3598 | // OpenMP [2.9.3.6, Restrictions, p.2] | ||||||||
3599 | // A list item that appears in a reduction clause of the innermost | ||||||||
3600 | // enclosing worksharing or parallel construct may not be accessed in | ||||||||
3601 | // an explicit task. | ||||||||
3602 | DVar = Stack->hasInnermostDSA( | ||||||||
3603 | FD, | ||||||||
3604 | [](OpenMPClauseKind C, bool AppliedToPointee) { | ||||||||
3605 | return C == OMPC_reduction && !AppliedToPointee; | ||||||||
3606 | }, | ||||||||
3607 | [](OpenMPDirectiveKind K) { | ||||||||
3608 | return isOpenMPParallelDirective(K) || | ||||||||
3609 | isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); | ||||||||
3610 | }, | ||||||||
3611 | /*FromParent=*/true); | ||||||||
3612 | if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { | ||||||||
3613 | ErrorFound = true; | ||||||||
3614 | SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); | ||||||||
3615 | reportOriginalDsa(SemaRef, Stack, FD, DVar); | ||||||||
3616 | return; | ||||||||
3617 | } | ||||||||
3618 | |||||||||
3619 | // Define implicit data-sharing attributes for task. | ||||||||
3620 | DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); | ||||||||
3621 | if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && | ||||||||
3622 | !Stack->isLoopControlVariable(FD).first) { | ||||||||
3623 | // Check if there is a captured expression for the current field in the | ||||||||
3624 | // region. Do not mark it as firstprivate unless there is no captured | ||||||||
3625 | // expression. | ||||||||
3626 | // TODO: try to make it firstprivate. | ||||||||
3627 | if (DVar.CKind != OMPC_unknown) | ||||||||
3628 | ImplicitFirstprivate.push_back(E); | ||||||||
3629 | } | ||||||||
3630 | return; | ||||||||
3631 | } | ||||||||
3632 | if (isOpenMPTargetExecutionDirective(DKind)) { | ||||||||
3633 | OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; | ||||||||
3634 | if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, | ||||||||
3635 | /*NoDiagnose=*/true)) | ||||||||
3636 | return; | ||||||||
3637 | const auto *VD = cast<ValueDecl>( | ||||||||
3638 | CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); | ||||||||
3639 | if (!Stack->checkMappableExprComponentListsForDecl( | ||||||||
3640 | VD, /*CurrentRegionOnly=*/true, | ||||||||
3641 | [&CurComponents]( | ||||||||
3642 | OMPClauseMappableExprCommon::MappableExprComponentListRef | ||||||||
3643 | StackComponents, | ||||||||
3644 | OpenMPClauseKind) { | ||||||||
3645 | auto CCI = CurComponents.rbegin(); | ||||||||
3646 | auto CCE = CurComponents.rend(); | ||||||||
3647 | for (const auto &SC : llvm::reverse(StackComponents)) { | ||||||||
3648 | // Do both expressions have the same kind? | ||||||||
3649 | if (CCI->getAssociatedExpression()->getStmtClass() != | ||||||||
3650 | SC.getAssociatedExpression()->getStmtClass()) | ||||||||
3651 | if (!((isa<OMPArraySectionExpr>( | ||||||||
3652 | SC.getAssociatedExpression()) || | ||||||||
3653 | isa<OMPArrayShapingExpr>( | ||||||||
3654 | SC.getAssociatedExpression())) && | ||||||||
3655 | isa<ArraySubscriptExpr>( | ||||||||
3656 | CCI->getAssociatedExpression()))) | ||||||||
3657 | return false; | ||||||||
3658 | |||||||||
3659 | const Decl *CCD = CCI->getAssociatedDeclaration(); | ||||||||
3660 | const Decl *SCD = SC.getAssociatedDeclaration(); | ||||||||
3661 | CCD = CCD ? CCD->getCanonicalDecl() : nullptr; | ||||||||
3662 | SCD = SCD ? SCD->getCanonicalDecl() : nullptr; | ||||||||
3663 | if (SCD != CCD) | ||||||||
3664 | return false; | ||||||||
3665 | std::advance(CCI, 1); | ||||||||
3666 | if (CCI == CCE) | ||||||||
3667 | break; | ||||||||
3668 | } | ||||||||
3669 | return true; | ||||||||
3670 | })) { | ||||||||
3671 | Visit(E->getBase()); | ||||||||
3672 | } | ||||||||
3673 | } else if (!TryCaptureCXXThisMembers) { | ||||||||
3674 | Visit(E->getBase()); | ||||||||
3675 | } | ||||||||
3676 | } | ||||||||
3677 | void VisitOMPExecutableDirective(OMPExecutableDirective *S) { | ||||||||
3678 | for (OMPClause *C : S->clauses()) { | ||||||||
3679 | // Skip analysis of arguments of implicitly defined firstprivate clause | ||||||||
3680 | // for task|target directives. | ||||||||
3681 | // Skip analysis of arguments of implicitly defined map clause for target | ||||||||
3682 | // directives. | ||||||||
3683 | if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && | ||||||||
3684 | C->isImplicit())) { | ||||||||
3685 | for (Stmt *CC : C->children()) { | ||||||||
3686 | if (CC) | ||||||||
3687 | Visit(CC); | ||||||||
3688 | } | ||||||||
3689 | } | ||||||||
3690 | } | ||||||||
3691 | // Check implicitly captured variables. | ||||||||
3692 | VisitSubCaptures(S); | ||||||||
3693 | } | ||||||||
3694 | void VisitStmt(Stmt *S) { | ||||||||
3695 | for (Stmt *C : S->children()) { | ||||||||
3696 | if (C) { | ||||||||
3697 | // Check implicitly captured variables in the task-based directives to | ||||||||
3698 | // check if they must be firstprivatized. | ||||||||
3699 | Visit(C); | ||||||||
3700 | } | ||||||||
3701 | } | ||||||||
3702 | } | ||||||||
3703 | |||||||||
3704 | void visitSubCaptures(CapturedStmt *S) { | ||||||||
3705 | for (const CapturedStmt::Capture &Cap : S->captures()) { | ||||||||
3706 | if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) | ||||||||
3707 | continue; | ||||||||
3708 | VarDecl *VD = Cap.getCapturedVar(); | ||||||||
3709 | // Do not try to map the variable if it or its sub-component was mapped | ||||||||
3710 | // already. | ||||||||
3711 | if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && | ||||||||
3712 | Stack->checkMappableExprComponentListsForDecl( | ||||||||
3713 | VD, /*CurrentRegionOnly=*/true, | ||||||||
3714 | [](OMPClauseMappableExprCommon::MappableExprComponentListRef, | ||||||||
3715 | OpenMPClauseKind) { return true; })) | ||||||||
3716 | continue; | ||||||||
3717 | DeclRefExpr *DRE = buildDeclRefExpr( | ||||||||
3718 | SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), | ||||||||
3719 | Cap.getLocation(), /*RefersToCapture=*/true); | ||||||||
3720 | Visit(DRE); | ||||||||
3721 | } | ||||||||
3722 | } | ||||||||
3723 | bool isErrorFound() const { return ErrorFound; } | ||||||||
3724 | ArrayRef<Expr *> getImplicitFirstprivate() const { | ||||||||
3725 | return ImplicitFirstprivate; | ||||||||
3726 | } | ||||||||
3727 | ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const { | ||||||||
3728 | return ImplicitMap[Kind]; | ||||||||
3729 | } | ||||||||
3730 | const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { | ||||||||
3731 | return VarsWithInheritedDSA; | ||||||||
3732 | } | ||||||||
3733 | |||||||||
3734 | DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) | ||||||||
3735 | : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { | ||||||||
3736 | // Process declare target link variables for the target directives. | ||||||||
3737 | if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { | ||||||||
3738 | for (DeclRefExpr *E : Stack->getLinkGlobals()) | ||||||||
3739 | Visit(E); | ||||||||
3740 | } | ||||||||
3741 | } | ||||||||
3742 | }; | ||||||||
3743 | } // namespace | ||||||||
3744 | |||||||||
3745 | void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { | ||||||||
3746 | switch (DKind) { | ||||||||
3747 | case OMPD_parallel: | ||||||||
3748 | case OMPD_parallel_for: | ||||||||
3749 | case OMPD_parallel_for_simd: | ||||||||
3750 | case OMPD_parallel_sections: | ||||||||
3751 | case OMPD_parallel_master: | ||||||||
3752 | case OMPD_teams: | ||||||||
3753 | case OMPD_teams_distribute: | ||||||||
3754 | case OMPD_teams_distribute_simd: { | ||||||||
3755 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); | ||||||||
3756 | QualType KmpInt32PtrTy = | ||||||||
3757 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); | ||||||||
3758 | Sema::CapturedParamNameType Params[] = { | ||||||||
3759 | std::make_pair(".global_tid.", KmpInt32PtrTy), | ||||||||
3760 | std::make_pair(".bound_tid.", KmpInt32PtrTy), | ||||||||
3761 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||||
3762 | }; | ||||||||
3763 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||||
3764 | Params); | ||||||||
3765 | break; | ||||||||
3766 | } | ||||||||
3767 | case OMPD_target_teams: | ||||||||
3768 | case OMPD_target_parallel: | ||||||||
3769 | case OMPD_target_parallel_for: | ||||||||
3770 | case OMPD_target_parallel_for_simd: | ||||||||
3771 | case OMPD_target_teams_distribute: | ||||||||
3772 | case OMPD_target_teams_distribute_simd: { | ||||||||
3773 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); | ||||||||
3774 | QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); | ||||||||
3775 | QualType KmpInt32PtrTy = | ||||||||
3776 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); | ||||||||
3777 | QualType Args[] = {VoidPtrTy}; | ||||||||
3778 | FunctionProtoType::ExtProtoInfo EPI; | ||||||||
3779 | EPI.Variadic = true; | ||||||||
3780 | QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); | ||||||||
3781 | Sema::CapturedParamNameType Params[] = { | ||||||||
3782 | std::make_pair(".global_tid.", KmpInt32Ty), | ||||||||
3783 | std::make_pair(".part_id.", KmpInt32PtrTy), | ||||||||
3784 | std::make_pair(".privates.", VoidPtrTy), | ||||||||
3785 | std::make_pair( | ||||||||
3786 | ".copy_fn.", | ||||||||
3787 | Context.getPointerType(CopyFnType).withConst().withRestrict()), | ||||||||
3788 | std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), | ||||||||
3789 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||||
3790 | }; | ||||||||
3791 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||||
3792 | Params, /*OpenMPCaptureLevel=*/0); | ||||||||
3793 | // Mark this captured region as inlined, because we don't use outlined | ||||||||
3794 | // function directly. | ||||||||
3795 | getCurCapturedRegion()->TheCapturedDecl->addAttr( | ||||||||
3796 | AlwaysInlineAttr::CreateImplicit( | ||||||||
3797 | Context, {}, AttributeCommonInfo::AS_Keyword, | ||||||||
3798 | AlwaysInlineAttr::Keyword_forceinline)); | ||||||||
3799 | Sema::CapturedParamNameType ParamsTarget[] = { | ||||||||
3800 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||||
3801 | }; | ||||||||
3802 | // Start a captured region for 'target' with no implicit parameters. | ||||||||
3803 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||||
3804 | ParamsTarget, /*OpenMPCaptureLevel=*/1); | ||||||||
3805 | Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { | ||||||||
3806 | std::make_pair(".global_tid.", KmpInt32PtrTy), | ||||||||
3807 | std::make_pair(".bound_tid.", KmpInt32PtrTy), | ||||||||
3808 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||||
3809 | }; | ||||||||
3810 | // Start a captured region for 'teams' or 'parallel'. Both regions have | ||||||||
3811 | // the same implicit parameters. | ||||||||
3812 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||||
3813 | ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); | ||||||||
3814 | break; | ||||||||
3815 | } | ||||||||
3816 | case OMPD_target: | ||||||||
3817 | case OMPD_target_simd: { | ||||||||
3818 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); | ||||||||
3819 | QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); | ||||||||
3820 | QualType KmpInt32PtrTy = | ||||||||
3821 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); | ||||||||
3822 | QualType Args[] = {VoidPtrTy}; | ||||||||
3823 | FunctionProtoType::ExtProtoInfo EPI; | ||||||||
3824 | EPI.Variadic = true; | ||||||||
3825 | QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); | ||||||||
3826 | Sema::CapturedParamNameType Params[] = { | ||||||||
3827 | std::make_pair(".global_tid.", KmpInt32Ty), | ||||||||
3828 | std::make_pair(".part_id.", KmpInt32PtrTy), | ||||||||
3829 | std::make_pair(".privates.", VoidPtrTy), | ||||||||
3830 | std::make_pair( | ||||||||
3831 | ".copy_fn.", | ||||||||
3832 | Context.getPointerType(CopyFnType).withConst().withRestrict()), | ||||||||
3833 | std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), | ||||||||
3834 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||||
3835 | }; | ||||||||
3836 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||||
3837 | Params, /*OpenMPCaptureLevel=*/0); | ||||||||
3838 | // Mark this captured region as inlined, because we don't use outlined | ||||||||
3839 | // function directly. | ||||||||
3840 | getCurCapturedRegion()->TheCapturedDecl->addAttr( | ||||||||
3841 | AlwaysInlineAttr::CreateImplicit( | ||||||||
3842 | Context, {}, AttributeCommonInfo::AS_Keyword, | ||||||||
3843 | AlwaysInlineAttr::Keyword_forceinline)); | ||||||||
3844 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||||
3845 | std::make_pair(StringRef(), QualType()), | ||||||||
3846 | /*OpenMPCaptureLevel=*/1); | ||||||||
3847 | break; | ||||||||
3848 | } | ||||||||
3849 | case OMPD_atomic: | ||||||||
3850 | case OMPD_critical: | ||||||||
3851 | case OMPD_section: | ||||||||
3852 | case OMPD_master: | ||||||||
3853 | break; | ||||||||
3854 | case OMPD_simd: | ||||||||
3855 | case OMPD_for: | ||||||||
3856 | case OMPD_for_simd: | ||||||||
3857 | case OMPD_sections: | ||||||||
3858 | case OMPD_single: | ||||||||
3859 | case OMPD_taskgroup: | ||||||||
3860 | case OMPD_distribute: | ||||||||
3861 | case OMPD_distribute_simd: | ||||||||
3862 | case OMPD_ordered: | ||||||||
3863 | case OMPD_target_data: { | ||||||||
3864 | Sema::CapturedParamNameType Params[] = { | ||||||||
3865 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||||
3866 | }; | ||||||||
3867 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||||
3868 | Params); | ||||||||
3869 | break; | ||||||||
3870 | } | ||||||||
3871 | case OMPD_task: { | ||||||||
3872 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); | ||||||||
3873 | QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); | ||||||||
3874 | QualType KmpInt32PtrTy = | ||||||||
3875 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); | ||||||||
3876 | QualType Args[] = {VoidPtrTy}; | ||||||||
3877 | FunctionProtoType::ExtProtoInfo EPI; | ||||||||
3878 | EPI.Variadic = true; | ||||||||
3879 | QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); | ||||||||
3880 | Sema::CapturedParamNameType Params[] = { | ||||||||
3881 | std::make_pair(".global_tid.", KmpInt32Ty), | ||||||||
3882 | std::make_pair(".part_id.", KmpInt32PtrTy), | ||||||||
3883 | std::make_pair(".privates.", VoidPtrTy), | ||||||||
3884 | std::make_pair( | ||||||||
3885 | ".copy_fn.", | ||||||||
3886 | Context.getPointerType(CopyFnType).withConst().withRestrict()), | ||||||||
3887 | std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), | ||||||||
3888 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||||
3889 | }; | ||||||||
3890 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||||
3891 | Params); | ||||||||
3892 | // Mark this captured region as inlined, because we don't use outlined | ||||||||
3893 | // function directly. | ||||||||
3894 | getCurCapturedRegion()->TheCapturedDecl->addAttr( | ||||||||
3895 | AlwaysInlineAttr::CreateImplicit( | ||||||||
3896 | Context, {}, AttributeCommonInfo::AS_Keyword, | ||||||||
3897 | AlwaysInlineAttr::Keyword_forceinline)); | ||||||||
3898 | break; | ||||||||
3899 | } | ||||||||
3900 | case OMPD_taskloop: | ||||||||
3901 | case OMPD_taskloop_simd: | ||||||||
3902 | case OMPD_master_taskloop: | ||||||||
3903 | case OMPD_master_taskloop_simd: { | ||||||||
3904 | QualType KmpInt32Ty = | ||||||||
3905 | Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) | ||||||||
3906 | .withConst(); | ||||||||
3907 | QualType KmpUInt64Ty = | ||||||||
3908 | Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) | ||||||||
3909 | .withConst(); | ||||||||
3910 | QualType KmpInt64Ty = | ||||||||
3911 | Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) | ||||||||
3912 | .withConst(); | ||||||||
3913 | QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); | ||||||||
3914 | QualType KmpInt32PtrTy = | ||||||||
3915 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); | ||||||||
3916 | QualType Args[] = {VoidPtrTy}; | ||||||||
3917 | FunctionProtoType::ExtProtoInfo EPI; | ||||||||
3918 | EPI.Variadic = true; | ||||||||
3919 | QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); | ||||||||
3920 | Sema::CapturedParamNameType Params[] = { | ||||||||
3921 | std::make_pair(".global_tid.", KmpInt32Ty), | ||||||||
3922 | std::make_pair(".part_id.", KmpInt32PtrTy), | ||||||||
3923 | std::make_pair(".privates.", VoidPtrTy), | ||||||||
3924 | std::make_pair( | ||||||||
3925 | ".copy_fn.", | ||||||||
3926 | Context.getPointerType(CopyFnType).withConst().withRestrict()), | ||||||||
3927 | std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), | ||||||||
3928 | std::make_pair(".lb.", KmpUInt64Ty), | ||||||||
3929 | std::make_pair(".ub.", KmpUInt64Ty), | ||||||||
3930 | std::make_pair(".st.", KmpInt64Ty), | ||||||||
3931 | std::make_pair(".liter.", KmpInt32Ty), | ||||||||
3932 | std::make_pair(".reductions.", VoidPtrTy), | ||||||||
3933 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||||
3934 | }; | ||||||||
3935 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||||
3936 | Params); | ||||||||
3937 | // Mark this captured region as inlined, because we don't use outlined | ||||||||
3938 | // function directly. | ||||||||
3939 | getCurCapturedRegion()->TheCapturedDecl->addAttr( | ||||||||
3940 | AlwaysInlineAttr::CreateImplicit( | ||||||||
3941 | Context, {}, AttributeCommonInfo::AS_Keyword, | ||||||||
3942 | AlwaysInlineAttr::Keyword_forceinline)); | ||||||||
3943 | break; | ||||||||
3944 | } | ||||||||
3945 | case OMPD_parallel_master_taskloop: | ||||||||
3946 | case OMPD_parallel_master_taskloop_simd: { | ||||||||
3947 | QualType KmpInt32Ty = | ||||||||
3948 | Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) | ||||||||
3949 | .withConst(); | ||||||||
3950 | QualType KmpUInt64Ty = | ||||||||
3951 | Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) | ||||||||
3952 | .withConst(); | ||||||||
3953 | QualType KmpInt64Ty = | ||||||||
3954 | Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) | ||||||||
3955 | .withConst(); | ||||||||
3956 | QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); | ||||||||
3957 | QualType KmpInt32PtrTy = | ||||||||
3958 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); | ||||||||
3959 | Sema::CapturedParamNameType ParamsParallel[] = { | ||||||||
3960 | std::make_pair(".global_tid.", KmpInt32PtrTy), | ||||||||
3961 | std::make_pair(".bound_tid.", KmpInt32PtrTy), | ||||||||
3962 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||||
3963 | }; | ||||||||
3964 | // Start a captured region for 'parallel'. | ||||||||
3965 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||||
3966 | ParamsParallel, /*OpenMPCaptureLevel=*/0); | ||||||||
3967 | QualType Args[] = {VoidPtrTy}; | ||||||||
3968 | FunctionProtoType::ExtProtoInfo EPI; | ||||||||
3969 | EPI.Variadic = true; | ||||||||
3970 | QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); | ||||||||
3971 | Sema::CapturedParamNameType Params[] = { | ||||||||
3972 | std::make_pair(".global_tid.", KmpInt32Ty), | ||||||||
3973 | std::make_pair(".part_id.", KmpInt32PtrTy), | ||||||||
3974 | std::make_pair(".privates.", VoidPtrTy), | ||||||||
3975 | std::make_pair( | ||||||||
3976 | ".copy_fn.", | ||||||||
3977 | Context.getPointerType(CopyFnType).withConst().withRestrict()), | ||||||||
3978 | std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), | ||||||||
3979 | std::make_pair(".lb.", KmpUInt64Ty), | ||||||||
3980 | std::make_pair(".ub.", KmpUInt64Ty), | ||||||||
3981 | std::make_pair(".st.", KmpInt64Ty), | ||||||||
3982 | std::make_pair(".liter.", KmpInt32Ty), | ||||||||
3983 | std::make_pair(".reductions.", VoidPtrTy), | ||||||||
3984 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||||
3985 | }; | ||||||||
3986 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||||
3987 | Params, /*OpenMPCaptureLevel=*/1); | ||||||||
3988 | // Mark this captured region as inlined, because we don't use outlined | ||||||||
3989 | // function directly. | ||||||||
3990 | getCurCapturedRegion()->TheCapturedDecl->addAttr( | ||||||||
3991 | AlwaysInlineAttr::CreateImplicit( | ||||||||
3992 | Context, {}, AttributeCommonInfo::AS_Keyword, | ||||||||
3993 | AlwaysInlineAttr::Keyword_forceinline)); | ||||||||
3994 | break; | ||||||||
3995 | } | ||||||||
3996 | case OMPD_distribute_parallel_for_simd: | ||||||||
3997 | case OMPD_distribute_parallel_for: { | ||||||||
3998 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); | ||||||||
3999 | QualType KmpInt32PtrTy = | ||||||||
4000 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); | ||||||||
4001 | Sema::CapturedParamNameType Params[] = { | ||||||||
4002 | std::make_pair(".global_tid.", KmpInt32PtrTy), | ||||||||
4003 | std::make_pair(".bound_tid.", KmpInt32PtrTy), | ||||||||
4004 | std::make_pair(".previous.lb.", Context.getSizeType().withConst()), | ||||||||
4005 | std::make_pair(".previous.ub.", Context.getSizeType().withConst()), | ||||||||
4006 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||||
4007 | }; | ||||||||
4008 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||||
4009 | Params); | ||||||||
4010 | break; | ||||||||
4011 | } | ||||||||
4012 | case OMPD_target_teams_distribute_parallel_for: | ||||||||
4013 | case OMPD_target_teams_distribute_parallel_for_simd: { | ||||||||
4014 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); | ||||||||
4015 | QualType KmpInt32PtrTy = | ||||||||
4016 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); | ||||||||
4017 | QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); | ||||||||
4018 | |||||||||
4019 | QualType Args[] = {VoidPtrTy}; | ||||||||
4020 | FunctionProtoType::ExtProtoInfo EPI; | ||||||||
4021 | EPI.Variadic = true; | ||||||||
4022 | QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); | ||||||||
4023 | Sema::CapturedParamNameType Params[] = { | ||||||||
4024 | std::make_pair(".global_tid.", KmpInt32Ty), | ||||||||
4025 | std::make_pair(".part_id.", KmpInt32PtrTy), | ||||||||
4026 | std::make_pair(".privates.", VoidPtrTy), | ||||||||
4027 | std::make_pair( | ||||||||
4028 | ".copy_fn.", | ||||||||
4029 | Context.getPointerType(CopyFnType).withConst().withRestrict()), | ||||||||
4030 | std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), | ||||||||
4031 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||||
4032 | }; | ||||||||
4033 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||||
4034 | Params, /*OpenMPCaptureLevel=*/0); | ||||||||
4035 | // Mark this captured region as inlined, because we don't use outlined | ||||||||
4036 | // function directly. | ||||||||
4037 | getCurCapturedRegion()->TheCapturedDecl->addAttr( | ||||||||
4038 | AlwaysInlineAttr::CreateImplicit( | ||||||||
4039 | Context, {}, AttributeCommonInfo::AS_Keyword, | ||||||||
4040 | AlwaysInlineAttr::Keyword_forceinline)); | ||||||||
4041 | Sema::CapturedParamNameType ParamsTarget[] = { | ||||||||
4042 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||||
4043 | }; | ||||||||
4044 | // Start a captured region for 'target' with no implicit parameters. | ||||||||
4045 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||||
4046 | ParamsTarget, /*OpenMPCaptureLevel=*/1); | ||||||||
4047 | |||||||||
4048 | Sema::CapturedParamNameType ParamsTeams[] = { | ||||||||
4049 | std::make_pair(".global_tid.", KmpInt32PtrTy), | ||||||||
4050 | std::make_pair(".bound_tid.", KmpInt32PtrTy), | ||||||||
4051 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||||
4052 | }; | ||||||||
4053 | // Start a captured region for 'target' with no implicit parameters. | ||||||||
4054 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||||
4055 | ParamsTeams, /*OpenMPCaptureLevel=*/2); | ||||||||
4056 | |||||||||
4057 | Sema::CapturedParamNameType ParamsParallel[] = { | ||||||||
4058 | std::make_pair(".global_tid.", KmpInt32PtrTy), | ||||||||
4059 | std::make_pair(".bound_tid.", KmpInt32PtrTy), | ||||||||
4060 | std::make_pair(".previous.lb.", Context.getSizeType().withConst()), | ||||||||
4061 | std::make_pair(".previous.ub.", Context.getSizeType().withConst()), | ||||||||
4062 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||||
4063 | }; | ||||||||
4064 | // Start a captured region for 'teams' or 'parallel'. Both regions have | ||||||||
4065 | // the same implicit parameters. | ||||||||
4066 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||||
4067 | ParamsParallel, /*OpenMPCaptureLevel=*/3); | ||||||||
4068 | break; | ||||||||
4069 | } | ||||||||
4070 | |||||||||
4071 | case OMPD_teams_distribute_parallel_for: | ||||||||
4072 | case OMPD_teams_distribute_parallel_for_simd: { | ||||||||
4073 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); | ||||||||
4074 | QualType KmpInt32PtrTy = | ||||||||
4075 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); | ||||||||
4076 | |||||||||
4077 | Sema::CapturedParamNameType ParamsTeams[] = { | ||||||||
4078 | std::make_pair(".global_tid.", KmpInt32PtrTy), | ||||||||
4079 | std::make_pair(".bound_tid.", KmpInt32PtrTy), | ||||||||
4080 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||||
4081 | }; | ||||||||
4082 | // Start a captured region for 'target' with no implicit parameters. | ||||||||
4083 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||||
4084 | ParamsTeams, /*OpenMPCaptureLevel=*/0); | ||||||||
4085 | |||||||||
4086 | Sema::CapturedParamNameType ParamsParallel[] = { | ||||||||
4087 | std::make_pair(".global_tid.", KmpInt32PtrTy), | ||||||||
4088 | std::make_pair(".bound_tid.", KmpInt32PtrTy), | ||||||||
4089 | std::make_pair(".previous.lb.", Context.getSizeType().withConst()), | ||||||||
4090 | std::make_pair(".previous.ub.", Context.getSizeType().withConst()), | ||||||||
4091 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||||
4092 | }; | ||||||||
4093 | // Start a captured region for 'teams' or 'parallel'. Both regions have | ||||||||
4094 | // the same implicit parameters. | ||||||||
4095 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||||
4096 | ParamsParallel, /*OpenMPCaptureLevel=*/1); | ||||||||
4097 | break; | ||||||||
4098 | } | ||||||||
4099 | case OMPD_target_update: | ||||||||
4100 | case OMPD_target_enter_data: | ||||||||
4101 | case OMPD_target_exit_data: { | ||||||||
4102 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); | ||||||||
4103 | QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); | ||||||||
4104 | QualType KmpInt32PtrTy = | ||||||||
4105 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); | ||||||||
4106 | QualType Args[] = {VoidPtrTy}; | ||||||||
4107 | FunctionProtoType::ExtProtoInfo EPI; | ||||||||
4108 | EPI.Variadic = true; | ||||||||
4109 | QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); | ||||||||
4110 | Sema::CapturedParamNameType Params[] = { | ||||||||
4111 | std::make_pair(".global_tid.", KmpInt32Ty), | ||||||||
4112 | std::make_pair(".part_id.", KmpInt32PtrTy), | ||||||||
4113 | std::make_pair(".privates.", VoidPtrTy), | ||||||||
4114 | std::make_pair( | ||||||||
4115 | ".copy_fn.", | ||||||||
4116 | Context.getPointerType(CopyFnType).withConst().withRestrict()), | ||||||||
4117 | std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), | ||||||||
4118 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||||
4119 | }; | ||||||||
4120 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||||
4121 | Params); | ||||||||
4122 | // Mark this captured region as inlined, because we don't use outlined | ||||||||
4123 | // function directly. | ||||||||
4124 | getCurCapturedRegion()->TheCapturedDecl->addAttr( | ||||||||
4125 | AlwaysInlineAttr::CreateImplicit( | ||||||||
4126 | Context, {}, AttributeCommonInfo::AS_Keyword, | ||||||||
4127 | AlwaysInlineAttr::Keyword_forceinline)); | ||||||||
4128 | break; | ||||||||
4129 | } | ||||||||
4130 | case OMPD_threadprivate: | ||||||||
4131 | case OMPD_allocate: | ||||||||
4132 | case OMPD_taskyield: | ||||||||
4133 | case OMPD_barrier: | ||||||||
4134 | case OMPD_taskwait: | ||||||||
4135 | case OMPD_cancellation_point: | ||||||||
4136 | case OMPD_cancel: | ||||||||
4137 | case OMPD_flush: | ||||||||
4138 | case OMPD_depobj: | ||||||||
4139 | case OMPD_scan: | ||||||||
4140 | case OMPD_declare_reduction: | ||||||||
4141 | case OMPD_declare_mapper: | ||||||||
4142 | case OMPD_declare_simd: | ||||||||
4143 | case OMPD_declare_target: | ||||||||
4144 | case OMPD_end_declare_target: | ||||||||
4145 | case OMPD_requires: | ||||||||
4146 | case OMPD_declare_variant: | ||||||||
4147 | case OMPD_begin_declare_variant: | ||||||||
4148 | case OMPD_end_declare_variant: | ||||||||
4149 | llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 4149); | ||||||||
4150 | case OMPD_unknown: | ||||||||
4151 | default: | ||||||||
4152 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 4152); | ||||||||
4153 | } | ||||||||
4154 | } | ||||||||
4155 | |||||||||
4156 | int Sema::getNumberOfConstructScopes(unsigned Level) const { | ||||||||
4157 | return getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDirective(Level)); | ||||||||
4158 | } | ||||||||
4159 | |||||||||
4160 | int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { | ||||||||
4161 | SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; | ||||||||
4162 | getOpenMPCaptureRegions(CaptureRegions, DKind); | ||||||||
4163 | return CaptureRegions.size(); | ||||||||
4164 | } | ||||||||
4165 | |||||||||
4166 | static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, | ||||||||
4167 | Expr *CaptureExpr, bool WithInit, | ||||||||
4168 | bool AsExpression) { | ||||||||
4169 | assert(CaptureExpr)((CaptureExpr) ? static_cast<void> (0) : __assert_fail ( "CaptureExpr", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 4169, __PRETTY_FUNCTION__)); | ||||||||
4170 | ASTContext &C = S.getASTContext(); | ||||||||
4171 | Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); | ||||||||
4172 | QualType Ty = Init->getType(); | ||||||||
4173 | if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { | ||||||||
4174 | if (S.getLangOpts().CPlusPlus) { | ||||||||
4175 | Ty = C.getLValueReferenceType(Ty); | ||||||||
4176 | } else { | ||||||||
4177 | Ty = C.getPointerType(Ty); | ||||||||
4178 | ExprResult Res = | ||||||||
4179 | S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); | ||||||||
4180 | if (!Res.isUsable()) | ||||||||
4181 | return nullptr; | ||||||||
4182 | Init = Res.get(); | ||||||||
4183 | } | ||||||||
4184 | WithInit = true; | ||||||||
4185 | } | ||||||||
4186 | auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, | ||||||||
4187 | CaptureExpr->getBeginLoc()); | ||||||||
4188 | if (!WithInit) | ||||||||
4189 | CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); | ||||||||
4190 | S.CurContext->addHiddenDecl(CED); | ||||||||
4191 | S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); | ||||||||
4192 | return CED; | ||||||||
4193 | } | ||||||||
4194 | |||||||||
4195 | static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, | ||||||||
4196 | bool WithInit) { | ||||||||
4197 | OMPCapturedExprDecl *CD; | ||||||||
4198 | if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) | ||||||||
4199 | CD = cast<OMPCapturedExprDecl>(VD); | ||||||||
4200 | else | ||||||||
4201 | CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, | ||||||||
4202 | /*AsExpression=*/false); | ||||||||
4203 | return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), | ||||||||
4204 | CaptureExpr->getExprLoc()); | ||||||||
4205 | } | ||||||||
4206 | |||||||||
4207 | static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { | ||||||||
4208 | CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); | ||||||||
4209 | if (!Ref) { | ||||||||
4210 | OMPCapturedExprDecl *CD = buildCaptureDecl( | ||||||||
4211 | S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, | ||||||||
4212 | /*WithInit=*/true, /*AsExpression=*/true); | ||||||||
4213 | Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), | ||||||||
4214 | CaptureExpr->getExprLoc()); | ||||||||
4215 | } | ||||||||
4216 | ExprResult Res = Ref; | ||||||||
4217 | if (!S.getLangOpts().CPlusPlus && | ||||||||
4218 | CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && | ||||||||
4219 | Ref->getType()->isPointerType()) { | ||||||||
4220 | Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); | ||||||||
4221 | if (!Res.isUsable()) | ||||||||
4222 | return ExprError(); | ||||||||
4223 | } | ||||||||
4224 | return S.DefaultLvalueConversion(Res.get()); | ||||||||
4225 | } | ||||||||
4226 | |||||||||
4227 | namespace { | ||||||||
4228 | // OpenMP directives parsed in this section are represented as a | ||||||||
4229 | // CapturedStatement with an associated statement. If a syntax error | ||||||||
4230 | // is detected during the parsing of the associated statement, the | ||||||||
4231 | // compiler must abort processing and close the CapturedStatement. | ||||||||
4232 | // | ||||||||
4233 | // Combined directives such as 'target parallel' have more than one | ||||||||
4234 | // nested CapturedStatements. This RAII ensures that we unwind out | ||||||||
4235 | // of all the nested CapturedStatements when an error is found. | ||||||||
4236 | class CaptureRegionUnwinderRAII { | ||||||||
4237 | private: | ||||||||
4238 | Sema &S; | ||||||||
4239 | bool &ErrorFound; | ||||||||
4240 | OpenMPDirectiveKind DKind = OMPD_unknown; | ||||||||
4241 | |||||||||
4242 | public: | ||||||||
4243 | CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, | ||||||||
4244 | OpenMPDirectiveKind DKind) | ||||||||
4245 | : S(S), ErrorFound(ErrorFound), DKind(DKind) {} | ||||||||
4246 | ~CaptureRegionUnwinderRAII() { | ||||||||
4247 | if (ErrorFound) { | ||||||||
4248 | int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); | ||||||||
4249 | while (--ThisCaptureLevel >= 0) | ||||||||
4250 | S.ActOnCapturedRegionError(); | ||||||||
4251 | } | ||||||||
4252 | } | ||||||||
4253 | }; | ||||||||
4254 | } // namespace | ||||||||
4255 | |||||||||
4256 | void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { | ||||||||
4257 | // Capture variables captured by reference in lambdas for target-based | ||||||||
4258 | // directives. | ||||||||
4259 | if (!CurContext->isDependentContext() && | ||||||||
4260 | (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()) || | ||||||||
4261 | isOpenMPTargetDataManagementDirective( | ||||||||
4262 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()))) { | ||||||||
4263 | QualType Type = V->getType(); | ||||||||
4264 | if (const auto *RD = Type.getCanonicalType() | ||||||||
4265 | .getNonReferenceType() | ||||||||
4266 | ->getAsCXXRecordDecl()) { | ||||||||
4267 | bool SavedForceCaptureByReferenceInTargetExecutable = | ||||||||
4268 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isForceCaptureByReferenceInTargetExecutable(); | ||||||||
4269 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setForceCaptureByReferenceInTargetExecutable( | ||||||||
4270 | /*V=*/true); | ||||||||
4271 | if (RD->isLambda()) { | ||||||||
4272 | llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; | ||||||||
4273 | FieldDecl *ThisCapture; | ||||||||
4274 | RD->getCaptureFields(Captures, ThisCapture); | ||||||||
4275 | for (const LambdaCapture &LC : RD->captures()) { | ||||||||
4276 | if (LC.getCaptureKind() == LCK_ByRef) { | ||||||||
4277 | VarDecl *VD = LC.getCapturedVar(); | ||||||||
4278 | DeclContext *VDC = VD->getDeclContext(); | ||||||||
4279 | if (!VDC->Encloses(CurContext)) | ||||||||
4280 | continue; | ||||||||
4281 | MarkVariableReferenced(LC.getLocation(), VD); | ||||||||
4282 | } else if (LC.getCaptureKind() == LCK_This) { | ||||||||
4283 | QualType ThisTy = getCurrentThisType(); | ||||||||
4284 | if (!ThisTy.isNull() && | ||||||||
4285 | Context.typesAreCompatible(ThisTy, ThisCapture->getType())) | ||||||||
4286 | CheckCXXThisCapture(LC.getLocation()); | ||||||||
4287 | } | ||||||||
4288 | } | ||||||||
4289 | } | ||||||||
4290 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setForceCaptureByReferenceInTargetExecutable( | ||||||||
4291 | SavedForceCaptureByReferenceInTargetExecutable); | ||||||||
4292 | } | ||||||||
4293 | } | ||||||||
4294 | } | ||||||||
4295 | |||||||||
4296 | static bool checkOrderedOrderSpecified(Sema &S, | ||||||||
4297 | const ArrayRef<OMPClause *> Clauses) { | ||||||||
4298 | const OMPOrderedClause *Ordered = nullptr; | ||||||||
4299 | const OMPOrderClause *Order = nullptr; | ||||||||
4300 | |||||||||
4301 | for (const OMPClause *Clause : Clauses) { | ||||||||
4302 | if (Clause->getClauseKind() == OMPC_ordered) | ||||||||
4303 | Ordered = cast<OMPOrderedClause>(Clause); | ||||||||
4304 | else if (Clause->getClauseKind() == OMPC_order) { | ||||||||
4305 | Order = cast<OMPOrderClause>(Clause); | ||||||||
4306 | if (Order->getKind() != OMPC_ORDER_concurrent) | ||||||||
4307 | Order = nullptr; | ||||||||
4308 | } | ||||||||
4309 | if (Ordered && Order) | ||||||||
4310 | break; | ||||||||
4311 | } | ||||||||
4312 | |||||||||
4313 | if (Ordered && Order) { | ||||||||
4314 | S.Diag(Order->getKindKwLoc(), | ||||||||
4315 | diag::err_omp_simple_clause_incompatible_with_ordered) | ||||||||
4316 | << getOpenMPClauseName(OMPC_order) | ||||||||
4317 | << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) | ||||||||
4318 | << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); | ||||||||
4319 | S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) | ||||||||
4320 | << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); | ||||||||
4321 | return true; | ||||||||
4322 | } | ||||||||
4323 | return false; | ||||||||
4324 | } | ||||||||
4325 | |||||||||
4326 | StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, | ||||||||
4327 | ArrayRef<OMPClause *> Clauses) { | ||||||||
4328 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() == OMPD_atomic || | ||||||||
4329 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() == OMPD_critical || | ||||||||
4330 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() == OMPD_section || | ||||||||
4331 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() == OMPD_master) | ||||||||
4332 | return S; | ||||||||
4333 | |||||||||
4334 | bool ErrorFound = false; | ||||||||
4335 | CaptureRegionUnwinderRAII CaptureRegionUnwinder( | ||||||||
4336 | *this, ErrorFound, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()); | ||||||||
4337 | if (!S.isUsable()) { | ||||||||
4338 | ErrorFound = true; | ||||||||
4339 | return StmtError(); | ||||||||
4340 | } | ||||||||
4341 | |||||||||
4342 | SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; | ||||||||
4343 | getOpenMPCaptureRegions(CaptureRegions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()); | ||||||||
4344 | OMPOrderedClause *OC = nullptr; | ||||||||
4345 | OMPScheduleClause *SC = nullptr; | ||||||||
4346 | SmallVector<const OMPLinearClause *, 4> LCs; | ||||||||
4347 | SmallVector<const OMPClauseWithPreInit *, 4> PICs; | ||||||||
4348 | // This is required for proper codegen. | ||||||||
4349 | for (OMPClause *Clause : Clauses) { | ||||||||
4350 | if (!LangOpts.OpenMPSimd && | ||||||||
4351 | isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()) && | ||||||||
4352 | Clause->getClauseKind() == OMPC_in_reduction) { | ||||||||
4353 | // Capture taskgroup task_reduction descriptors inside the tasking regions | ||||||||
4354 | // with the corresponding in_reduction items. | ||||||||
4355 | auto *IRC = cast<OMPInReductionClause>(Clause); | ||||||||
4356 | for (Expr *E : IRC->taskgroup_descriptors()) | ||||||||
4357 | if (E) | ||||||||
4358 | MarkDeclarationsReferencedInExpr(E); | ||||||||
4359 | } | ||||||||
4360 | if (isOpenMPPrivate(Clause->getClauseKind()) || | ||||||||
4361 | Clause->getClauseKind() == OMPC_copyprivate || | ||||||||
4362 | (getLangOpts().OpenMPUseTLS && | ||||||||
4363 | getASTContext().getTargetInfo().isTLSSupported() && | ||||||||
4364 | Clause->getClauseKind() == OMPC_copyin)) { | ||||||||
4365 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); | ||||||||
4366 | // Mark all variables in private list clauses as used in inner region. | ||||||||
4367 | for (Stmt *VarRef : Clause->children()) { | ||||||||
4368 | if (auto *E = cast_or_null<Expr>(VarRef)) { | ||||||||
4369 | MarkDeclarationsReferencedInExpr(E); | ||||||||
4370 | } | ||||||||
4371 | } | ||||||||
4372 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setForceVarCapturing(/*V=*/false); | ||||||||
4373 | } else if (CaptureRegions.size() > 1 || | ||||||||
4374 | CaptureRegions.back() != OMPD_unknown) { | ||||||||
4375 | if (auto *C = OMPClauseWithPreInit::get(Clause)) | ||||||||
4376 | PICs.push_back(C); | ||||||||
4377 | if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { | ||||||||
4378 | if (Expr *E = C->getPostUpdateExpr()) | ||||||||
4379 | MarkDeclarationsReferencedInExpr(E); | ||||||||
4380 | } | ||||||||
4381 | } | ||||||||
4382 | if (Clause->getClauseKind() == OMPC_schedule) | ||||||||
4383 | SC = cast<OMPScheduleClause>(Clause); | ||||||||
4384 | else if (Clause->getClauseKind() == OMPC_ordered) | ||||||||
4385 | OC = cast<OMPOrderedClause>(Clause); | ||||||||
4386 | else if (Clause->getClauseKind() == OMPC_linear) | ||||||||
4387 | LCs.push_back(cast<OMPLinearClause>(Clause)); | ||||||||
4388 | } | ||||||||
4389 | // Capture allocator expressions if used. | ||||||||
4390 | for (Expr *E : DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getInnerAllocators()) | ||||||||
4391 | MarkDeclarationsReferencedInExpr(E); | ||||||||
4392 | // OpenMP, 2.7.1 Loop Construct, Restrictions | ||||||||
4393 | // The nonmonotonic modifier cannot be specified if an ordered clause is | ||||||||
4394 | // specified. | ||||||||
4395 | if (SC && | ||||||||
4396 | (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || | ||||||||
4397 | SC->getSecondScheduleModifier() == | ||||||||
4398 | OMPC_SCHEDULE_MODIFIER_nonmonotonic) && | ||||||||
4399 | OC) { | ||||||||
4400 | Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic | ||||||||
4401 | ? SC->getFirstScheduleModifierLoc() | ||||||||
4402 | : SC->getSecondScheduleModifierLoc(), | ||||||||
4403 | diag::err_omp_simple_clause_incompatible_with_ordered) | ||||||||
4404 | << getOpenMPClauseName(OMPC_schedule) | ||||||||
4405 | << getOpenMPSimpleClauseTypeName(OMPC_schedule, | ||||||||
4406 | OMPC_SCHEDULE_MODIFIER_nonmonotonic) | ||||||||
4407 | << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); | ||||||||
4408 | ErrorFound = true; | ||||||||
4409 | } | ||||||||
4410 | // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. | ||||||||
4411 | // If an order(concurrent) clause is present, an ordered clause may not appear | ||||||||
4412 | // on the same directive. | ||||||||
4413 | if (checkOrderedOrderSpecified(*this, Clauses)) | ||||||||
4414 | ErrorFound = true; | ||||||||
4415 | if (!LCs.empty() && OC && OC->getNumForLoops()) { | ||||||||
4416 | for (const OMPLinearClause *C : LCs) { | ||||||||
4417 | Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) | ||||||||
4418 | << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); | ||||||||
4419 | } | ||||||||
4420 | ErrorFound = true; | ||||||||
4421 | } | ||||||||
4422 | if (isOpenMPWorksharingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()) && | ||||||||
4423 | isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()) && OC && | ||||||||
4424 | OC->getNumForLoops()) { | ||||||||
4425 | Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) | ||||||||
4426 | << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()); | ||||||||
4427 | ErrorFound = true; | ||||||||
4428 | } | ||||||||
4429 | if (ErrorFound) { | ||||||||
4430 | return StmtError(); | ||||||||
4431 | } | ||||||||
4432 | StmtResult SR = S; | ||||||||
4433 | unsigned CompletedRegions = 0; | ||||||||
4434 | for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { | ||||||||
4435 | // Mark all variables in private list clauses as used in inner region. | ||||||||
4436 | // Required for proper codegen of combined directives. | ||||||||
4437 | // TODO: add processing for other clauses. | ||||||||
4438 | if (ThisCaptureRegion != OMPD_unknown) { | ||||||||
4439 | for (const clang::OMPClauseWithPreInit *C : PICs) { | ||||||||
4440 | OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); | ||||||||
4441 | // Find the particular capture region for the clause if the | ||||||||
4442 | // directive is a combined one with multiple capture regions. | ||||||||
4443 | // If the directive is not a combined one, the capture region | ||||||||
4444 | // associated with the clause is OMPD_unknown and is generated | ||||||||
4445 | // only once. | ||||||||
4446 | if (CaptureRegion == ThisCaptureRegion || | ||||||||
4447 | CaptureRegion == OMPD_unknown) { | ||||||||
4448 | if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { | ||||||||
4449 | for (Decl *D : DS->decls()) | ||||||||
4450 | MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); | ||||||||
4451 | } | ||||||||
4452 | } | ||||||||
4453 | } | ||||||||
4454 | } | ||||||||
4455 | if (ThisCaptureRegion == OMPD_target) { | ||||||||
4456 | // Capture allocator traits in the target region. They are used implicitly | ||||||||
4457 | // and, thus, are not captured by default. | ||||||||
4458 | for (OMPClause *C : Clauses) { | ||||||||
4459 | if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) { | ||||||||
4460 | for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End; | ||||||||
4461 | ++I) { | ||||||||
4462 | OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I); | ||||||||
4463 | if (Expr *E = D.AllocatorTraits) | ||||||||
4464 | MarkDeclarationsReferencedInExpr(E); | ||||||||
4465 | } | ||||||||
4466 | continue; | ||||||||
4467 | } | ||||||||
4468 | } | ||||||||
4469 | } | ||||||||
4470 | if (++CompletedRegions == CaptureRegions.size()) | ||||||||
4471 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setBodyComplete(); | ||||||||
4472 | SR = ActOnCapturedRegionEnd(SR.get()); | ||||||||
4473 | } | ||||||||
4474 | return SR; | ||||||||
4475 | } | ||||||||
4476 | |||||||||
4477 | static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, | ||||||||
4478 | OpenMPDirectiveKind CancelRegion, | ||||||||
4479 | SourceLocation StartLoc) { | ||||||||
4480 | // CancelRegion is only needed for cancel and cancellation_point. | ||||||||
4481 | if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) | ||||||||
4482 | return false; | ||||||||
4483 | |||||||||
4484 | if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || | ||||||||
4485 | CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) | ||||||||
4486 | return false; | ||||||||
4487 | |||||||||
4488 | SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) | ||||||||
4489 | << getOpenMPDirectiveName(CancelRegion); | ||||||||
4490 | return true; | ||||||||
4491 | } | ||||||||
4492 | |||||||||
4493 | static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, | ||||||||
4494 | OpenMPDirectiveKind CurrentRegion, | ||||||||
4495 | const DeclarationNameInfo &CurrentName, | ||||||||
4496 | OpenMPDirectiveKind CancelRegion, | ||||||||
4497 | SourceLocation StartLoc) { | ||||||||
4498 | if (Stack->getCurScope()) { | ||||||||
4499 | OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); | ||||||||
4500 | OpenMPDirectiveKind OffendingRegion = ParentRegion; | ||||||||
4501 | bool NestingProhibited = false; | ||||||||
4502 | bool CloseNesting = true; | ||||||||
4503 | bool OrphanSeen = false; | ||||||||
4504 | enum { | ||||||||
4505 | NoRecommend, | ||||||||
4506 | ShouldBeInParallelRegion, | ||||||||
4507 | ShouldBeInOrderedRegion, | ||||||||
4508 | ShouldBeInTargetRegion, | ||||||||
4509 | ShouldBeInTeamsRegion, | ||||||||
4510 | ShouldBeInLoopSimdRegion, | ||||||||
4511 | } Recommend = NoRecommend; | ||||||||
4512 | if (isOpenMPSimdDirective(ParentRegion) && | ||||||||
4513 | ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || | ||||||||
4514 | (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && | ||||||||
4515 | CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic && | ||||||||
4516 | CurrentRegion != OMPD_scan))) { | ||||||||
4517 | // OpenMP [2.16, Nesting of Regions] | ||||||||
4518 | // OpenMP constructs may not be nested inside a simd region. | ||||||||
4519 | // OpenMP [2.8.1,simd Construct, Restrictions] | ||||||||
4520 | // An ordered construct with the simd clause is the only OpenMP | ||||||||
4521 | // construct that can appear in the simd region. | ||||||||
4522 | // Allowing a SIMD construct nested in another SIMD construct is an | ||||||||
4523 | // extension. The OpenMP 4.5 spec does not allow it. Issue a warning | ||||||||
4524 | // message. | ||||||||
4525 | // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] | ||||||||
4526 | // The only OpenMP constructs that can be encountered during execution of | ||||||||
4527 | // a simd region are the atomic construct, the loop construct, the simd | ||||||||
4528 | // construct and the ordered construct with the simd clause. | ||||||||
4529 | SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) | ||||||||
4530 | ? diag::err_omp_prohibited_region_simd | ||||||||
4531 | : diag::warn_omp_nesting_simd) | ||||||||
4532 | << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); | ||||||||
4533 | return CurrentRegion != OMPD_simd; | ||||||||
4534 | } | ||||||||
4535 | if (ParentRegion == OMPD_atomic) { | ||||||||
4536 | // OpenMP [2.16, Nesting of Regions] | ||||||||
4537 | // OpenMP constructs may not be nested inside an atomic region. | ||||||||
4538 | SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); | ||||||||
4539 | return true; | ||||||||
4540 | } | ||||||||
4541 | if (CurrentRegion == OMPD_section) { | ||||||||
4542 | // OpenMP [2.7.2, sections Construct, Restrictions] | ||||||||
4543 | // Orphaned section directives are prohibited. That is, the section | ||||||||
4544 | // directives must appear within the sections construct and must not be | ||||||||
4545 | // encountered elsewhere in the sections region. | ||||||||
4546 | if (ParentRegion != OMPD_sections && | ||||||||
4547 | ParentRegion != OMPD_parallel_sections) { | ||||||||
4548 | SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) | ||||||||
4549 | << (ParentRegion != OMPD_unknown) | ||||||||
4550 | << getOpenMPDirectiveName(ParentRegion); | ||||||||
4551 | return true; | ||||||||
4552 | } | ||||||||
4553 | return false; | ||||||||
4554 | } | ||||||||
4555 | // Allow some constructs (except teams and cancellation constructs) to be | ||||||||
4556 | // orphaned (they could be used in functions, called from OpenMP regions | ||||||||
4557 | // with the required preconditions). | ||||||||
4558 | if (ParentRegion == OMPD_unknown && | ||||||||
4559 | !isOpenMPNestingTeamsDirective(CurrentRegion) && | ||||||||
4560 | CurrentRegion != OMPD_cancellation_point && | ||||||||
4561 | CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan) | ||||||||
4562 | return false; | ||||||||
4563 | if (CurrentRegion == OMPD_cancellation_point || | ||||||||
4564 | CurrentRegion == OMPD_cancel) { | ||||||||
4565 | // OpenMP [2.16, Nesting of Regions] | ||||||||
4566 | // A cancellation point construct for which construct-type-clause is | ||||||||
4567 | // taskgroup must be nested inside a task construct. A cancellation | ||||||||
4568 | // point construct for which construct-type-clause is not taskgroup must | ||||||||
4569 | // be closely nested inside an OpenMP construct that matches the type | ||||||||
4570 | // specified in construct-type-clause. | ||||||||
4571 | // A cancel construct for which construct-type-clause is taskgroup must be | ||||||||
4572 | // nested inside a task construct. A cancel construct for which | ||||||||
4573 | // construct-type-clause is not taskgroup must be closely nested inside an | ||||||||
4574 | // OpenMP construct that matches the type specified in | ||||||||
4575 | // construct-type-clause. | ||||||||
4576 | NestingProhibited = | ||||||||
4577 | !((CancelRegion == OMPD_parallel && | ||||||||
4578 | (ParentRegion == OMPD_parallel || | ||||||||
4579 | ParentRegion == OMPD_target_parallel)) || | ||||||||
4580 | (CancelRegion == OMPD_for && | ||||||||
4581 | (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || | ||||||||
4582 | ParentRegion == OMPD_target_parallel_for || | ||||||||
4583 | ParentRegion == OMPD_distribute_parallel_for || | ||||||||
4584 | ParentRegion == OMPD_teams_distribute_parallel_for || | ||||||||
4585 | ParentRegion == OMPD_target_teams_distribute_parallel_for)) || | ||||||||
4586 | (CancelRegion == OMPD_taskgroup && | ||||||||
4587 | (ParentRegion == OMPD_task || | ||||||||
4588 | (SemaRef.getLangOpts().OpenMP >= 50 && | ||||||||
4589 | (ParentRegion == OMPD_taskloop || | ||||||||
4590 | ParentRegion == OMPD_master_taskloop || | ||||||||
4591 | ParentRegion == OMPD_parallel_master_taskloop)))) || | ||||||||
4592 | (CancelRegion == OMPD_sections && | ||||||||
4593 | (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || | ||||||||
4594 | ParentRegion == OMPD_parallel_sections))); | ||||||||
4595 | OrphanSeen = ParentRegion == OMPD_unknown; | ||||||||
4596 | } else if (CurrentRegion == OMPD_master) { | ||||||||
4597 | // OpenMP [2.16, Nesting of Regions] | ||||||||
4598 | // A master region may not be closely nested inside a worksharing, | ||||||||
4599 | // atomic, or explicit task region. | ||||||||
4600 | NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || | ||||||||
4601 | isOpenMPTaskingDirective(ParentRegion); | ||||||||
4602 | } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { | ||||||||
4603 | // OpenMP [2.16, Nesting of Regions] | ||||||||
4604 | // A critical region may not be nested (closely or otherwise) inside a | ||||||||
4605 | // critical region with the same name. Note that this restriction is not | ||||||||
4606 | // sufficient to prevent deadlock. | ||||||||
4607 | SourceLocation PreviousCriticalLoc; | ||||||||
4608 | bool DeadLock = Stack->hasDirective( | ||||||||
4609 | [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, | ||||||||
4610 | const DeclarationNameInfo &DNI, | ||||||||
4611 | SourceLocation Loc) { | ||||||||
4612 | if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { | ||||||||
4613 | PreviousCriticalLoc = Loc; | ||||||||
4614 | return true; | ||||||||
4615 | } | ||||||||
4616 | return false; | ||||||||
4617 | }, | ||||||||
4618 | false /* skip top directive */); | ||||||||
4619 | if (DeadLock) { | ||||||||
4620 | SemaRef.Diag(StartLoc, | ||||||||
4621 | diag::err_omp_prohibited_region_critical_same_name) | ||||||||
4622 | << CurrentName.getName(); | ||||||||
4623 | if (PreviousCriticalLoc.isValid()) | ||||||||
4624 | SemaRef.Diag(PreviousCriticalLoc, | ||||||||
4625 | diag::note_omp_previous_critical_region); | ||||||||
4626 | return true; | ||||||||
4627 | } | ||||||||
4628 | } else if (CurrentRegion == OMPD_barrier) { | ||||||||
4629 | // OpenMP [2.16, Nesting of Regions] | ||||||||
4630 | // A barrier region may not be closely nested inside a worksharing, | ||||||||
4631 | // explicit task, critical, ordered, atomic, or master region. | ||||||||
4632 | NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || | ||||||||
4633 | isOpenMPTaskingDirective(ParentRegion) || | ||||||||
4634 | ParentRegion == OMPD_master || | ||||||||
4635 | ParentRegion == OMPD_parallel_master || | ||||||||
4636 | ParentRegion == OMPD_critical || | ||||||||
4637 | ParentRegion == OMPD_ordered; | ||||||||
4638 | } else if (isOpenMPWorksharingDirective(CurrentRegion) && | ||||||||
4639 | !isOpenMPParallelDirective(CurrentRegion) && | ||||||||
4640 | !isOpenMPTeamsDirective(CurrentRegion)) { | ||||||||
4641 | // OpenMP [2.16, Nesting of Regions] | ||||||||
4642 | // A worksharing region may not be closely nested inside a worksharing, | ||||||||
4643 | // explicit task, critical, ordered, atomic, or master region. | ||||||||
4644 | NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || | ||||||||
4645 | isOpenMPTaskingDirective(ParentRegion) || | ||||||||
4646 | ParentRegion == OMPD_master || | ||||||||
4647 | ParentRegion == OMPD_parallel_master || | ||||||||
4648 | ParentRegion == OMPD_critical || | ||||||||
4649 | ParentRegion == OMPD_ordered; | ||||||||
4650 | Recommend = ShouldBeInParallelRegion; | ||||||||
4651 | } else if (CurrentRegion == OMPD_ordered) { | ||||||||
4652 | // OpenMP [2.16, Nesting of Regions] | ||||||||
4653 | // An ordered region may not be closely nested inside a critical, | ||||||||
4654 | // atomic, or explicit task region. | ||||||||
4655 | // An ordered region must be closely nested inside a loop region (or | ||||||||
4656 | // parallel loop region) with an ordered clause. | ||||||||
4657 | // OpenMP [2.8.1,simd Construct, Restrictions] | ||||||||
4658 | // An ordered construct with the simd clause is the only OpenMP construct | ||||||||
4659 | // that can appear in the simd region. | ||||||||
4660 | NestingProhibited = ParentRegion == OMPD_critical || | ||||||||
4661 | isOpenMPTaskingDirective(ParentRegion) || | ||||||||
4662 | !(isOpenMPSimdDirective(ParentRegion) || | ||||||||
4663 | Stack->isParentOrderedRegion()); | ||||||||
4664 | Recommend = ShouldBeInOrderedRegion; | ||||||||
4665 | } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { | ||||||||
4666 | // OpenMP [2.16, Nesting of Regions] | ||||||||
4667 | // If specified, a teams construct must be contained within a target | ||||||||
4668 | // construct. | ||||||||
4669 | NestingProhibited = | ||||||||
4670 | (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || | ||||||||
4671 | (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && | ||||||||
4672 | ParentRegion != OMPD_target); | ||||||||
4673 | OrphanSeen = ParentRegion == OMPD_unknown; | ||||||||
4674 | Recommend = ShouldBeInTargetRegion; | ||||||||
4675 | } else if (CurrentRegion == OMPD_scan) { | ||||||||
4676 | // OpenMP [2.16, Nesting of Regions] | ||||||||
4677 | // If specified, a teams construct must be contained within a target | ||||||||
4678 | // construct. | ||||||||
4679 | NestingProhibited = | ||||||||
4680 | SemaRef.LangOpts.OpenMP < 50 || | ||||||||
4681 | (ParentRegion != OMPD_simd && ParentRegion != OMPD_for && | ||||||||
4682 | ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for && | ||||||||
4683 | ParentRegion != OMPD_parallel_for_simd); | ||||||||
4684 | OrphanSeen = ParentRegion == OMPD_unknown; | ||||||||
4685 | Recommend = ShouldBeInLoopSimdRegion; | ||||||||
4686 | } | ||||||||
4687 | if (!NestingProhibited && | ||||||||
4688 | !isOpenMPTargetExecutionDirective(CurrentRegion) && | ||||||||
4689 | !isOpenMPTargetDataManagementDirective(CurrentRegion) && | ||||||||
4690 | (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { | ||||||||
4691 | // OpenMP [2.16, Nesting of Regions] | ||||||||
4692 | // distribute, parallel, parallel sections, parallel workshare, and the | ||||||||
4693 | // parallel loop and parallel loop SIMD constructs are the only OpenMP | ||||||||
4694 | // constructs that can be closely nested in the teams region. | ||||||||
4695 | NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && | ||||||||
4696 | !isOpenMPDistributeDirective(CurrentRegion); | ||||||||
4697 | Recommend = ShouldBeInParallelRegion; | ||||||||
4698 | } | ||||||||
4699 | if (!NestingProhibited && | ||||||||
4700 | isOpenMPNestingDistributeDirective(CurrentRegion)) { | ||||||||
4701 | // OpenMP 4.5 [2.17 Nesting of Regions] | ||||||||
4702 | // The region associated with the distribute construct must be strictly | ||||||||
4703 | // nested inside a teams region | ||||||||
4704 | NestingProhibited = | ||||||||
4705 | (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); | ||||||||
4706 | Recommend = ShouldBeInTeamsRegion; | ||||||||
4707 | } | ||||||||
4708 | if (!NestingProhibited && | ||||||||
4709 | (isOpenMPTargetExecutionDirective(CurrentRegion) || | ||||||||
4710 | isOpenMPTargetDataManagementDirective(CurrentRegion))) { | ||||||||
4711 | // OpenMP 4.5 [2.17 Nesting of Regions] | ||||||||
4712 | // If a target, target update, target data, target enter data, or | ||||||||
4713 | // target exit data construct is encountered during execution of a | ||||||||
4714 | // target region, the behavior is unspecified. | ||||||||
4715 | NestingProhibited = Stack->hasDirective( | ||||||||
4716 | [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, | ||||||||
4717 | SourceLocation) { | ||||||||
4718 | if (isOpenMPTargetExecutionDirective(K)) { | ||||||||
4719 | OffendingRegion = K; | ||||||||
4720 | return true; | ||||||||
4721 | } | ||||||||
4722 | return false; | ||||||||
4723 | }, | ||||||||
4724 | false /* don't skip top directive */); | ||||||||
4725 | CloseNesting = false; | ||||||||
4726 | } | ||||||||
4727 | if (NestingProhibited) { | ||||||||
4728 | if (OrphanSeen) { | ||||||||
4729 | SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) | ||||||||
4730 | << getOpenMPDirectiveName(CurrentRegion) << Recommend; | ||||||||
4731 | } else { | ||||||||
4732 | SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) | ||||||||
4733 | << CloseNesting << getOpenMPDirectiveName(OffendingRegion) | ||||||||
4734 | << Recommend << getOpenMPDirectiveName(CurrentRegion); | ||||||||
4735 | } | ||||||||
4736 | return true; | ||||||||
4737 | } | ||||||||
4738 | } | ||||||||
4739 | return false; | ||||||||
4740 | } | ||||||||
4741 | |||||||||
4742 | struct Kind2Unsigned { | ||||||||
4743 | using argument_type = OpenMPDirectiveKind; | ||||||||
4744 | unsigned operator()(argument_type DK) { return unsigned(DK); } | ||||||||
4745 | }; | ||||||||
4746 | static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, | ||||||||
4747 | ArrayRef<OMPClause *> Clauses, | ||||||||
4748 | ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { | ||||||||
4749 | bool ErrorFound = false; | ||||||||
4750 | unsigned NamedModifiersNumber = 0; | ||||||||
4751 | llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; | ||||||||
4752 | FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1); | ||||||||
4753 | SmallVector<SourceLocation, 4> NameModifierLoc; | ||||||||
4754 | for (const OMPClause *C : Clauses) { | ||||||||
4755 | if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { | ||||||||
4756 | // At most one if clause without a directive-name-modifier can appear on | ||||||||
4757 | // the directive. | ||||||||
4758 | OpenMPDirectiveKind CurNM = IC->getNameModifier(); | ||||||||
4759 | if (FoundNameModifiers[CurNM]) { | ||||||||
4760 | S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) | ||||||||
4761 | << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) | ||||||||
4762 | << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); | ||||||||
4763 | ErrorFound = true; | ||||||||
4764 | } else if (CurNM != OMPD_unknown) { | ||||||||
4765 | NameModifierLoc.push_back(IC->getNameModifierLoc()); | ||||||||
4766 | ++NamedModifiersNumber; | ||||||||
4767 | } | ||||||||
4768 | FoundNameModifiers[CurNM] = IC; | ||||||||
4769 | if (CurNM == OMPD_unknown) | ||||||||
4770 | continue; | ||||||||
4771 | // Check if the specified name modifier is allowed for the current | ||||||||
4772 | // directive. | ||||||||
4773 | // At most one if clause with the particular directive-name-modifier can | ||||||||
4774 | // appear on the directive. | ||||||||
4775 | bool MatchFound = false; | ||||||||
4776 | for (auto NM : AllowedNameModifiers) { | ||||||||
4777 | if (CurNM == NM) { | ||||||||
4778 | MatchFound = true; | ||||||||
4779 | break; | ||||||||
4780 | } | ||||||||
4781 | } | ||||||||
4782 | if (!MatchFound) { | ||||||||
4783 | S.Diag(IC->getNameModifierLoc(), | ||||||||
4784 | diag::err_omp_wrong_if_directive_name_modifier) | ||||||||
4785 | << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); | ||||||||
4786 | ErrorFound = true; | ||||||||
4787 | } | ||||||||
4788 | } | ||||||||
4789 | } | ||||||||
4790 | // If any if clause on the directive includes a directive-name-modifier then | ||||||||
4791 | // all if clauses on the directive must include a directive-name-modifier. | ||||||||
4792 | if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { | ||||||||
4793 | if (NamedModifiersNumber == AllowedNameModifiers.size()) { | ||||||||
4794 | S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), | ||||||||
4795 | diag::err_omp_no_more_if_clause); | ||||||||
4796 | } else { | ||||||||
4797 | std::string Values; | ||||||||
4798 | std::string Sep(", "); | ||||||||
4799 | unsigned AllowedCnt = 0; | ||||||||
4800 | unsigned TotalAllowedNum = | ||||||||
4801 | AllowedNameModifiers.size() - NamedModifiersNumber; | ||||||||
4802 | for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; | ||||||||
4803 | ++Cnt) { | ||||||||
4804 | OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; | ||||||||
4805 | if (!FoundNameModifiers[NM]) { | ||||||||
4806 | Values += "'"; | ||||||||
4807 | Values += getOpenMPDirectiveName(NM); | ||||||||
4808 | Values += "'"; | ||||||||
4809 | if (AllowedCnt + 2 == TotalAllowedNum) | ||||||||
4810 | Values += " or "; | ||||||||
4811 | else if (AllowedCnt + 1 != TotalAllowedNum) | ||||||||
4812 | Values += Sep; | ||||||||
4813 | ++AllowedCnt; | ||||||||
4814 | } | ||||||||
4815 | } | ||||||||
4816 | S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), | ||||||||
4817 | diag::err_omp_unnamed_if_clause) | ||||||||
4818 | << (TotalAllowedNum > 1) << Values; | ||||||||
4819 | } | ||||||||
4820 | for (SourceLocation Loc : NameModifierLoc) { | ||||||||
4821 | S.Diag(Loc, diag::note_omp_previous_named_if_clause); | ||||||||
4822 | } | ||||||||
4823 | ErrorFound = true; | ||||||||
4824 | } | ||||||||
4825 | return ErrorFound; | ||||||||
4826 | } | ||||||||
4827 | |||||||||
4828 | static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, | ||||||||
4829 | SourceLocation &ELoc, | ||||||||
4830 | SourceRange &ERange, | ||||||||
4831 | bool AllowArraySection) { | ||||||||
4832 | if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || | ||||||||
4833 | RefExpr->containsUnexpandedParameterPack()) | ||||||||
4834 | return std::make_pair(nullptr, true); | ||||||||
4835 | |||||||||
4836 | // OpenMP [3.1, C/C++] | ||||||||
4837 | // A list item is a variable name. | ||||||||
4838 | // OpenMP [2.9.3.3, Restrictions, p.1] | ||||||||
4839 | // A variable that is part of another variable (as an array or | ||||||||
4840 | // structure element) cannot appear in a private clause. | ||||||||
4841 | RefExpr = RefExpr->IgnoreParens(); | ||||||||
4842 | enum { | ||||||||
4843 | NoArrayExpr = -1, | ||||||||
4844 | ArraySubscript = 0, | ||||||||
4845 | OMPArraySection = 1 | ||||||||
4846 | } IsArrayExpr = NoArrayExpr; | ||||||||
4847 | if (AllowArraySection) { | ||||||||
4848 | if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { | ||||||||
4849 | Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); | ||||||||
4850 | while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) | ||||||||
4851 | Base = TempASE->getBase()->IgnoreParenImpCasts(); | ||||||||
4852 | RefExpr = Base; | ||||||||
4853 | IsArrayExpr = ArraySubscript; | ||||||||
4854 | } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { | ||||||||
4855 | Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); | ||||||||
4856 | while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) | ||||||||
4857 | Base = TempOASE->getBase()->IgnoreParenImpCasts(); | ||||||||
4858 | while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) | ||||||||
4859 | Base = TempASE->getBase()->IgnoreParenImpCasts(); | ||||||||
4860 | RefExpr = Base; | ||||||||
4861 | IsArrayExpr = OMPArraySection; | ||||||||
4862 | } | ||||||||
4863 | } | ||||||||
4864 | ELoc = RefExpr->getExprLoc(); | ||||||||
4865 | ERange = RefExpr->getSourceRange(); | ||||||||
4866 | RefExpr = RefExpr->IgnoreParenImpCasts(); | ||||||||
4867 | auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); | ||||||||
4868 | auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); | ||||||||
4869 | if ((!DE || !isa<VarDecl>(DE->getDecl())) && | ||||||||
4870 | (S.getCurrentThisType().isNull() || !ME || | ||||||||
4871 | !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || | ||||||||
4872 | !isa<FieldDecl>(ME->getMemberDecl()))) { | ||||||||
4873 | if (IsArrayExpr != NoArrayExpr) { | ||||||||
4874 | S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr | ||||||||
4875 | << ERange; | ||||||||
4876 | } else { | ||||||||
4877 | S.Diag(ELoc, | ||||||||
4878 | AllowArraySection | ||||||||
4879 | ? diag::err_omp_expected_var_name_member_expr_or_array_item | ||||||||
4880 | : diag::err_omp_expected_var_name_member_expr) | ||||||||
4881 | << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; | ||||||||
4882 | } | ||||||||
4883 | return std::make_pair(nullptr, false); | ||||||||
4884 | } | ||||||||
4885 | return std::make_pair( | ||||||||
4886 | getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); | ||||||||
4887 | } | ||||||||
4888 | |||||||||
4889 | namespace { | ||||||||
4890 | /// Checks if the allocator is used in uses_allocators clause to be allowed in | ||||||||
4891 | /// target regions. | ||||||||
4892 | class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> { | ||||||||
4893 | DSAStackTy *S = nullptr; | ||||||||
4894 | |||||||||
4895 | public: | ||||||||
4896 | bool VisitDeclRefExpr(const DeclRefExpr *E) { | ||||||||
4897 | return S->isUsesAllocatorsDecl(E->getDecl()) | ||||||||
4898 | .getValueOr( | ||||||||
4899 | DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == | ||||||||
4900 | DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait; | ||||||||
4901 | } | ||||||||
4902 | bool VisitStmt(const Stmt *S) { | ||||||||
4903 | for (const Stmt *Child : S->children()) { | ||||||||
4904 | if (Child && Visit(Child)) | ||||||||
4905 | return true; | ||||||||
4906 | } | ||||||||
4907 | return false; | ||||||||
4908 | } | ||||||||
4909 | explicit AllocatorChecker(DSAStackTy *S) : S(S) {} | ||||||||
4910 | }; | ||||||||
4911 | } // namespace | ||||||||
4912 | |||||||||
4913 | static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, | ||||||||
4914 | ArrayRef<OMPClause *> Clauses) { | ||||||||
4915 | assert(!S.CurContext->isDependentContext() &&((!S.CurContext->isDependentContext() && "Expected non-dependent context." ) ? static_cast<void> (0) : __assert_fail ("!S.CurContext->isDependentContext() && \"Expected non-dependent context.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 4916, __PRETTY_FUNCTION__)) | ||||||||
4916 | "Expected non-dependent context.")((!S.CurContext->isDependentContext() && "Expected non-dependent context." ) ? static_cast<void> (0) : __assert_fail ("!S.CurContext->isDependentContext() && \"Expected non-dependent context.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 4916, __PRETTY_FUNCTION__)); | ||||||||
4917 | auto AllocateRange = | ||||||||
4918 | llvm::make_filter_range(Clauses, OMPAllocateClause::classof); | ||||||||
4919 | llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> | ||||||||
4920 | DeclToCopy; | ||||||||
4921 | auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { | ||||||||
4922 | return isOpenMPPrivate(C->getClauseKind()); | ||||||||
4923 | }); | ||||||||
4924 | for (OMPClause *Cl : PrivateRange) { | ||||||||
4925 | MutableArrayRef<Expr *>::iterator I, It, Et; | ||||||||
4926 | if (Cl->getClauseKind() == OMPC_private) { | ||||||||
4927 | auto *PC = cast<OMPPrivateClause>(Cl); | ||||||||
4928 | I = PC->private_copies().begin(); | ||||||||
4929 | It = PC->varlist_begin(); | ||||||||
4930 | Et = PC->varlist_end(); | ||||||||
4931 | } else if (Cl->getClauseKind() == OMPC_firstprivate) { | ||||||||
4932 | auto *PC = cast<OMPFirstprivateClause>(Cl); | ||||||||
4933 | I = PC->private_copies().begin(); | ||||||||
4934 | It = PC->varlist_begin(); | ||||||||
4935 | Et = PC->varlist_end(); | ||||||||
4936 | } else if (Cl->getClauseKind() == OMPC_lastprivate) { | ||||||||
4937 | auto *PC = cast<OMPLastprivateClause>(Cl); | ||||||||
4938 | I = PC->private_copies().begin(); | ||||||||
4939 | It = PC->varlist_begin(); | ||||||||
4940 | Et = PC->varlist_end(); | ||||||||
4941 | } else if (Cl->getClauseKind() == OMPC_linear) { | ||||||||
4942 | auto *PC = cast<OMPLinearClause>(Cl); | ||||||||
4943 | I = PC->privates().begin(); | ||||||||
4944 | It = PC->varlist_begin(); | ||||||||
4945 | Et = PC->varlist_end(); | ||||||||
4946 | } else if (Cl->getClauseKind() == OMPC_reduction) { | ||||||||
4947 | auto *PC = cast<OMPReductionClause>(Cl); | ||||||||
4948 | I = PC->privates().begin(); | ||||||||
4949 | It = PC->varlist_begin(); | ||||||||
4950 | Et = PC->varlist_end(); | ||||||||
4951 | } else if (Cl->getClauseKind() == OMPC_task_reduction) { | ||||||||
4952 | auto *PC = cast<OMPTaskReductionClause>(Cl); | ||||||||
4953 | I = PC->privates().begin(); | ||||||||
4954 | It = PC->varlist_begin(); | ||||||||
4955 | Et = PC->varlist_end(); | ||||||||
4956 | } else if (Cl->getClauseKind() == OMPC_in_reduction) { | ||||||||
4957 | auto *PC = cast<OMPInReductionClause>(Cl); | ||||||||
4958 | I = PC->privates().begin(); | ||||||||
4959 | It = PC->varlist_begin(); | ||||||||
4960 | Et = PC->varlist_end(); | ||||||||
4961 | } else { | ||||||||
4962 | llvm_unreachable("Expected private clause.")::llvm::llvm_unreachable_internal("Expected private clause.", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 4962); | ||||||||
4963 | } | ||||||||
4964 | for (Expr *E : llvm::make_range(It, Et)) { | ||||||||
4965 | if (!*I) { | ||||||||
4966 | ++I; | ||||||||
4967 | continue; | ||||||||
4968 | } | ||||||||
4969 | SourceLocation ELoc; | ||||||||
4970 | SourceRange ERange; | ||||||||
4971 | Expr *SimpleRefExpr = E; | ||||||||
4972 | auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, | ||||||||
4973 | /*AllowArraySection=*/true); | ||||||||
4974 | DeclToCopy.try_emplace(Res.first, | ||||||||
4975 | cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); | ||||||||
4976 | ++I; | ||||||||
4977 | } | ||||||||
4978 | } | ||||||||
4979 | for (OMPClause *C : AllocateRange) { | ||||||||
4980 | auto *AC = cast<OMPAllocateClause>(C); | ||||||||
4981 | if (S.getLangOpts().OpenMP >= 50 && | ||||||||
4982 | !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() && | ||||||||
4983 | isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && | ||||||||
4984 | AC->getAllocator()) { | ||||||||
4985 | Expr *Allocator = AC->getAllocator(); | ||||||||
4986 | // OpenMP, 2.12.5 target Construct | ||||||||
4987 | // Memory allocators that do not appear in a uses_allocators clause cannot | ||||||||
4988 | // appear as an allocator in an allocate clause or be used in the target | ||||||||
4989 | // region unless a requires directive with the dynamic_allocators clause | ||||||||
4990 | // is present in the same compilation unit. | ||||||||
4991 | AllocatorChecker Checker(Stack); | ||||||||
4992 | if (Checker.Visit(Allocator)) | ||||||||
4993 | S.Diag(Allocator->getExprLoc(), | ||||||||
4994 | diag::err_omp_allocator_not_in_uses_allocators) | ||||||||
4995 | << Allocator->getSourceRange(); | ||||||||
4996 | } | ||||||||
4997 | OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = | ||||||||
4998 | getAllocatorKind(S, Stack, AC->getAllocator()); | ||||||||
4999 | // OpenMP, 2.11.4 allocate Clause, Restrictions. | ||||||||
5000 | // For task, taskloop or target directives, allocation requests to memory | ||||||||
5001 | // allocators with the trait access set to thread result in unspecified | ||||||||
5002 | // behavior. | ||||||||
5003 | if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && | ||||||||
5004 | (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || | ||||||||
5005 | isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { | ||||||||
5006 | S.Diag(AC->getAllocator()->getExprLoc(), | ||||||||
5007 | diag::warn_omp_allocate_thread_on_task_target_directive) | ||||||||
5008 | << getOpenMPDirectiveName(Stack->getCurrentDirective()); | ||||||||
5009 | } | ||||||||
5010 | for (Expr *E : AC->varlists()) { | ||||||||
5011 | SourceLocation ELoc; | ||||||||
5012 | SourceRange ERange; | ||||||||
5013 | Expr *SimpleRefExpr = E; | ||||||||
5014 | auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); | ||||||||
5015 | ValueDecl *VD = Res.first; | ||||||||
5016 | DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); | ||||||||
5017 | if (!isOpenMPPrivate(Data.CKind)) { | ||||||||
5018 | S.Diag(E->getExprLoc(), | ||||||||
5019 | diag::err_omp_expected_private_copy_for_allocate); | ||||||||
5020 | continue; | ||||||||
5021 | } | ||||||||
5022 | VarDecl *PrivateVD = DeclToCopy[VD]; | ||||||||
5023 | if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, | ||||||||
5024 | AllocatorKind, AC->getAllocator())) | ||||||||
5025 | continue; | ||||||||
5026 | applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), | ||||||||
5027 | E->getSourceRange()); | ||||||||
5028 | } | ||||||||
5029 | } | ||||||||
5030 | } | ||||||||
5031 | |||||||||
5032 | StmtResult Sema::ActOnOpenMPExecutableDirective( | ||||||||
5033 | OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, | ||||||||
5034 | OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, | ||||||||
5035 | Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { | ||||||||
5036 | StmtResult Res = StmtError(); | ||||||||
5037 | // First check CancelRegion which is then used in checkNestingOfRegions. | ||||||||
5038 | if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || | ||||||||
5039 | checkNestingOfRegions(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), Kind, DirName, CancelRegion, | ||||||||
5040 | StartLoc)) | ||||||||
5041 | return StmtError(); | ||||||||
5042 | |||||||||
5043 | llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; | ||||||||
5044 | VarsWithInheritedDSAType VarsWithInheritedDSA; | ||||||||
5045 | bool ErrorFound = false; | ||||||||
5046 | ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); | ||||||||
5047 | if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic && | ||||||||
5048 | Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master) { | ||||||||
5049 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5049, __PRETTY_FUNCTION__)); | ||||||||
5050 | |||||||||
5051 | // Check default data sharing attributes for referenced variables. | ||||||||
5052 | DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), *this, cast<CapturedStmt>(AStmt)); | ||||||||
5053 | int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); | ||||||||
5054 | Stmt *S = AStmt; | ||||||||
5055 | while (--ThisCaptureLevel >= 0) | ||||||||
5056 | S = cast<CapturedStmt>(S)->getCapturedStmt(); | ||||||||
5057 | DSAChecker.Visit(S); | ||||||||
5058 | if (!isOpenMPTargetDataManagementDirective(Kind) && | ||||||||
5059 | !isOpenMPTaskingDirective(Kind)) { | ||||||||
5060 | // Visit subcaptures to generate implicit clauses for captured vars. | ||||||||
5061 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
5062 | SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; | ||||||||
5063 | getOpenMPCaptureRegions(CaptureRegions, Kind); | ||||||||
5064 | // Ignore outer tasking regions for target directives. | ||||||||
5065 | if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) | ||||||||
5066 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||||
5067 | DSAChecker.visitSubCaptures(CS); | ||||||||
5068 | } | ||||||||
5069 | if (DSAChecker.isErrorFound()) | ||||||||
5070 | return StmtError(); | ||||||||
5071 | // Generate list of implicitly defined firstprivate variables. | ||||||||
5072 | VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); | ||||||||
5073 | |||||||||
5074 | SmallVector<Expr *, 4> ImplicitFirstprivates( | ||||||||
5075 | DSAChecker.getImplicitFirstprivate().begin(), | ||||||||
5076 | DSAChecker.getImplicitFirstprivate().end()); | ||||||||
5077 | SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete]; | ||||||||
5078 | for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { | ||||||||
5079 | ArrayRef<Expr *> ImplicitMap = | ||||||||
5080 | DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I)); | ||||||||
5081 | ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end()); | ||||||||
5082 | } | ||||||||
5083 | // Mark taskgroup task_reduction descriptors as implicitly firstprivate. | ||||||||
5084 | for (OMPClause *C : Clauses) { | ||||||||
5085 | if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { | ||||||||
5086 | for (Expr *E : IRC->taskgroup_descriptors()) | ||||||||
5087 | if (E) | ||||||||
5088 | ImplicitFirstprivates.emplace_back(E); | ||||||||
5089 | } | ||||||||
5090 | // OpenMP 5.0, 2.10.1 task Construct | ||||||||
5091 | // [detach clause]... The event-handle will be considered as if it was | ||||||||
5092 | // specified on a firstprivate clause. | ||||||||
5093 | if (auto *DC = dyn_cast<OMPDetachClause>(C)) | ||||||||
5094 | ImplicitFirstprivates.push_back(DC->getEventHandler()); | ||||||||
5095 | } | ||||||||
5096 | if (!ImplicitFirstprivates.empty()) { | ||||||||
5097 | if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( | ||||||||
5098 | ImplicitFirstprivates, SourceLocation(), SourceLocation(), | ||||||||
5099 | SourceLocation())) { | ||||||||
5100 | ClausesWithImplicit.push_back(Implicit); | ||||||||
5101 | ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != | ||||||||
5102 | ImplicitFirstprivates.size(); | ||||||||
5103 | } else { | ||||||||
5104 | ErrorFound = true; | ||||||||
5105 | } | ||||||||
5106 | } | ||||||||
5107 | int ClauseKindCnt = -1; | ||||||||
5108 | for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) { | ||||||||
5109 | ++ClauseKindCnt; | ||||||||
5110 | if (ImplicitMap.empty()) | ||||||||
5111 | continue; | ||||||||
5112 | CXXScopeSpec MapperIdScopeSpec; | ||||||||
5113 | DeclarationNameInfo MapperId; | ||||||||
5114 | auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); | ||||||||
5115 | if (OMPClause *Implicit = ActOnOpenMPMapClause( | ||||||||
5116 | llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind, | ||||||||
5117 | /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), | ||||||||
5118 | ImplicitMap, OMPVarListLocTy())) { | ||||||||
5119 | ClausesWithImplicit.emplace_back(Implicit); | ||||||||
5120 | ErrorFound |= | ||||||||
5121 | cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size(); | ||||||||
5122 | } else { | ||||||||
5123 | ErrorFound = true; | ||||||||
5124 | } | ||||||||
5125 | } | ||||||||
5126 | } | ||||||||
5127 | |||||||||
5128 | llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; | ||||||||
5129 | switch (Kind) { | ||||||||
5130 | case OMPD_parallel: | ||||||||
5131 | Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||||
5132 | EndLoc); | ||||||||
5133 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||||
5134 | break; | ||||||||
5135 | case OMPD_simd: | ||||||||
5136 | Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, | ||||||||
5137 | VarsWithInheritedDSA); | ||||||||
5138 | if (LangOpts.OpenMP >= 50) | ||||||||
5139 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||||
5140 | break; | ||||||||
5141 | case OMPD_for: | ||||||||
5142 | Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, | ||||||||
5143 | VarsWithInheritedDSA); | ||||||||
5144 | break; | ||||||||
5145 | case OMPD_for_simd: | ||||||||
5146 | Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||||
5147 | EndLoc, VarsWithInheritedDSA); | ||||||||
5148 | if (LangOpts.OpenMP >= 50) | ||||||||
5149 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||||
5150 | break; | ||||||||
5151 | case OMPD_sections: | ||||||||
5152 | Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||||
5153 | EndLoc); | ||||||||
5154 | break; | ||||||||
5155 | case OMPD_section: | ||||||||
5156 | assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp section' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp section' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5157, __PRETTY_FUNCTION__)) | ||||||||
5157 | "No clauses are allowed for 'omp section' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp section' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp section' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5157, __PRETTY_FUNCTION__)); | ||||||||
5158 | Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); | ||||||||
5159 | break; | ||||||||
5160 | case OMPD_single: | ||||||||
5161 | Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||||
5162 | EndLoc); | ||||||||
5163 | break; | ||||||||
5164 | case OMPD_master: | ||||||||
5165 | assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp master' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp master' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5166, __PRETTY_FUNCTION__)) | ||||||||
5166 | "No clauses are allowed for 'omp master' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp master' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp master' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5166, __PRETTY_FUNCTION__)); | ||||||||
5167 | Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); | ||||||||
5168 | break; | ||||||||
5169 | case OMPD_critical: | ||||||||
5170 | Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, | ||||||||
5171 | StartLoc, EndLoc); | ||||||||
5172 | break; | ||||||||
5173 | case OMPD_parallel_for: | ||||||||
5174 | Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||||
5175 | EndLoc, VarsWithInheritedDSA); | ||||||||
5176 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||||
5177 | break; | ||||||||
5178 | case OMPD_parallel_for_simd: | ||||||||
5179 | Res = ActOnOpenMPParallelForSimdDirective( | ||||||||
5180 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||||
5181 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||||
5182 | if (LangOpts.OpenMP >= 50) | ||||||||
5183 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||||
5184 | break; | ||||||||
5185 | case OMPD_parallel_master: | ||||||||
5186 | Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, | ||||||||
5187 | StartLoc, EndLoc); | ||||||||
5188 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||||
5189 | break; | ||||||||
5190 | case OMPD_parallel_sections: | ||||||||
5191 | Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, | ||||||||
5192 | StartLoc, EndLoc); | ||||||||
5193 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||||
5194 | break; | ||||||||
5195 | case OMPD_task: | ||||||||
5196 | Res = | ||||||||
5197 | ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); | ||||||||
5198 | AllowedNameModifiers.push_back(OMPD_task); | ||||||||
5199 | break; | ||||||||
5200 | case OMPD_taskyield: | ||||||||
5201 | assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp taskyield' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskyield' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5202, __PRETTY_FUNCTION__)) | ||||||||
5202 | "No clauses are allowed for 'omp taskyield' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp taskyield' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskyield' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5202, __PRETTY_FUNCTION__)); | ||||||||
5203 | assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp taskyield' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskyield' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5204, __PRETTY_FUNCTION__)) | ||||||||
5204 | "No associated statement allowed for 'omp taskyield' directive")((AStmt == nullptr && "No associated statement allowed for 'omp taskyield' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskyield' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5204, __PRETTY_FUNCTION__)); | ||||||||
5205 | Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); | ||||||||
5206 | break; | ||||||||
5207 | case OMPD_barrier: | ||||||||
5208 | assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp barrier' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp barrier' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5209, __PRETTY_FUNCTION__)) | ||||||||
5209 | "No clauses are allowed for 'omp barrier' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp barrier' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp barrier' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5209, __PRETTY_FUNCTION__)); | ||||||||
5210 | assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp barrier' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp barrier' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5211, __PRETTY_FUNCTION__)) | ||||||||
5211 | "No associated statement allowed for 'omp barrier' directive")((AStmt == nullptr && "No associated statement allowed for 'omp barrier' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp barrier' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5211, __PRETTY_FUNCTION__)); | ||||||||
5212 | Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); | ||||||||
5213 | break; | ||||||||
5214 | case OMPD_taskwait: | ||||||||
5215 | assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp taskwait' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskwait' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5216, __PRETTY_FUNCTION__)) | ||||||||
5216 | "No clauses are allowed for 'omp taskwait' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp taskwait' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskwait' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5216, __PRETTY_FUNCTION__)); | ||||||||
5217 | assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp taskwait' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskwait' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5218, __PRETTY_FUNCTION__)) | ||||||||
5218 | "No associated statement allowed for 'omp taskwait' directive")((AStmt == nullptr && "No associated statement allowed for 'omp taskwait' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskwait' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5218, __PRETTY_FUNCTION__)); | ||||||||
5219 | Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); | ||||||||
5220 | break; | ||||||||
5221 | case OMPD_taskgroup: | ||||||||
5222 | Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||||
5223 | EndLoc); | ||||||||
5224 | break; | ||||||||
5225 | case OMPD_flush: | ||||||||
5226 | assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp flush' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp flush' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5227, __PRETTY_FUNCTION__)) | ||||||||
5227 | "No associated statement allowed for 'omp flush' directive")((AStmt == nullptr && "No associated statement allowed for 'omp flush' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp flush' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5227, __PRETTY_FUNCTION__)); | ||||||||
5228 | Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); | ||||||||
5229 | break; | ||||||||
5230 | case OMPD_depobj: | ||||||||
5231 | assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp depobj' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp depobj' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5232, __PRETTY_FUNCTION__)) | ||||||||
5232 | "No associated statement allowed for 'omp depobj' directive")((AStmt == nullptr && "No associated statement allowed for 'omp depobj' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp depobj' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5232, __PRETTY_FUNCTION__)); | ||||||||
5233 | Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc); | ||||||||
5234 | break; | ||||||||
5235 | case OMPD_scan: | ||||||||
5236 | assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp scan' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp scan' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5237, __PRETTY_FUNCTION__)) | ||||||||
5237 | "No associated statement allowed for 'omp scan' directive")((AStmt == nullptr && "No associated statement allowed for 'omp scan' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp scan' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5237, __PRETTY_FUNCTION__)); | ||||||||
5238 | Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc); | ||||||||
5239 | break; | ||||||||
5240 | case OMPD_ordered: | ||||||||
5241 | Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||||
5242 | EndLoc); | ||||||||
5243 | break; | ||||||||
5244 | case OMPD_atomic: | ||||||||
5245 | Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||||
5246 | EndLoc); | ||||||||
5247 | break; | ||||||||
5248 | case OMPD_teams: | ||||||||
5249 | Res = | ||||||||
5250 | ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); | ||||||||
5251 | break; | ||||||||
5252 | case OMPD_target: | ||||||||
5253 | Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||||
5254 | EndLoc); | ||||||||
5255 | AllowedNameModifiers.push_back(OMPD_target); | ||||||||
5256 | break; | ||||||||
5257 | case OMPD_target_parallel: | ||||||||
5258 | Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, | ||||||||
5259 | StartLoc, EndLoc); | ||||||||
5260 | AllowedNameModifiers.push_back(OMPD_target); | ||||||||
5261 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||||
5262 | break; | ||||||||
5263 | case OMPD_target_parallel_for: | ||||||||
5264 | Res = ActOnOpenMPTargetParallelForDirective( | ||||||||
5265 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||||
5266 | AllowedNameModifiers.push_back(OMPD_target); | ||||||||
5267 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||||
5268 | break; | ||||||||
5269 | case OMPD_cancellation_point: | ||||||||
5270 | assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp cancellation point' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp cancellation point' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5271, __PRETTY_FUNCTION__)) | ||||||||
5271 | "No clauses are allowed for 'omp cancellation point' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp cancellation point' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp cancellation point' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5271, __PRETTY_FUNCTION__)); | ||||||||
5272 | assert(AStmt == nullptr && "No associated statement allowed for 'omp "((AStmt == nullptr && "No associated statement allowed for 'omp " "cancellation point' directive") ? static_cast<void> ( 0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp \" \"cancellation point' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5273, __PRETTY_FUNCTION__)) | ||||||||
5273 | "cancellation point' directive")((AStmt == nullptr && "No associated statement allowed for 'omp " "cancellation point' directive") ? static_cast<void> ( 0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp \" \"cancellation point' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5273, __PRETTY_FUNCTION__)); | ||||||||
5274 | Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); | ||||||||
5275 | break; | ||||||||
5276 | case OMPD_cancel: | ||||||||
5277 | assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp cancel' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp cancel' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5278, __PRETTY_FUNCTION__)) | ||||||||
5278 | "No associated statement allowed for 'omp cancel' directive")((AStmt == nullptr && "No associated statement allowed for 'omp cancel' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp cancel' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5278, __PRETTY_FUNCTION__)); | ||||||||
5279 | Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, | ||||||||
5280 | CancelRegion); | ||||||||
5281 | AllowedNameModifiers.push_back(OMPD_cancel); | ||||||||
5282 | break; | ||||||||
5283 | case OMPD_target_data: | ||||||||
5284 | Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||||
5285 | EndLoc); | ||||||||
5286 | AllowedNameModifiers.push_back(OMPD_target_data); | ||||||||
5287 | break; | ||||||||
5288 | case OMPD_target_enter_data: | ||||||||
5289 | Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, | ||||||||
5290 | EndLoc, AStmt); | ||||||||
5291 | AllowedNameModifiers.push_back(OMPD_target_enter_data); | ||||||||
5292 | break; | ||||||||
5293 | case OMPD_target_exit_data: | ||||||||
5294 | Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, | ||||||||
5295 | EndLoc, AStmt); | ||||||||
5296 | AllowedNameModifiers.push_back(OMPD_target_exit_data); | ||||||||
5297 | break; | ||||||||
5298 | case OMPD_taskloop: | ||||||||
5299 | Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||||
5300 | EndLoc, VarsWithInheritedDSA); | ||||||||
5301 | AllowedNameModifiers.push_back(OMPD_taskloop); | ||||||||
5302 | break; | ||||||||
5303 | case OMPD_taskloop_simd: | ||||||||
5304 | Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||||
5305 | EndLoc, VarsWithInheritedDSA); | ||||||||
5306 | AllowedNameModifiers.push_back(OMPD_taskloop); | ||||||||
5307 | if (LangOpts.OpenMP >= 50) | ||||||||
5308 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||||
5309 | break; | ||||||||
5310 | case OMPD_master_taskloop: | ||||||||
5311 | Res = ActOnOpenMPMasterTaskLoopDirective( | ||||||||
5312 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||||
5313 | AllowedNameModifiers.push_back(OMPD_taskloop); | ||||||||
5314 | break; | ||||||||
5315 | case OMPD_master_taskloop_simd: | ||||||||
5316 | Res = ActOnOpenMPMasterTaskLoopSimdDirective( | ||||||||
5317 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||||
5318 | AllowedNameModifiers.push_back(OMPD_taskloop); | ||||||||
5319 | if (LangOpts.OpenMP >= 50) | ||||||||
5320 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||||
5321 | break; | ||||||||
5322 | case OMPD_parallel_master_taskloop: | ||||||||
5323 | Res = ActOnOpenMPParallelMasterTaskLoopDirective( | ||||||||
5324 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||||
5325 | AllowedNameModifiers.push_back(OMPD_taskloop); | ||||||||
5326 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||||
5327 | break; | ||||||||
5328 | case OMPD_parallel_master_taskloop_simd: | ||||||||
5329 | Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( | ||||||||
5330 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||||
5331 | AllowedNameModifiers.push_back(OMPD_taskloop); | ||||||||
5332 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||||
5333 | if (LangOpts.OpenMP >= 50) | ||||||||
5334 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||||
5335 | break; | ||||||||
5336 | case OMPD_distribute: | ||||||||
5337 | Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||||
5338 | EndLoc, VarsWithInheritedDSA); | ||||||||
5339 | break; | ||||||||
5340 | case OMPD_target_update: | ||||||||
5341 | Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, | ||||||||
5342 | EndLoc, AStmt); | ||||||||
5343 | AllowedNameModifiers.push_back(OMPD_target_update); | ||||||||
5344 | break; | ||||||||
5345 | case OMPD_distribute_parallel_for: | ||||||||
5346 | Res = ActOnOpenMPDistributeParallelForDirective( | ||||||||
5347 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||||
5348 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||||
5349 | break; | ||||||||
5350 | case OMPD_distribute_parallel_for_simd: | ||||||||
5351 | Res = ActOnOpenMPDistributeParallelForSimdDirective( | ||||||||
5352 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||||
5353 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||||
5354 | if (LangOpts.OpenMP >= 50) | ||||||||
5355 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||||
5356 | break; | ||||||||
5357 | case OMPD_distribute_simd: | ||||||||
5358 | Res = ActOnOpenMPDistributeSimdDirective( | ||||||||
5359 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||||
5360 | if (LangOpts.OpenMP >= 50) | ||||||||
5361 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||||
5362 | break; | ||||||||
5363 | case OMPD_target_parallel_for_simd: | ||||||||
5364 | Res = ActOnOpenMPTargetParallelForSimdDirective( | ||||||||
5365 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||||
5366 | AllowedNameModifiers.push_back(OMPD_target); | ||||||||
5367 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||||
5368 | if (LangOpts.OpenMP >= 50) | ||||||||
5369 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||||
5370 | break; | ||||||||
5371 | case OMPD_target_simd: | ||||||||
5372 | Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||||
5373 | EndLoc, VarsWithInheritedDSA); | ||||||||
5374 | AllowedNameModifiers.push_back(OMPD_target); | ||||||||
5375 | if (LangOpts.OpenMP >= 50) | ||||||||
5376 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||||
5377 | break; | ||||||||
5378 | case OMPD_teams_distribute: | ||||||||
5379 | Res = ActOnOpenMPTeamsDistributeDirective( | ||||||||
5380 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||||
5381 | break; | ||||||||
5382 | case OMPD_teams_distribute_simd: | ||||||||
5383 | Res = ActOnOpenMPTeamsDistributeSimdDirective( | ||||||||
5384 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||||
5385 | if (LangOpts.OpenMP >= 50) | ||||||||
5386 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||||
5387 | break; | ||||||||
5388 | case OMPD_teams_distribute_parallel_for_simd: | ||||||||
5389 | Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( | ||||||||
5390 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||||
5391 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||||
5392 | if (LangOpts.OpenMP >= 50) | ||||||||
5393 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||||
5394 | break; | ||||||||
5395 | case OMPD_teams_distribute_parallel_for: | ||||||||
5396 | Res = ActOnOpenMPTeamsDistributeParallelForDirective( | ||||||||
5397 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||||
5398 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||||
5399 | break; | ||||||||
5400 | case OMPD_target_teams: | ||||||||
5401 | Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||||
5402 | EndLoc); | ||||||||
5403 | AllowedNameModifiers.push_back(OMPD_target); | ||||||||
5404 | break; | ||||||||
5405 | case OMPD_target_teams_distribute: | ||||||||
5406 | Res = ActOnOpenMPTargetTeamsDistributeDirective( | ||||||||
5407 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||||
5408 | AllowedNameModifiers.push_back(OMPD_target); | ||||||||
5409 | break; | ||||||||
5410 | case OMPD_target_teams_distribute_parallel_for: | ||||||||
5411 | Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( | ||||||||
5412 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||||
5413 | AllowedNameModifiers.push_back(OMPD_target); | ||||||||
5414 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||||
5415 | break; | ||||||||
5416 | case OMPD_target_teams_distribute_parallel_for_simd: | ||||||||
5417 | Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( | ||||||||
5418 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||||
5419 | AllowedNameModifiers.push_back(OMPD_target); | ||||||||
5420 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||||
5421 | if (LangOpts.OpenMP >= 50) | ||||||||
5422 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||||
5423 | break; | ||||||||
5424 | case OMPD_target_teams_distribute_simd: | ||||||||
5425 | Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( | ||||||||
5426 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||||
5427 | AllowedNameModifiers.push_back(OMPD_target); | ||||||||
5428 | if (LangOpts.OpenMP >= 50) | ||||||||
5429 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||||
5430 | break; | ||||||||
5431 | case OMPD_declare_target: | ||||||||
5432 | case OMPD_end_declare_target: | ||||||||
5433 | case OMPD_threadprivate: | ||||||||
5434 | case OMPD_allocate: | ||||||||
5435 | case OMPD_declare_reduction: | ||||||||
5436 | case OMPD_declare_mapper: | ||||||||
5437 | case OMPD_declare_simd: | ||||||||
5438 | case OMPD_requires: | ||||||||
5439 | case OMPD_declare_variant: | ||||||||
5440 | case OMPD_begin_declare_variant: | ||||||||
5441 | case OMPD_end_declare_variant: | ||||||||
5442 | llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5442); | ||||||||
5443 | case OMPD_unknown: | ||||||||
5444 | default: | ||||||||
5445 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5445); | ||||||||
5446 | } | ||||||||
5447 | |||||||||
5448 | ErrorFound = Res.isInvalid() || ErrorFound; | ||||||||
5449 | |||||||||
5450 | // Check variables in the clauses if default(none) or | ||||||||
5451 | // default(firstprivate) was specified. | ||||||||
5452 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() == DSA_none || | ||||||||
5453 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() == DSA_firstprivate) { | ||||||||
5454 | DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), *this, nullptr); | ||||||||
5455 | for (OMPClause *C : Clauses) { | ||||||||
5456 | switch (C->getClauseKind()) { | ||||||||
5457 | case OMPC_num_threads: | ||||||||
5458 | case OMPC_dist_schedule: | ||||||||
5459 | // Do not analyse if no parent teams directive. | ||||||||
5460 | if (isOpenMPTeamsDirective(Kind)) | ||||||||
5461 | break; | ||||||||
5462 | continue; | ||||||||
5463 | case OMPC_if: | ||||||||
5464 | if (isOpenMPTeamsDirective(Kind) && | ||||||||
5465 | cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) | ||||||||
5466 | break; | ||||||||
5467 | if (isOpenMPParallelDirective(Kind) && | ||||||||
5468 | isOpenMPTaskLoopDirective(Kind) && | ||||||||
5469 | cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) | ||||||||
5470 | break; | ||||||||
5471 | continue; | ||||||||
5472 | case OMPC_schedule: | ||||||||
5473 | case OMPC_detach: | ||||||||
5474 | break; | ||||||||
5475 | case OMPC_grainsize: | ||||||||
5476 | case OMPC_num_tasks: | ||||||||
5477 | case OMPC_final: | ||||||||
5478 | case OMPC_priority: | ||||||||
5479 | // Do not analyze if no parent parallel directive. | ||||||||
5480 | if (isOpenMPParallelDirective(Kind)) | ||||||||
5481 | break; | ||||||||
5482 | continue; | ||||||||
5483 | case OMPC_ordered: | ||||||||
5484 | case OMPC_device: | ||||||||
5485 | case OMPC_num_teams: | ||||||||
5486 | case OMPC_thread_limit: | ||||||||
5487 | case OMPC_hint: | ||||||||
5488 | case OMPC_collapse: | ||||||||
5489 | case OMPC_safelen: | ||||||||
5490 | case OMPC_simdlen: | ||||||||
5491 | case OMPC_default: | ||||||||
5492 | case OMPC_proc_bind: | ||||||||
5493 | case OMPC_private: | ||||||||
5494 | case OMPC_firstprivate: | ||||||||
5495 | case OMPC_lastprivate: | ||||||||
5496 | case OMPC_shared: | ||||||||
5497 | case OMPC_reduction: | ||||||||
5498 | case OMPC_task_reduction: | ||||||||
5499 | case OMPC_in_reduction: | ||||||||
5500 | case OMPC_linear: | ||||||||
5501 | case OMPC_aligned: | ||||||||
5502 | case OMPC_copyin: | ||||||||
5503 | case OMPC_copyprivate: | ||||||||
5504 | case OMPC_nowait: | ||||||||
5505 | case OMPC_untied: | ||||||||
5506 | case OMPC_mergeable: | ||||||||
5507 | case OMPC_allocate: | ||||||||
5508 | case OMPC_read: | ||||||||
5509 | case OMPC_write: | ||||||||
5510 | case OMPC_update: | ||||||||
5511 | case OMPC_capture: | ||||||||
5512 | case OMPC_seq_cst: | ||||||||
5513 | case OMPC_acq_rel: | ||||||||
5514 | case OMPC_acquire: | ||||||||
5515 | case OMPC_release: | ||||||||
5516 | case OMPC_relaxed: | ||||||||
5517 | case OMPC_depend: | ||||||||
5518 | case OMPC_threads: | ||||||||
5519 | case OMPC_simd: | ||||||||
5520 | case OMPC_map: | ||||||||
5521 | case OMPC_nogroup: | ||||||||
5522 | case OMPC_defaultmap: | ||||||||
5523 | case OMPC_to: | ||||||||
5524 | case OMPC_from: | ||||||||
5525 | case OMPC_use_device_ptr: | ||||||||
5526 | case OMPC_use_device_addr: | ||||||||
5527 | case OMPC_is_device_ptr: | ||||||||
5528 | case OMPC_nontemporal: | ||||||||
5529 | case OMPC_order: | ||||||||
5530 | case OMPC_destroy: | ||||||||
5531 | case OMPC_inclusive: | ||||||||
5532 | case OMPC_exclusive: | ||||||||
5533 | case OMPC_uses_allocators: | ||||||||
5534 | case OMPC_affinity: | ||||||||
5535 | continue; | ||||||||
5536 | case OMPC_allocator: | ||||||||
5537 | case OMPC_flush: | ||||||||
5538 | case OMPC_depobj: | ||||||||
5539 | case OMPC_threadprivate: | ||||||||
5540 | case OMPC_uniform: | ||||||||
5541 | case OMPC_unknown: | ||||||||
5542 | case OMPC_unified_address: | ||||||||
5543 | case OMPC_unified_shared_memory: | ||||||||
5544 | case OMPC_reverse_offload: | ||||||||
5545 | case OMPC_dynamic_allocators: | ||||||||
5546 | case OMPC_atomic_default_mem_order: | ||||||||
5547 | case OMPC_device_type: | ||||||||
5548 | case OMPC_match: | ||||||||
5549 | default: | ||||||||
5550 | llvm_unreachable("Unexpected clause")::llvm::llvm_unreachable_internal("Unexpected clause", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5550); | ||||||||
5551 | } | ||||||||
5552 | for (Stmt *CC : C->children()) { | ||||||||
5553 | if (CC) | ||||||||
5554 | DSAChecker.Visit(CC); | ||||||||
5555 | } | ||||||||
5556 | } | ||||||||
5557 | for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) | ||||||||
5558 | VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); | ||||||||
5559 | } | ||||||||
5560 | for (const auto &P : VarsWithInheritedDSA) { | ||||||||
5561 | if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) | ||||||||
5562 | continue; | ||||||||
5563 | ErrorFound = true; | ||||||||
5564 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() == DSA_none || | ||||||||
5565 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() == DSA_firstprivate) { | ||||||||
5566 | Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) | ||||||||
5567 | << P.first << P.second->getSourceRange(); | ||||||||
5568 | Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSALocation(), diag::note_omp_default_dsa_none); | ||||||||
5569 | } else if (getLangOpts().OpenMP >= 50) { | ||||||||
5570 | Diag(P.second->getExprLoc(), | ||||||||
5571 | diag::err_omp_defaultmap_no_attr_for_variable) | ||||||||
5572 | << P.first << P.second->getSourceRange(); | ||||||||
5573 | Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSALocation(), | ||||||||
5574 | diag::note_omp_defaultmap_attr_none); | ||||||||
5575 | } | ||||||||
5576 | } | ||||||||
5577 | |||||||||
5578 | if (!AllowedNameModifiers.empty()) | ||||||||
5579 | ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || | ||||||||
5580 | ErrorFound; | ||||||||
5581 | |||||||||
5582 | if (ErrorFound) | ||||||||
5583 | return StmtError(); | ||||||||
5584 | |||||||||
5585 | if (!CurContext->isDependentContext() && | ||||||||
5586 | isOpenMPTargetExecutionDirective(Kind) && | ||||||||
5587 | !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || | ||||||||
5588 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || | ||||||||
5589 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || | ||||||||
5590 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { | ||||||||
5591 | // Register target to DSA Stack. | ||||||||
5592 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addTargetDirLocation(StartLoc); | ||||||||
5593 | } | ||||||||
5594 | |||||||||
5595 | return Res; | ||||||||
5596 | } | ||||||||
5597 | |||||||||
5598 | Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( | ||||||||
5599 | DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, | ||||||||
5600 | ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, | ||||||||
5601 | ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, | ||||||||
5602 | ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { | ||||||||
5603 | assert(Aligneds.size() == Alignments.size())((Aligneds.size() == Alignments.size()) ? static_cast<void > (0) : __assert_fail ("Aligneds.size() == Alignments.size()" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5603, __PRETTY_FUNCTION__)); | ||||||||
5604 | assert(Linears.size() == LinModifiers.size())((Linears.size() == LinModifiers.size()) ? static_cast<void > (0) : __assert_fail ("Linears.size() == LinModifiers.size()" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5604, __PRETTY_FUNCTION__)); | ||||||||
5605 | assert(Linears.size() == Steps.size())((Linears.size() == Steps.size()) ? static_cast<void> ( 0) : __assert_fail ("Linears.size() == Steps.size()", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5605, __PRETTY_FUNCTION__)); | ||||||||
5606 | if (!DG || DG.get().isNull()) | ||||||||
5607 | return DeclGroupPtrTy(); | ||||||||
5608 | |||||||||
5609 | const int SimdId = 0; | ||||||||
5610 | if (!DG.get().isSingleDecl()) { | ||||||||
5611 | Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) | ||||||||
5612 | << SimdId; | ||||||||
5613 | return DG; | ||||||||
5614 | } | ||||||||
5615 | Decl *ADecl = DG.get().getSingleDecl(); | ||||||||
5616 | if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) | ||||||||
5617 | ADecl = FTD->getTemplatedDecl(); | ||||||||
5618 | |||||||||
5619 | auto *FD = dyn_cast<FunctionDecl>(ADecl); | ||||||||
5620 | if (!FD) { | ||||||||
5621 | Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; | ||||||||
5622 | return DeclGroupPtrTy(); | ||||||||
5623 | } | ||||||||
5624 | |||||||||
5625 | // OpenMP [2.8.2, declare simd construct, Description] | ||||||||
5626 | // The parameter of the simdlen clause must be a constant positive integer | ||||||||
5627 | // expression. | ||||||||
5628 | ExprResult SL; | ||||||||
5629 | if (Simdlen) | ||||||||
5630 | SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); | ||||||||
5631 | // OpenMP [2.8.2, declare simd construct, Description] | ||||||||
5632 | // The special this pointer can be used as if was one of the arguments to the | ||||||||
5633 | // function in any of the linear, aligned, or uniform clauses. | ||||||||
5634 | // The uniform clause declares one or more arguments to have an invariant | ||||||||
5635 | // value for all concurrent invocations of the function in the execution of a | ||||||||
5636 | // single SIMD loop. | ||||||||
5637 | llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; | ||||||||
5638 | const Expr *UniformedLinearThis = nullptr; | ||||||||
5639 | for (const Expr *E : Uniforms) { | ||||||||
5640 | E = E->IgnoreParenImpCasts(); | ||||||||
5641 | if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) | ||||||||
5642 | if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) | ||||||||
5643 | if (FD->getNumParams() > PVD->getFunctionScopeIndex() && | ||||||||
5644 | FD->getParamDecl(PVD->getFunctionScopeIndex()) | ||||||||
5645 | ->getCanonicalDecl() == PVD->getCanonicalDecl()) { | ||||||||
5646 | UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); | ||||||||
5647 | continue; | ||||||||
5648 | } | ||||||||
5649 | if (isa<CXXThisExpr>(E)) { | ||||||||
5650 | UniformedLinearThis = E; | ||||||||
5651 | continue; | ||||||||
5652 | } | ||||||||
5653 | Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) | ||||||||
5654 | << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); | ||||||||
5655 | } | ||||||||
5656 | // OpenMP [2.8.2, declare simd construct, Description] | ||||||||
5657 | // The aligned clause declares that the object to which each list item points | ||||||||
5658 | // is aligned to the number of bytes expressed in the optional parameter of | ||||||||
5659 | // the aligned clause. | ||||||||
5660 | // The special this pointer can be used as if was one of the arguments to the | ||||||||
5661 | // function in any of the linear, aligned, or uniform clauses. | ||||||||
5662 | // The type of list items appearing in the aligned clause must be array, | ||||||||
5663 | // pointer, reference to array, or reference to pointer. | ||||||||
5664 | llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; | ||||||||
5665 | const Expr *AlignedThis = nullptr; | ||||||||
5666 | for (const Expr *E : Aligneds) { | ||||||||
5667 | E = E->IgnoreParenImpCasts(); | ||||||||
5668 | if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) | ||||||||
5669 | if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { | ||||||||
5670 | const VarDecl *CanonPVD = PVD->getCanonicalDecl(); | ||||||||
5671 | if (FD->getNumParams() > PVD->getFunctionScopeIndex() && | ||||||||
5672 | FD->getParamDecl(PVD->getFunctionScopeIndex()) | ||||||||
5673 | ->getCanonicalDecl() == CanonPVD) { | ||||||||
5674 | // OpenMP [2.8.1, simd construct, Restrictions] | ||||||||
5675 | // A list-item cannot appear in more than one aligned clause. | ||||||||
5676 | if (AlignedArgs.count(CanonPVD) > 0) { | ||||||||
5677 | Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) | ||||||||
5678 | << 1 << getOpenMPClauseName(OMPC_aligned) | ||||||||
5679 | << E->getSourceRange(); | ||||||||
5680 | Diag(AlignedArgs[CanonPVD]->getExprLoc(), | ||||||||
5681 | diag::note_omp_explicit_dsa) | ||||||||
5682 | << getOpenMPClauseName(OMPC_aligned); | ||||||||
5683 | continue; | ||||||||
5684 | } | ||||||||
5685 | AlignedArgs[CanonPVD] = E; | ||||||||
5686 | QualType QTy = PVD->getType() | ||||||||
5687 | .getNonReferenceType() | ||||||||
5688 | .getUnqualifiedType() | ||||||||
5689 | .getCanonicalType(); | ||||||||
5690 | const Type *Ty = QTy.getTypePtrOrNull(); | ||||||||
5691 | if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { | ||||||||
5692 | Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) | ||||||||
5693 | << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); | ||||||||
5694 | Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; | ||||||||
5695 | } | ||||||||
5696 | continue; | ||||||||
5697 | } | ||||||||
5698 | } | ||||||||
5699 | if (isa<CXXThisExpr>(E)) { | ||||||||
5700 | if (AlignedThis) { | ||||||||
5701 | Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) | ||||||||
5702 | << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); | ||||||||
5703 | Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) | ||||||||
5704 | << getOpenMPClauseName(OMPC_aligned); | ||||||||
5705 | } | ||||||||
5706 | AlignedThis = E; | ||||||||
5707 | continue; | ||||||||
5708 | } | ||||||||
5709 | Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) | ||||||||
5710 | << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); | ||||||||
5711 | } | ||||||||
5712 | // The optional parameter of the aligned clause, alignment, must be a constant | ||||||||
5713 | // positive integer expression. If no optional parameter is specified, | ||||||||
5714 | // implementation-defined default alignments for SIMD instructions on the | ||||||||
5715 | // target platforms are assumed. | ||||||||
5716 | SmallVector<const Expr *, 4> NewAligns; | ||||||||
5717 | for (Expr *E : Alignments) { | ||||||||
5718 | ExprResult Align; | ||||||||
5719 | if (E) | ||||||||
5720 | Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); | ||||||||
5721 | NewAligns.push_back(Align.get()); | ||||||||
5722 | } | ||||||||
5723 | // OpenMP [2.8.2, declare simd construct, Description] | ||||||||
5724 | // The linear clause declares one or more list items to be private to a SIMD | ||||||||
5725 | // lane and to have a linear relationship with respect to the iteration space | ||||||||
5726 | // of a loop. | ||||||||
5727 | // The special this pointer can be used as if was one of the arguments to the | ||||||||
5728 | // function in any of the linear, aligned, or uniform clauses. | ||||||||
5729 | // When a linear-step expression is specified in a linear clause it must be | ||||||||
5730 | // either a constant integer expression or an integer-typed parameter that is | ||||||||
5731 | // specified in a uniform clause on the directive. | ||||||||
5732 | llvm::DenseMap<const Decl *, const Expr *> LinearArgs; | ||||||||
5733 | const bool IsUniformedThis = UniformedLinearThis != nullptr; | ||||||||
5734 | auto MI = LinModifiers.begin(); | ||||||||
5735 | for (const Expr *E : Linears) { | ||||||||
5736 | auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); | ||||||||
5737 | ++MI; | ||||||||
5738 | E = E->IgnoreParenImpCasts(); | ||||||||
5739 | if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) | ||||||||
5740 | if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { | ||||||||
5741 | const VarDecl *CanonPVD = PVD->getCanonicalDecl(); | ||||||||
5742 | if (FD->getNumParams() > PVD->getFunctionScopeIndex() && | ||||||||
5743 | FD->getParamDecl(PVD->getFunctionScopeIndex()) | ||||||||
5744 | ->getCanonicalDecl() == CanonPVD) { | ||||||||
5745 | // OpenMP [2.15.3.7, linear Clause, Restrictions] | ||||||||
5746 | // A list-item cannot appear in more than one linear clause. | ||||||||
5747 | if (LinearArgs.count(CanonPVD) > 0) { | ||||||||
5748 | Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) | ||||||||
5749 | << getOpenMPClauseName(OMPC_linear) | ||||||||
5750 | << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); | ||||||||
5751 | Diag(LinearArgs[CanonPVD]->getExprLoc(), | ||||||||
5752 | diag::note_omp_explicit_dsa) | ||||||||
5753 | << getOpenMPClauseName(OMPC_linear); | ||||||||
5754 | continue; | ||||||||
5755 | } | ||||||||
5756 | // Each argument can appear in at most one uniform or linear clause. | ||||||||
5757 | if (UniformedArgs.count(CanonPVD) > 0) { | ||||||||
5758 | Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) | ||||||||
5759 | << getOpenMPClauseName(OMPC_linear) | ||||||||
5760 | << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); | ||||||||
5761 | Diag(UniformedArgs[CanonPVD]->getExprLoc(), | ||||||||
5762 | diag::note_omp_explicit_dsa) | ||||||||
5763 | << getOpenMPClauseName(OMPC_uniform); | ||||||||
5764 | continue; | ||||||||
5765 | } | ||||||||
5766 | LinearArgs[CanonPVD] = E; | ||||||||
5767 | if (E->isValueDependent() || E->isTypeDependent() || | ||||||||
5768 | E->isInstantiationDependent() || | ||||||||
5769 | E->containsUnexpandedParameterPack()) | ||||||||
5770 | continue; | ||||||||
5771 | (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, | ||||||||
5772 | PVD->getOriginalType(), | ||||||||
5773 | /*IsDeclareSimd=*/true); | ||||||||
5774 | continue; | ||||||||
5775 | } | ||||||||
5776 | } | ||||||||
5777 | if (isa<CXXThisExpr>(E)) { | ||||||||
5778 | if (UniformedLinearThis) { | ||||||||
5779 | Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) | ||||||||
5780 | << getOpenMPClauseName(OMPC_linear) | ||||||||
5781 | << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) | ||||||||
5782 | << E->getSourceRange(); | ||||||||
5783 | Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) | ||||||||
5784 | << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform | ||||||||
5785 | : OMPC_linear); | ||||||||
5786 | continue; | ||||||||
5787 | } | ||||||||
5788 | UniformedLinearThis = E; | ||||||||
5789 | if (E->isValueDependent() || E->isTypeDependent() || | ||||||||
5790 | E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) | ||||||||
5791 | continue; | ||||||||
5792 | (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, | ||||||||
5793 | E->getType(), /*IsDeclareSimd=*/true); | ||||||||
5794 | continue; | ||||||||
5795 | } | ||||||||
5796 | Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) | ||||||||
5797 | << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); | ||||||||
5798 | } | ||||||||
5799 | Expr *Step = nullptr; | ||||||||
5800 | Expr *NewStep = nullptr; | ||||||||
5801 | SmallVector<Expr *, 4> NewSteps; | ||||||||
5802 | for (Expr *E : Steps) { | ||||||||
5803 | // Skip the same step expression, it was checked already. | ||||||||
5804 | if (Step == E || !E) { | ||||||||
5805 | NewSteps.push_back(E ? NewStep : nullptr); | ||||||||
5806 | continue; | ||||||||
5807 | } | ||||||||
5808 | Step = E; | ||||||||
5809 | if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) | ||||||||
5810 | if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { | ||||||||
5811 | const VarDecl *CanonPVD = PVD->getCanonicalDecl(); | ||||||||
5812 | if (UniformedArgs.count(CanonPVD) == 0) { | ||||||||
5813 | Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) | ||||||||
5814 | << Step->getSourceRange(); | ||||||||
5815 | } else if (E->isValueDependent() || E->isTypeDependent() || | ||||||||
5816 | E->isInstantiationDependent() || | ||||||||
5817 | E->containsUnexpandedParameterPack() || | ||||||||
5818 | CanonPVD->getType()->hasIntegerRepresentation()) { | ||||||||
5819 | NewSteps.push_back(Step); | ||||||||
5820 | } else { | ||||||||
5821 | Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) | ||||||||
5822 | << Step->getSourceRange(); | ||||||||
5823 | } | ||||||||
5824 | continue; | ||||||||
5825 | } | ||||||||
5826 | NewStep = Step; | ||||||||
5827 | if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && | ||||||||
5828 | !Step->isInstantiationDependent() && | ||||||||
5829 | !Step->containsUnexpandedParameterPack()) { | ||||||||
5830 | NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) | ||||||||
5831 | .get(); | ||||||||
5832 | if (NewStep) | ||||||||
5833 | NewStep = VerifyIntegerConstantExpression(NewStep).get(); | ||||||||
5834 | } | ||||||||
5835 | NewSteps.push_back(NewStep); | ||||||||
5836 | } | ||||||||
5837 | auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( | ||||||||
5838 | Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), | ||||||||
5839 | Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), | ||||||||
5840 | const_cast<Expr **>(NewAligns.data()), NewAligns.size(), | ||||||||
5841 | const_cast<Expr **>(Linears.data()), Linears.size(), | ||||||||
5842 | const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), | ||||||||
5843 | NewSteps.data(), NewSteps.size(), SR); | ||||||||
5844 | ADecl->addAttr(NewAttr); | ||||||||
5845 | return DG; | ||||||||
5846 | } | ||||||||
5847 | |||||||||
5848 | static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, | ||||||||
5849 | QualType NewType) { | ||||||||
5850 | assert(NewType->isFunctionProtoType() &&((NewType->isFunctionProtoType() && "Expected function type with prototype." ) ? static_cast<void> (0) : __assert_fail ("NewType->isFunctionProtoType() && \"Expected function type with prototype.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5851, __PRETTY_FUNCTION__)) | ||||||||
5851 | "Expected function type with prototype.")((NewType->isFunctionProtoType() && "Expected function type with prototype." ) ? static_cast<void> (0) : __assert_fail ("NewType->isFunctionProtoType() && \"Expected function type with prototype.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5851, __PRETTY_FUNCTION__)); | ||||||||
5852 | assert(FD->getType()->isFunctionNoProtoType() &&((FD->getType()->isFunctionNoProtoType() && "Expected function with type with no prototype." ) ? static_cast<void> (0) : __assert_fail ("FD->getType()->isFunctionNoProtoType() && \"Expected function with type with no prototype.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5853, __PRETTY_FUNCTION__)) | ||||||||
5853 | "Expected function with type with no prototype.")((FD->getType()->isFunctionNoProtoType() && "Expected function with type with no prototype." ) ? static_cast<void> (0) : __assert_fail ("FD->getType()->isFunctionNoProtoType() && \"Expected function with type with no prototype.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5853, __PRETTY_FUNCTION__)); | ||||||||
5854 | assert(FDWithProto->getType()->isFunctionProtoType() &&((FDWithProto->getType()->isFunctionProtoType() && "Expected function with prototype.") ? static_cast<void> (0) : __assert_fail ("FDWithProto->getType()->isFunctionProtoType() && \"Expected function with prototype.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5855, __PRETTY_FUNCTION__)) | ||||||||
5855 | "Expected function with prototype.")((FDWithProto->getType()->isFunctionProtoType() && "Expected function with prototype.") ? static_cast<void> (0) : __assert_fail ("FDWithProto->getType()->isFunctionProtoType() && \"Expected function with prototype.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 5855, __PRETTY_FUNCTION__)); | ||||||||
5856 | // Synthesize parameters with the same types. | ||||||||
5857 | FD->setType(NewType); | ||||||||
5858 | SmallVector<ParmVarDecl *, 16> Params; | ||||||||
5859 | for (const ParmVarDecl *P : FDWithProto->parameters()) { | ||||||||
5860 | auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), | ||||||||
5861 | SourceLocation(), nullptr, P->getType(), | ||||||||
5862 | /*TInfo=*/nullptr, SC_None, nullptr); | ||||||||
5863 | Param->setScopeInfo(0, Params.size()); | ||||||||
5864 | Param->setImplicit(); | ||||||||
5865 | Params.push_back(Param); | ||||||||
5866 | } | ||||||||
5867 | |||||||||
5868 | FD->setParams(Params); | ||||||||
5869 | } | ||||||||
5870 | |||||||||
5871 | Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI) | ||||||||
5872 | : TI(&TI), NameSuffix(TI.getMangledName()) {} | ||||||||
5873 | |||||||||
5874 | FunctionDecl * | ||||||||
5875 | Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S, | ||||||||
5876 | Declarator &D) { | ||||||||
5877 | IdentifierInfo *BaseII = D.getIdentifier(); | ||||||||
5878 | LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(), | ||||||||
5879 | LookupOrdinaryName); | ||||||||
5880 | LookupParsedName(Lookup, S, &D.getCXXScopeSpec()); | ||||||||
5881 | |||||||||
5882 | TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); | ||||||||
5883 | QualType FType = TInfo->getType(); | ||||||||
5884 | |||||||||
5885 | bool IsConstexpr = D.getDeclSpec().getConstexprSpecifier() == CSK_constexpr; | ||||||||
5886 | bool IsConsteval = D.getDeclSpec().getConstexprSpecifier() == CSK_consteval; | ||||||||
5887 | |||||||||
5888 | FunctionDecl *BaseFD = nullptr; | ||||||||
5889 | for (auto *Candidate : Lookup) { | ||||||||
5890 | auto *UDecl = dyn_cast<FunctionDecl>(Candidate->getUnderlyingDecl()); | ||||||||
5891 | if (!UDecl) | ||||||||
5892 | continue; | ||||||||
5893 | |||||||||
5894 | // Don't specialize constexpr/consteval functions with | ||||||||
5895 | // non-constexpr/consteval functions. | ||||||||
5896 | if (UDecl->isConstexpr() && !IsConstexpr) | ||||||||
5897 | continue; | ||||||||
5898 | if (UDecl->isConsteval() && !IsConsteval) | ||||||||
5899 | continue; | ||||||||
5900 | |||||||||
5901 | QualType NewType = Context.mergeFunctionTypes( | ||||||||
5902 | FType, UDecl->getType(), /* OfBlockPointer */ false, | ||||||||
5903 | /* Unqualified */ false, /* AllowCXX */ true); | ||||||||
5904 | if (NewType.isNull()) | ||||||||
5905 | continue; | ||||||||
5906 | |||||||||
5907 | // Found a base! | ||||||||
5908 | BaseFD = UDecl; | ||||||||
5909 | break; | ||||||||
5910 | } | ||||||||
5911 | if (!BaseFD) { | ||||||||
5912 | BaseFD = cast<FunctionDecl>(ActOnDeclarator(S, D)); | ||||||||
5913 | BaseFD->setImplicit(true); | ||||||||
5914 | } | ||||||||
5915 | |||||||||
5916 | OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); | ||||||||
5917 | std::string MangledName; | ||||||||
5918 | MangledName += D.getIdentifier()->getName(); | ||||||||
5919 | MangledName += getOpenMPVariantManglingSeparatorStr(); | ||||||||
5920 | MangledName += DVScope.NameSuffix; | ||||||||
5921 | IdentifierInfo &VariantII = Context.Idents.get(MangledName); | ||||||||
5922 | |||||||||
5923 | VariantII.setMangledOpenMPVariantName(true); | ||||||||
5924 | D.SetIdentifier(&VariantII, D.getBeginLoc()); | ||||||||
5925 | return BaseFD; | ||||||||
5926 | } | ||||||||
5927 | |||||||||
5928 | void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( | ||||||||
5929 | FunctionDecl *FD, FunctionDecl *BaseFD) { | ||||||||
5930 | // Do not mark function as is used to prevent its emission if this is the | ||||||||
5931 | // only place where it is used. | ||||||||
5932 | EnterExpressionEvaluationContext Unevaluated( | ||||||||
5933 | *this, Sema::ExpressionEvaluationContext::Unevaluated); | ||||||||
5934 | |||||||||
5935 | Expr *VariantFuncRef = DeclRefExpr::Create( | ||||||||
5936 | Context, NestedNameSpecifierLoc(), SourceLocation(), FD, | ||||||||
5937 | /* RefersToEnclosingVariableOrCapture */ false, | ||||||||
5938 | /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue); | ||||||||
5939 | |||||||||
5940 | OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); | ||||||||
5941 | auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit( | ||||||||
5942 | Context, VariantFuncRef, DVScope.TI); | ||||||||
5943 | BaseFD->addAttr(OMPDeclareVariantA); | ||||||||
5944 | } | ||||||||
5945 | |||||||||
5946 | ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope, | ||||||||
5947 | SourceLocation LParenLoc, | ||||||||
5948 | MultiExprArg ArgExprs, | ||||||||
5949 | SourceLocation RParenLoc, Expr *ExecConfig) { | ||||||||
5950 | // The common case is a regular call we do not want to specialize at all. Try | ||||||||
5951 | // to make that case fast by bailing early. | ||||||||
5952 | CallExpr *CE = dyn_cast<CallExpr>(Call.get()); | ||||||||
5953 | if (!CE) | ||||||||
5954 | return Call; | ||||||||
5955 | |||||||||
5956 | FunctionDecl *CalleeFnDecl = CE->getDirectCallee(); | ||||||||
5957 | if (!CalleeFnDecl) | ||||||||
5958 | return Call; | ||||||||
5959 | |||||||||
5960 | if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>()) | ||||||||
5961 | return Call; | ||||||||
5962 | |||||||||
5963 | ASTContext &Context = getASTContext(); | ||||||||
5964 | std::function<void(StringRef)> DiagUnknownTrait = [this, | ||||||||
5965 | CE](StringRef ISATrait) { | ||||||||
5966 | // TODO Track the selector locations in a way that is accessible here to | ||||||||
5967 | // improve the diagnostic location. | ||||||||
5968 | Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait) | ||||||||
5969 | << ISATrait; | ||||||||
5970 | }; | ||||||||
5971 | TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait), | ||||||||
5972 | getCurFunctionDecl()); | ||||||||
5973 | |||||||||
5974 | SmallVector<Expr *, 4> Exprs; | ||||||||
5975 | SmallVector<VariantMatchInfo, 4> VMIs; | ||||||||
5976 | while (CalleeFnDecl) { | ||||||||
5977 | for (OMPDeclareVariantAttr *A : | ||||||||
5978 | CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) { | ||||||||
5979 | Expr *VariantRef = A->getVariantFuncRef(); | ||||||||
5980 | |||||||||
5981 | VariantMatchInfo VMI; | ||||||||
5982 | OMPTraitInfo &TI = A->getTraitInfo(); | ||||||||
5983 | TI.getAsVariantMatchInfo(Context, VMI); | ||||||||
5984 | if (!isVariantApplicableInContext(VMI, OMPCtx, | ||||||||
5985 | /* DeviceSetOnly */ false)) | ||||||||
5986 | continue; | ||||||||
5987 | |||||||||
5988 | VMIs.push_back(VMI); | ||||||||
5989 | Exprs.push_back(VariantRef); | ||||||||
5990 | } | ||||||||
5991 | |||||||||
5992 | CalleeFnDecl = CalleeFnDecl->getPreviousDecl(); | ||||||||
5993 | } | ||||||||
5994 | |||||||||
5995 | ExprResult NewCall; | ||||||||
5996 | do { | ||||||||
5997 | int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx); | ||||||||
5998 | if (BestIdx < 0) | ||||||||
5999 | return Call; | ||||||||
6000 | Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]); | ||||||||
6001 | Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl(); | ||||||||
6002 | |||||||||
6003 | { | ||||||||
6004 | // Try to build a (member) call expression for the current best applicable | ||||||||
6005 | // variant expression. We allow this to fail in which case we continue | ||||||||
6006 | // with the next best variant expression. The fail case is part of the | ||||||||
6007 | // implementation defined behavior in the OpenMP standard when it talks | ||||||||
6008 | // about what differences in the function prototypes: "Any differences | ||||||||
6009 | // that the specific OpenMP context requires in the prototype of the | ||||||||
6010 | // variant from the base function prototype are implementation defined." | ||||||||
6011 | // This wording is there to allow the specialized variant to have a | ||||||||
6012 | // different type than the base function. This is intended and OK but if | ||||||||
6013 | // we cannot create a call the difference is not in the "implementation | ||||||||
6014 | // defined range" we allow. | ||||||||
6015 | Sema::TentativeAnalysisScope Trap(*this); | ||||||||
6016 | |||||||||
6017 | if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) { | ||||||||
6018 | auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE); | ||||||||
6019 | BestExpr = MemberExpr::CreateImplicit( | ||||||||
6020 | Context, MemberCall->getImplicitObjectArgument(), | ||||||||
6021 | /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy, | ||||||||
6022 | MemberCall->getValueKind(), MemberCall->getObjectKind()); | ||||||||
6023 | } | ||||||||
6024 | NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, | ||||||||
6025 | ExecConfig); | ||||||||
6026 | if (NewCall.isUsable()) | ||||||||
6027 | break; | ||||||||
6028 | } | ||||||||
6029 | |||||||||
6030 | VMIs.erase(VMIs.begin() + BestIdx); | ||||||||
6031 | Exprs.erase(Exprs.begin() + BestIdx); | ||||||||
6032 | } while (!VMIs.empty()); | ||||||||
6033 | |||||||||
6034 | if (!NewCall.isUsable()) | ||||||||
6035 | return Call; | ||||||||
6036 | return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0); | ||||||||
6037 | } | ||||||||
6038 | |||||||||
6039 | Optional<std::pair<FunctionDecl *, Expr *>> | ||||||||
6040 | Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, | ||||||||
6041 | Expr *VariantRef, OMPTraitInfo &TI, | ||||||||
6042 | SourceRange SR) { | ||||||||
6043 | if (!DG || DG.get().isNull()) | ||||||||
6044 | return None; | ||||||||
6045 | |||||||||
6046 | const int VariantId = 1; | ||||||||
6047 | // Must be applied only to single decl. | ||||||||
6048 | if (!DG.get().isSingleDecl()) { | ||||||||
6049 | Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) | ||||||||
6050 | << VariantId << SR; | ||||||||
6051 | return None; | ||||||||
6052 | } | ||||||||
6053 | Decl *ADecl = DG.get().getSingleDecl(); | ||||||||
6054 | if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) | ||||||||
6055 | ADecl = FTD->getTemplatedDecl(); | ||||||||
6056 | |||||||||
6057 | // Decl must be a function. | ||||||||
6058 | auto *FD = dyn_cast<FunctionDecl>(ADecl); | ||||||||
6059 | if (!FD) { | ||||||||
6060 | Diag(ADecl->getLocation(), diag::err_omp_function_expected) | ||||||||
6061 | << VariantId << SR; | ||||||||
6062 | return None; | ||||||||
6063 | } | ||||||||
6064 | |||||||||
6065 | auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { | ||||||||
6066 | return FD->hasAttrs() && | ||||||||
6067 | (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || | ||||||||
6068 | FD->hasAttr<TargetAttr>()); | ||||||||
6069 | }; | ||||||||
6070 | // OpenMP is not compatible with CPU-specific attributes. | ||||||||
6071 | if (HasMultiVersionAttributes(FD)) { | ||||||||
6072 | Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) | ||||||||
6073 | << SR; | ||||||||
6074 | return None; | ||||||||
6075 | } | ||||||||
6076 | |||||||||
6077 | // Allow #pragma omp declare variant only if the function is not used. | ||||||||
6078 | if (FD->isUsed(false)) | ||||||||
6079 | Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) | ||||||||
6080 | << FD->getLocation(); | ||||||||
6081 | |||||||||
6082 | // Check if the function was emitted already. | ||||||||
6083 | const FunctionDecl *Definition; | ||||||||
6084 | if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && | ||||||||
6085 | (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) | ||||||||
6086 | Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) | ||||||||
6087 | << FD->getLocation(); | ||||||||
6088 | |||||||||
6089 | // The VariantRef must point to function. | ||||||||
6090 | if (!VariantRef) { | ||||||||
6091 | Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; | ||||||||
6092 | return None; | ||||||||
6093 | } | ||||||||
6094 | |||||||||
6095 | auto ShouldDelayChecks = [](Expr *&E, bool) { | ||||||||
6096 | return E && (E->isTypeDependent() || E->isValueDependent() || | ||||||||
6097 | E->containsUnexpandedParameterPack() || | ||||||||
6098 | E->isInstantiationDependent()); | ||||||||
6099 | }; | ||||||||
6100 | // Do not check templates, wait until instantiation. | ||||||||
6101 | if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) || | ||||||||
6102 | TI.anyScoreOrCondition(ShouldDelayChecks)) | ||||||||
6103 | return std::make_pair(FD, VariantRef); | ||||||||
6104 | |||||||||
6105 | // Deal with non-constant score and user condition expressions. | ||||||||
6106 | auto HandleNonConstantScoresAndConditions = [this](Expr *&E, | ||||||||
6107 | bool IsScore) -> bool { | ||||||||
6108 | if (!E || E->isIntegerConstantExpr(Context)) | ||||||||
6109 | return false; | ||||||||
6110 | |||||||||
6111 | if (IsScore) { | ||||||||
6112 | // We warn on non-constant scores and pretend they were not present. | ||||||||
6113 | Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant) | ||||||||
6114 | << E; | ||||||||
6115 | E = nullptr; | ||||||||
6116 | } else { | ||||||||
6117 | // We could replace a non-constant user condition with "false" but we | ||||||||
6118 | // will soon need to handle these anyway for the dynamic version of | ||||||||
6119 | // OpenMP context selectors. | ||||||||
6120 | Diag(E->getExprLoc(), | ||||||||
6121 | diag::err_omp_declare_variant_user_condition_not_constant) | ||||||||
6122 | << E; | ||||||||
6123 | } | ||||||||
6124 | return true; | ||||||||
6125 | }; | ||||||||
6126 | if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions)) | ||||||||
6127 | return None; | ||||||||
6128 | |||||||||
6129 | // Convert VariantRef expression to the type of the original function to | ||||||||
6130 | // resolve possible conflicts. | ||||||||
6131 | ExprResult VariantRefCast; | ||||||||
6132 | if (LangOpts.CPlusPlus) { | ||||||||
6133 | QualType FnPtrType; | ||||||||
6134 | auto *Method = dyn_cast<CXXMethodDecl>(FD); | ||||||||
6135 | if (Method && !Method->isStatic()) { | ||||||||
6136 | const Type *ClassType = | ||||||||
6137 | Context.getTypeDeclType(Method->getParent()).getTypePtr(); | ||||||||
6138 | FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); | ||||||||
6139 | ExprResult ER; | ||||||||
6140 | { | ||||||||
6141 | // Build adrr_of unary op to correctly handle type checks for member | ||||||||
6142 | // functions. | ||||||||
6143 | Sema::TentativeAnalysisScope Trap(*this); | ||||||||
6144 | ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, | ||||||||
6145 | VariantRef); | ||||||||
6146 | } | ||||||||
6147 | if (!ER.isUsable()) { | ||||||||
6148 | Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) | ||||||||
6149 | << VariantId << VariantRef->getSourceRange(); | ||||||||
6150 | return None; | ||||||||
6151 | } | ||||||||
6152 | VariantRef = ER.get(); | ||||||||
6153 | } else { | ||||||||
6154 | FnPtrType = Context.getPointerType(FD->getType()); | ||||||||
6155 | } | ||||||||
6156 | ImplicitConversionSequence ICS = | ||||||||
6157 | TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), | ||||||||
6158 | /*SuppressUserConversions=*/false, | ||||||||
6159 | AllowedExplicit::None, | ||||||||
6160 | /*InOverloadResolution=*/false, | ||||||||
6161 | /*CStyle=*/false, | ||||||||
6162 | /*AllowObjCWritebackConversion=*/false); | ||||||||
6163 | if (ICS.isFailure()) { | ||||||||
6164 | Diag(VariantRef->getExprLoc(), | ||||||||
6165 | diag::err_omp_declare_variant_incompat_types) | ||||||||
6166 | << VariantRef->getType() | ||||||||
6167 | << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) | ||||||||
6168 | << VariantRef->getSourceRange(); | ||||||||
6169 | return None; | ||||||||
6170 | } | ||||||||
6171 | VariantRefCast = PerformImplicitConversion( | ||||||||
6172 | VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); | ||||||||
6173 | if (!VariantRefCast.isUsable()) | ||||||||
6174 | return None; | ||||||||
6175 | // Drop previously built artificial addr_of unary op for member functions. | ||||||||
6176 | if (Method && !Method->isStatic()) { | ||||||||
6177 | Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); | ||||||||
6178 | if (auto *UO = dyn_cast<UnaryOperator>( | ||||||||
6179 | PossibleAddrOfVariantRef->IgnoreImplicit())) | ||||||||
6180 | VariantRefCast = UO->getSubExpr(); | ||||||||
6181 | } | ||||||||
6182 | } else { | ||||||||
6183 | VariantRefCast = VariantRef; | ||||||||
6184 | } | ||||||||
6185 | |||||||||
6186 | ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); | ||||||||
6187 | if (!ER.isUsable() || | ||||||||
6188 | !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { | ||||||||
6189 | Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) | ||||||||
6190 | << VariantId << VariantRef->getSourceRange(); | ||||||||
6191 | return None; | ||||||||
6192 | } | ||||||||
6193 | |||||||||
6194 | // The VariantRef must point to function. | ||||||||
6195 | auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); | ||||||||
6196 | if (!DRE) { | ||||||||
6197 | Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) | ||||||||
6198 | << VariantId << VariantRef->getSourceRange(); | ||||||||
6199 | return None; | ||||||||
6200 | } | ||||||||
6201 | auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); | ||||||||
6202 | if (!NewFD) { | ||||||||
6203 | Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) | ||||||||
6204 | << VariantId << VariantRef->getSourceRange(); | ||||||||
6205 | return None; | ||||||||
6206 | } | ||||||||
6207 | |||||||||
6208 | // Check if function types are compatible in C. | ||||||||
6209 | if (!LangOpts.CPlusPlus) { | ||||||||
6210 | QualType NewType = | ||||||||
6211 | Context.mergeFunctionTypes(FD->getType(), NewFD->getType()); | ||||||||
6212 | if (NewType.isNull()) { | ||||||||
6213 | Diag(VariantRef->getExprLoc(), | ||||||||
6214 | diag::err_omp_declare_variant_incompat_types) | ||||||||
6215 | << NewFD->getType() << FD->getType() << VariantRef->getSourceRange(); | ||||||||
6216 | return None; | ||||||||
6217 | } | ||||||||
6218 | if (NewType->isFunctionProtoType()) { | ||||||||
6219 | if (FD->getType()->isFunctionNoProtoType()) | ||||||||
6220 | setPrototype(*this, FD, NewFD, NewType); | ||||||||
6221 | else if (NewFD->getType()->isFunctionNoProtoType()) | ||||||||
6222 | setPrototype(*this, NewFD, FD, NewType); | ||||||||
6223 | } | ||||||||
6224 | } | ||||||||
6225 | |||||||||
6226 | // Check if variant function is not marked with declare variant directive. | ||||||||
6227 | if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { | ||||||||
6228 | Diag(VariantRef->getExprLoc(), | ||||||||
6229 | diag::warn_omp_declare_variant_marked_as_declare_variant) | ||||||||
6230 | << VariantRef->getSourceRange(); | ||||||||
6231 | SourceRange SR = | ||||||||
6232 | NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); | ||||||||
6233 | Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; | ||||||||
6234 | return None; | ||||||||
6235 | } | ||||||||
6236 | |||||||||
6237 | enum DoesntSupport { | ||||||||
6238 | VirtFuncs = 1, | ||||||||
6239 | Constructors = 3, | ||||||||
6240 | Destructors = 4, | ||||||||
6241 | DeletedFuncs = 5, | ||||||||
6242 | DefaultedFuncs = 6, | ||||||||
6243 | ConstexprFuncs = 7, | ||||||||
6244 | ConstevalFuncs = 8, | ||||||||
6245 | }; | ||||||||
6246 | if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { | ||||||||
6247 | if (CXXFD->isVirtual()) { | ||||||||
6248 | Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) | ||||||||
6249 | << VirtFuncs; | ||||||||
6250 | return None; | ||||||||
6251 | } | ||||||||
6252 | |||||||||
6253 | if (isa<CXXConstructorDecl>(FD)) { | ||||||||
6254 | Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) | ||||||||
6255 | << Constructors; | ||||||||
6256 | return None; | ||||||||
6257 | } | ||||||||
6258 | |||||||||
6259 | if (isa<CXXDestructorDecl>(FD)) { | ||||||||
6260 | Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) | ||||||||
6261 | << Destructors; | ||||||||
6262 | return None; | ||||||||
6263 | } | ||||||||
6264 | } | ||||||||
6265 | |||||||||
6266 | if (FD->isDeleted()) { | ||||||||
6267 | Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) | ||||||||
6268 | << DeletedFuncs; | ||||||||
6269 | return None; | ||||||||
6270 | } | ||||||||
6271 | |||||||||
6272 | if (FD->isDefaulted()) { | ||||||||
6273 | Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) | ||||||||
6274 | << DefaultedFuncs; | ||||||||
6275 | return None; | ||||||||
6276 | } | ||||||||
6277 | |||||||||
6278 | if (FD->isConstexpr()) { | ||||||||
6279 | Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) | ||||||||
6280 | << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); | ||||||||
6281 | return None; | ||||||||
6282 | } | ||||||||
6283 | |||||||||
6284 | // Check general compatibility. | ||||||||
6285 | if (areMultiversionVariantFunctionsCompatible( | ||||||||
6286 | FD, NewFD, PartialDiagnostic::NullDiagnostic(), | ||||||||
6287 | PartialDiagnosticAt(SourceLocation(), | ||||||||
6288 | PartialDiagnostic::NullDiagnostic()), | ||||||||
6289 | PartialDiagnosticAt( | ||||||||
6290 | VariantRef->getExprLoc(), | ||||||||
6291 | PDiag(diag::err_omp_declare_variant_doesnt_support)), | ||||||||
6292 | PartialDiagnosticAt(VariantRef->getExprLoc(), | ||||||||
6293 | PDiag(diag::err_omp_declare_variant_diff) | ||||||||
6294 | << FD->getLocation()), | ||||||||
6295 | /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, | ||||||||
6296 | /*CLinkageMayDiffer=*/true)) | ||||||||
6297 | return None; | ||||||||
6298 | return std::make_pair(FD, cast<Expr>(DRE)); | ||||||||
6299 | } | ||||||||
6300 | |||||||||
6301 | void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, | ||||||||
6302 | Expr *VariantRef, | ||||||||
6303 | OMPTraitInfo &TI, | ||||||||
6304 | SourceRange SR) { | ||||||||
6305 | auto *NewAttr = | ||||||||
6306 | OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR); | ||||||||
6307 | FD->addAttr(NewAttr); | ||||||||
6308 | } | ||||||||
6309 | |||||||||
6310 | StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, | ||||||||
6311 | Stmt *AStmt, | ||||||||
6312 | SourceLocation StartLoc, | ||||||||
6313 | SourceLocation EndLoc) { | ||||||||
6314 | if (!AStmt) | ||||||||
6315 | return StmtError(); | ||||||||
6316 | |||||||||
6317 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
6318 | // 1.2.2 OpenMP Language Terminology | ||||||||
6319 | // Structured block - An executable statement with a single entry at the | ||||||||
6320 | // top and a single exit at the bottom. | ||||||||
6321 | // The point of exit cannot be a branch out of the structured block. | ||||||||
6322 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
6323 | CS->getCapturedDecl()->setNothrow(); | ||||||||
6324 | |||||||||
6325 | setFunctionHasBranchProtectedScope(); | ||||||||
6326 | |||||||||
6327 | return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, | ||||||||
6328 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), | ||||||||
6329 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||||
6330 | } | ||||||||
6331 | |||||||||
6332 | namespace { | ||||||||
6333 | /// Iteration space of a single for loop. | ||||||||
6334 | struct LoopIterationSpace final { | ||||||||
6335 | /// True if the condition operator is the strict compare operator (<, > or | ||||||||
6336 | /// !=). | ||||||||
6337 | bool IsStrictCompare = false; | ||||||||
6338 | /// Condition of the loop. | ||||||||
6339 | Expr *PreCond = nullptr; | ||||||||
6340 | /// This expression calculates the number of iterations in the loop. | ||||||||
6341 | /// It is always possible to calculate it before starting the loop. | ||||||||
6342 | Expr *NumIterations = nullptr; | ||||||||
6343 | /// The loop counter variable. | ||||||||
6344 | Expr *CounterVar = nullptr; | ||||||||
6345 | /// Private loop counter variable. | ||||||||
6346 | Expr *PrivateCounterVar = nullptr; | ||||||||
6347 | /// This is initializer for the initial value of #CounterVar. | ||||||||
6348 | Expr *CounterInit = nullptr; | ||||||||
6349 | /// This is step for the #CounterVar used to generate its update: | ||||||||
6350 | /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. | ||||||||
6351 | Expr *CounterStep = nullptr; | ||||||||
6352 | /// Should step be subtracted? | ||||||||
6353 | bool Subtract = false; | ||||||||
6354 | /// Source range of the loop init. | ||||||||
6355 | SourceRange InitSrcRange; | ||||||||
6356 | /// Source range of the loop condition. | ||||||||
6357 | SourceRange CondSrcRange; | ||||||||
6358 | /// Source range of the loop increment. | ||||||||
6359 | SourceRange IncSrcRange; | ||||||||
6360 | /// Minimum value that can have the loop control variable. Used to support | ||||||||
6361 | /// non-rectangular loops. Applied only for LCV with the non-iterator types, | ||||||||
6362 | /// since only such variables can be used in non-loop invariant expressions. | ||||||||
6363 | Expr *MinValue = nullptr; | ||||||||
6364 | /// Maximum value that can have the loop control variable. Used to support | ||||||||
6365 | /// non-rectangular loops. Applied only for LCV with the non-iterator type, | ||||||||
6366 | /// since only such variables can be used in non-loop invariant expressions. | ||||||||
6367 | Expr *MaxValue = nullptr; | ||||||||
6368 | /// true, if the lower bound depends on the outer loop control var. | ||||||||
6369 | bool IsNonRectangularLB = false; | ||||||||
6370 | /// true, if the upper bound depends on the outer loop control var. | ||||||||
6371 | bool IsNonRectangularUB = false; | ||||||||
6372 | /// Index of the loop this loop depends on and forms non-rectangular loop | ||||||||
6373 | /// nest. | ||||||||
6374 | unsigned LoopDependentIdx = 0; | ||||||||
6375 | /// Final condition for the non-rectangular loop nest support. It is used to | ||||||||
6376 | /// check that the number of iterations for this particular counter must be | ||||||||
6377 | /// finished. | ||||||||
6378 | Expr *FinalCondition = nullptr; | ||||||||
6379 | }; | ||||||||
6380 | |||||||||
6381 | /// Helper class for checking canonical form of the OpenMP loops and | ||||||||
6382 | /// extracting iteration space of each loop in the loop nest, that will be used | ||||||||
6383 | /// for IR generation. | ||||||||
6384 | class OpenMPIterationSpaceChecker { | ||||||||
6385 | /// Reference to Sema. | ||||||||
6386 | Sema &SemaRef; | ||||||||
6387 | /// Data-sharing stack. | ||||||||
6388 | DSAStackTy &Stack; | ||||||||
6389 | /// A location for diagnostics (when there is no some better location). | ||||||||
6390 | SourceLocation DefaultLoc; | ||||||||
6391 | /// A location for diagnostics (when increment is not compatible). | ||||||||
6392 | SourceLocation ConditionLoc; | ||||||||
6393 | /// A source location for referring to loop init later. | ||||||||
6394 | SourceRange InitSrcRange; | ||||||||
6395 | /// A source location for referring to condition later. | ||||||||
6396 | SourceRange ConditionSrcRange; | ||||||||
6397 | /// A source location for referring to increment later. | ||||||||
6398 | SourceRange IncrementSrcRange; | ||||||||
6399 | /// Loop variable. | ||||||||
6400 | ValueDecl *LCDecl = nullptr; | ||||||||
6401 | /// Reference to loop variable. | ||||||||
6402 | Expr *LCRef = nullptr; | ||||||||
6403 | /// Lower bound (initializer for the var). | ||||||||
6404 | Expr *LB = nullptr; | ||||||||
6405 | /// Upper bound. | ||||||||
6406 | Expr *UB = nullptr; | ||||||||
6407 | /// Loop step (increment). | ||||||||
6408 | Expr *Step = nullptr; | ||||||||
6409 | /// This flag is true when condition is one of: | ||||||||
6410 | /// Var < UB | ||||||||
6411 | /// Var <= UB | ||||||||
6412 | /// UB > Var | ||||||||
6413 | /// UB >= Var | ||||||||
6414 | /// This will have no value when the condition is != | ||||||||
6415 | llvm::Optional<bool> TestIsLessOp; | ||||||||
6416 | /// This flag is true when condition is strict ( < or > ). | ||||||||
6417 | bool TestIsStrictOp = false; | ||||||||
6418 | /// This flag is true when step is subtracted on each iteration. | ||||||||
6419 | bool SubtractStep = false; | ||||||||
6420 | /// The outer loop counter this loop depends on (if any). | ||||||||
6421 | const ValueDecl *DepDecl = nullptr; | ||||||||
6422 | /// Contains number of loop (starts from 1) on which loop counter init | ||||||||
6423 | /// expression of this loop depends on. | ||||||||
6424 | Optional<unsigned> InitDependOnLC; | ||||||||
6425 | /// Contains number of loop (starts from 1) on which loop counter condition | ||||||||
6426 | /// expression of this loop depends on. | ||||||||
6427 | Optional<unsigned> CondDependOnLC; | ||||||||
6428 | /// Checks if the provide statement depends on the loop counter. | ||||||||
6429 | Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); | ||||||||
6430 | /// Original condition required for checking of the exit condition for | ||||||||
6431 | /// non-rectangular loop. | ||||||||
6432 | Expr *Condition = nullptr; | ||||||||
6433 | |||||||||
6434 | public: | ||||||||
6435 | OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, | ||||||||
6436 | SourceLocation DefaultLoc) | ||||||||
6437 | : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), | ||||||||
6438 | ConditionLoc(DefaultLoc) {} | ||||||||
6439 | /// Check init-expr for canonical loop form and save loop counter | ||||||||
6440 | /// variable - #Var and its initialization value - #LB. | ||||||||
6441 | bool checkAndSetInit(Stmt *S, bool EmitDiags = true); | ||||||||
6442 | /// Check test-expr for canonical form, save upper-bound (#UB), flags | ||||||||
6443 | /// for less/greater and for strict/non-strict comparison. | ||||||||
6444 | bool checkAndSetCond(Expr *S); | ||||||||
6445 | /// Check incr-expr for canonical loop form and return true if it | ||||||||
6446 | /// does not conform, otherwise save loop step (#Step). | ||||||||
6447 | bool checkAndSetInc(Expr *S); | ||||||||
6448 | /// Return the loop counter variable. | ||||||||
6449 | ValueDecl *getLoopDecl() const { return LCDecl; } | ||||||||
6450 | /// Return the reference expression to loop counter variable. | ||||||||
6451 | Expr *getLoopDeclRefExpr() const { return LCRef; } | ||||||||
6452 | /// Source range of the loop init. | ||||||||
6453 | SourceRange getInitSrcRange() const { return InitSrcRange; } | ||||||||
6454 | /// Source range of the loop condition. | ||||||||
6455 | SourceRange getConditionSrcRange() const { return ConditionSrcRange; } | ||||||||
6456 | /// Source range of the loop increment. | ||||||||
6457 | SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } | ||||||||
6458 | /// True if the step should be subtracted. | ||||||||
6459 | bool shouldSubtractStep() const { return SubtractStep; } | ||||||||
6460 | /// True, if the compare operator is strict (<, > or !=). | ||||||||
6461 | bool isStrictTestOp() const { return TestIsStrictOp; } | ||||||||
6462 | /// Build the expression to calculate the number of iterations. | ||||||||
6463 | Expr *buildNumIterations( | ||||||||
6464 | Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, | ||||||||
6465 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; | ||||||||
6466 | /// Build the precondition expression for the loops. | ||||||||
6467 | Expr * | ||||||||
6468 | buildPreCond(Scope *S, Expr *Cond, | ||||||||
6469 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; | ||||||||
6470 | /// Build reference expression to the counter be used for codegen. | ||||||||
6471 | DeclRefExpr * | ||||||||
6472 | buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, | ||||||||
6473 | DSAStackTy &DSA) const; | ||||||||
6474 | /// Build reference expression to the private counter be used for | ||||||||
6475 | /// codegen. | ||||||||
6476 | Expr *buildPrivateCounterVar() const; | ||||||||
6477 | /// Build initialization of the counter be used for codegen. | ||||||||
6478 | Expr *buildCounterInit() const; | ||||||||
6479 | /// Build step of the counter be used for codegen. | ||||||||
6480 | Expr *buildCounterStep() const; | ||||||||
6481 | /// Build loop data with counter value for depend clauses in ordered | ||||||||
6482 | /// directives. | ||||||||
6483 | Expr * | ||||||||
6484 | buildOrderedLoopData(Scope *S, Expr *Counter, | ||||||||
6485 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, | ||||||||
6486 | SourceLocation Loc, Expr *Inc = nullptr, | ||||||||
6487 | OverloadedOperatorKind OOK = OO_Amp); | ||||||||
6488 | /// Builds the minimum value for the loop counter. | ||||||||
6489 | std::pair<Expr *, Expr *> buildMinMaxValues( | ||||||||
6490 | Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; | ||||||||
6491 | /// Builds final condition for the non-rectangular loops. | ||||||||
6492 | Expr *buildFinalCondition(Scope *S) const; | ||||||||
6493 | /// Return true if any expression is dependent. | ||||||||
6494 | bool dependent() const; | ||||||||
6495 | /// Returns true if the initializer forms non-rectangular loop. | ||||||||
6496 | bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } | ||||||||
6497 | /// Returns true if the condition forms non-rectangular loop. | ||||||||
6498 | bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } | ||||||||
6499 | /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. | ||||||||
6500 | unsigned getLoopDependentIdx() const { | ||||||||
6501 | return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); | ||||||||
6502 | } | ||||||||
6503 | |||||||||
6504 | private: | ||||||||
6505 | /// Check the right-hand side of an assignment in the increment | ||||||||
6506 | /// expression. | ||||||||
6507 | bool checkAndSetIncRHS(Expr *RHS); | ||||||||
6508 | /// Helper to set loop counter variable and its initializer. | ||||||||
6509 | bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, | ||||||||
6510 | bool EmitDiags); | ||||||||
6511 | /// Helper to set upper bound. | ||||||||
6512 | bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, | ||||||||
6513 | SourceRange SR, SourceLocation SL); | ||||||||
6514 | /// Helper to set loop increment. | ||||||||
6515 | bool setStep(Expr *NewStep, bool Subtract); | ||||||||
6516 | }; | ||||||||
6517 | |||||||||
6518 | bool OpenMPIterationSpaceChecker::dependent() const { | ||||||||
6519 | if (!LCDecl) { | ||||||||
6520 | assert(!LB && !UB && !Step)((!LB && !UB && !Step) ? static_cast<void> (0) : __assert_fail ("!LB && !UB && !Step", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 6520, __PRETTY_FUNCTION__)); | ||||||||
6521 | return false; | ||||||||
6522 | } | ||||||||
6523 | return LCDecl->getType()->isDependentType() || | ||||||||
6524 | (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || | ||||||||
6525 | (Step && Step->isValueDependent()); | ||||||||
6526 | } | ||||||||
6527 | |||||||||
6528 | bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, | ||||||||
6529 | Expr *NewLCRefExpr, | ||||||||
6530 | Expr *NewLB, bool EmitDiags) { | ||||||||
6531 | // State consistency checking to ensure correct usage. | ||||||||
6532 | assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&((LCDecl == nullptr && LB == nullptr && LCRef == nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp) ? static_cast <void> (0) : __assert_fail ("LCDecl == nullptr && LB == nullptr && LCRef == nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 6533, __PRETTY_FUNCTION__)) | ||||||||
6533 | UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp)((LCDecl == nullptr && LB == nullptr && LCRef == nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp) ? static_cast <void> (0) : __assert_fail ("LCDecl == nullptr && LB == nullptr && LCRef == nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 6533, __PRETTY_FUNCTION__)); | ||||||||
6534 | if (!NewLCDecl || !NewLB) | ||||||||
6535 | return true; | ||||||||
6536 | LCDecl = getCanonicalDecl(NewLCDecl); | ||||||||
6537 | LCRef = NewLCRefExpr; | ||||||||
6538 | if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) | ||||||||
6539 | if (const CXXConstructorDecl *Ctor = CE->getConstructor()) | ||||||||
6540 | if ((Ctor->isCopyOrMoveConstructor() || | ||||||||
6541 | Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && | ||||||||
6542 | CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) | ||||||||
6543 | NewLB = CE->getArg(0)->IgnoreParenImpCasts(); | ||||||||
6544 | LB = NewLB; | ||||||||
6545 | if (EmitDiags) | ||||||||
6546 | InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); | ||||||||
6547 | return false; | ||||||||
6548 | } | ||||||||
6549 | |||||||||
6550 | bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, | ||||||||
6551 | llvm::Optional<bool> LessOp, | ||||||||
6552 | bool StrictOp, SourceRange SR, | ||||||||
6553 | SourceLocation SL) { | ||||||||
6554 | // State consistency checking to ensure correct usage. | ||||||||
6555 | assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&((LCDecl != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp) ? static_cast<void> (0) : __assert_fail ("LCDecl != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 6556, __PRETTY_FUNCTION__)) | ||||||||
6556 | Step == nullptr && !TestIsLessOp && !TestIsStrictOp)((LCDecl != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp) ? static_cast<void> (0) : __assert_fail ("LCDecl != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 6556, __PRETTY_FUNCTION__)); | ||||||||
6557 | if (!NewUB) | ||||||||
6558 | return true; | ||||||||
6559 | UB = NewUB; | ||||||||
6560 | if (LessOp) | ||||||||
6561 | TestIsLessOp = LessOp; | ||||||||
6562 | TestIsStrictOp = StrictOp; | ||||||||
6563 | ConditionSrcRange = SR; | ||||||||
6564 | ConditionLoc = SL; | ||||||||
6565 | CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); | ||||||||
6566 | return false; | ||||||||
6567 | } | ||||||||
6568 | |||||||||
6569 | bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { | ||||||||
6570 | // State consistency checking to ensure correct usage. | ||||||||
6571 | assert(LCDecl != nullptr && LB != nullptr && Step == nullptr)((LCDecl != nullptr && LB != nullptr && Step == nullptr) ? static_cast<void> (0) : __assert_fail ("LCDecl != nullptr && LB != nullptr && Step == nullptr" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 6571, __PRETTY_FUNCTION__)); | ||||||||
6572 | if (!NewStep) | ||||||||
6573 | return true; | ||||||||
6574 | if (!NewStep->isValueDependent()) { | ||||||||
6575 | // Check that the step is integer expression. | ||||||||
6576 | SourceLocation StepLoc = NewStep->getBeginLoc(); | ||||||||
6577 | ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( | ||||||||
6578 | StepLoc, getExprAsWritten(NewStep)); | ||||||||
6579 | if (Val.isInvalid()) | ||||||||
6580 | return true; | ||||||||
6581 | NewStep = Val.get(); | ||||||||
6582 | |||||||||
6583 | // OpenMP [2.6, Canonical Loop Form, Restrictions] | ||||||||
6584 | // If test-expr is of form var relational-op b and relational-op is < or | ||||||||
6585 | // <= then incr-expr must cause var to increase on each iteration of the | ||||||||
6586 | // loop. If test-expr is of form var relational-op b and relational-op is | ||||||||
6587 | // > or >= then incr-expr must cause var to decrease on each iteration of | ||||||||
6588 | // the loop. | ||||||||
6589 | // If test-expr is of form b relational-op var and relational-op is < or | ||||||||
6590 | // <= then incr-expr must cause var to decrease on each iteration of the | ||||||||
6591 | // loop. If test-expr is of form b relational-op var and relational-op is | ||||||||
6592 | // > or >= then incr-expr must cause var to increase on each iteration of | ||||||||
6593 | // the loop. | ||||||||
6594 | Optional<llvm::APSInt> Result = | ||||||||
6595 | NewStep->getIntegerConstantExpr(SemaRef.Context); | ||||||||
6596 | bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); | ||||||||
6597 | bool IsConstNeg = | ||||||||
6598 | Result && Result->isSigned() && (Subtract != Result->isNegative()); | ||||||||
6599 | bool IsConstPos = | ||||||||
6600 | Result && Result->isSigned() && (Subtract == Result->isNegative()); | ||||||||
6601 | bool IsConstZero = Result && !Result->getBoolValue(); | ||||||||
6602 | |||||||||
6603 | // != with increment is treated as <; != with decrement is treated as > | ||||||||
6604 | if (!TestIsLessOp.hasValue()) | ||||||||
6605 | TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); | ||||||||
6606 | if (UB && (IsConstZero || | ||||||||
6607 | (TestIsLessOp.getValue() ? | ||||||||
6608 | (IsConstNeg || (IsUnsigned && Subtract)) : | ||||||||
6609 | (IsConstPos || (IsUnsigned && !Subtract))))) { | ||||||||
6610 | SemaRef.Diag(NewStep->getExprLoc(), | ||||||||
6611 | diag::err_omp_loop_incr_not_compatible) | ||||||||
6612 | << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); | ||||||||
6613 | SemaRef.Diag(ConditionLoc, | ||||||||
6614 | diag::note_omp_loop_cond_requres_compatible_incr) | ||||||||
6615 | << TestIsLessOp.getValue() << ConditionSrcRange; | ||||||||
6616 | return true; | ||||||||
6617 | } | ||||||||
6618 | if (TestIsLessOp.getValue() == Subtract) { | ||||||||
6619 | NewStep = | ||||||||
6620 | SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) | ||||||||
6621 | .get(); | ||||||||
6622 | Subtract = !Subtract; | ||||||||
6623 | } | ||||||||
6624 | } | ||||||||
6625 | |||||||||
6626 | Step = NewStep; | ||||||||
6627 | SubtractStep = Subtract; | ||||||||
6628 | return false; | ||||||||
6629 | } | ||||||||
6630 | |||||||||
6631 | namespace { | ||||||||
6632 | /// Checker for the non-rectangular loops. Checks if the initializer or | ||||||||
6633 | /// condition expression references loop counter variable. | ||||||||
6634 | class LoopCounterRefChecker final | ||||||||
6635 | : public ConstStmtVisitor<LoopCounterRefChecker, bool> { | ||||||||
6636 | Sema &SemaRef; | ||||||||
6637 | DSAStackTy &Stack; | ||||||||
6638 | const ValueDecl *CurLCDecl = nullptr; | ||||||||
6639 | const ValueDecl *DepDecl = nullptr; | ||||||||
6640 | const ValueDecl *PrevDepDecl = nullptr; | ||||||||
6641 | bool IsInitializer = true; | ||||||||
6642 | unsigned BaseLoopId = 0; | ||||||||
6643 | bool checkDecl(const Expr *E, const ValueDecl *VD) { | ||||||||
6644 | if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { | ||||||||
6645 | SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) | ||||||||
6646 | << (IsInitializer ? 0 : 1); | ||||||||
6647 | return false; | ||||||||
6648 | } | ||||||||
6649 | const auto &&Data = Stack.isLoopControlVariable(VD); | ||||||||
6650 | // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. | ||||||||
6651 | // The type of the loop iterator on which we depend may not have a random | ||||||||
6652 | // access iterator type. | ||||||||
6653 | if (Data.first && VD->getType()->isRecordType()) { | ||||||||
6654 | SmallString<128> Name; | ||||||||
6655 | llvm::raw_svector_ostream OS(Name); | ||||||||
6656 | VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), | ||||||||
6657 | /*Qualified=*/true); | ||||||||
6658 | SemaRef.Diag(E->getExprLoc(), | ||||||||
6659 | diag::err_omp_wrong_dependency_iterator_type) | ||||||||
6660 | << OS.str(); | ||||||||
6661 | SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; | ||||||||
6662 | return false; | ||||||||
6663 | } | ||||||||
6664 | if (Data.first && | ||||||||
6665 | (DepDecl || (PrevDepDecl && | ||||||||
6666 | getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { | ||||||||
6667 | if (!DepDecl && PrevDepDecl) | ||||||||
6668 | DepDecl = PrevDepDecl; | ||||||||
6669 | SmallString<128> Name; | ||||||||
6670 | llvm::raw_svector_ostream OS(Name); | ||||||||
6671 | DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), | ||||||||
6672 | /*Qualified=*/true); | ||||||||
6673 | SemaRef.Diag(E->getExprLoc(), | ||||||||
6674 | diag::err_omp_invariant_or_linear_dependency) | ||||||||
6675 | << OS.str(); | ||||||||
6676 | return false; | ||||||||
6677 | } | ||||||||
6678 | if (Data.first) { | ||||||||
6679 | DepDecl = VD; | ||||||||
6680 | BaseLoopId = Data.first; | ||||||||
6681 | } | ||||||||
6682 | return Data.first; | ||||||||
6683 | } | ||||||||
6684 | |||||||||
6685 | public: | ||||||||
6686 | bool VisitDeclRefExpr(const DeclRefExpr *E) { | ||||||||
6687 | const ValueDecl *VD = E->getDecl(); | ||||||||
6688 | if (isa<VarDecl>(VD)) | ||||||||
6689 | return checkDecl(E, VD); | ||||||||
6690 | return false; | ||||||||
6691 | } | ||||||||
6692 | bool VisitMemberExpr(const MemberExpr *E) { | ||||||||
6693 | if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { | ||||||||
6694 | const ValueDecl *VD = E->getMemberDecl(); | ||||||||
6695 | if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) | ||||||||
6696 | return checkDecl(E, VD); | ||||||||
6697 | } | ||||||||
6698 | return false; | ||||||||
6699 | } | ||||||||
6700 | bool VisitStmt(const Stmt *S) { | ||||||||
6701 | bool Res = false; | ||||||||
6702 | for (const Stmt *Child : S->children()) | ||||||||
6703 | Res = (Child && Visit(Child)) || Res; | ||||||||
6704 | return Res; | ||||||||
6705 | } | ||||||||
6706 | explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, | ||||||||
6707 | const ValueDecl *CurLCDecl, bool IsInitializer, | ||||||||
6708 | const ValueDecl *PrevDepDecl = nullptr) | ||||||||
6709 | : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), | ||||||||
6710 | PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} | ||||||||
6711 | unsigned getBaseLoopId() const { | ||||||||
6712 | assert(CurLCDecl && "Expected loop dependency.")((CurLCDecl && "Expected loop dependency.") ? static_cast <void> (0) : __assert_fail ("CurLCDecl && \"Expected loop dependency.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 6712, __PRETTY_FUNCTION__)); | ||||||||
6713 | return BaseLoopId; | ||||||||
6714 | } | ||||||||
6715 | const ValueDecl *getDepDecl() const { | ||||||||
6716 | assert(CurLCDecl && "Expected loop dependency.")((CurLCDecl && "Expected loop dependency.") ? static_cast <void> (0) : __assert_fail ("CurLCDecl && \"Expected loop dependency.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 6716, __PRETTY_FUNCTION__)); | ||||||||
6717 | return DepDecl; | ||||||||
6718 | } | ||||||||
6719 | }; | ||||||||
6720 | } // namespace | ||||||||
6721 | |||||||||
6722 | Optional<unsigned> | ||||||||
6723 | OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, | ||||||||
6724 | bool IsInitializer) { | ||||||||
6725 | // Check for the non-rectangular loops. | ||||||||
6726 | LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, | ||||||||
6727 | DepDecl); | ||||||||
6728 | if (LoopStmtChecker.Visit(S)) { | ||||||||
6729 | DepDecl = LoopStmtChecker.getDepDecl(); | ||||||||
6730 | return LoopStmtChecker.getBaseLoopId(); | ||||||||
6731 | } | ||||||||
6732 | return llvm::None; | ||||||||
6733 | } | ||||||||
6734 | |||||||||
6735 | bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { | ||||||||
6736 | // Check init-expr for canonical loop form and save loop counter | ||||||||
6737 | // variable - #Var and its initialization value - #LB. | ||||||||
6738 | // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: | ||||||||
6739 | // var = lb | ||||||||
6740 | // integer-type var = lb | ||||||||
6741 | // random-access-iterator-type var = lb | ||||||||
6742 | // pointer-type var = lb | ||||||||
6743 | // | ||||||||
6744 | if (!S) { | ||||||||
6745 | if (EmitDiags) { | ||||||||
6746 | SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); | ||||||||
6747 | } | ||||||||
6748 | return true; | ||||||||
6749 | } | ||||||||
6750 | if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) | ||||||||
6751 | if (!ExprTemp->cleanupsHaveSideEffects()) | ||||||||
6752 | S = ExprTemp->getSubExpr(); | ||||||||
6753 | |||||||||
6754 | InitSrcRange = S->getSourceRange(); | ||||||||
6755 | if (Expr *E = dyn_cast<Expr>(S)) | ||||||||
6756 | S = E->IgnoreParens(); | ||||||||
6757 | if (auto *BO = dyn_cast<BinaryOperator>(S)) { | ||||||||
6758 | if (BO->getOpcode() == BO_Assign) { | ||||||||
6759 | Expr *LHS = BO->getLHS()->IgnoreParens(); | ||||||||
6760 | if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { | ||||||||
6761 | if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) | ||||||||
6762 | if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) | ||||||||
6763 | return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), | ||||||||
6764 | EmitDiags); | ||||||||
6765 | return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); | ||||||||
6766 | } | ||||||||
6767 | if (auto *ME = dyn_cast<MemberExpr>(LHS)) { | ||||||||
6768 | if (ME->isArrow() && | ||||||||
6769 | isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) | ||||||||
6770 | return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), | ||||||||
6771 | EmitDiags); | ||||||||
6772 | } | ||||||||
6773 | } | ||||||||
6774 | } else if (auto *DS = dyn_cast<DeclStmt>(S)) { | ||||||||
6775 | if (DS->isSingleDecl()) { | ||||||||
6776 | if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { | ||||||||
6777 | if (Var->hasInit() && !Var->getType()->isReferenceType()) { | ||||||||
6778 | // Accept non-canonical init form here but emit ext. warning. | ||||||||
6779 | if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) | ||||||||
6780 | SemaRef.Diag(S->getBeginLoc(), | ||||||||
6781 | diag::ext_omp_loop_not_canonical_init) | ||||||||
6782 | << S->getSourceRange(); | ||||||||
6783 | return setLCDeclAndLB( | ||||||||
6784 | Var, | ||||||||
6785 | buildDeclRefExpr(SemaRef, Var, | ||||||||
6786 | Var->getType().getNonReferenceType(), | ||||||||
6787 | DS->getBeginLoc()), | ||||||||
6788 | Var->getInit(), EmitDiags); | ||||||||
6789 | } | ||||||||
6790 | } | ||||||||
6791 | } | ||||||||
6792 | } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { | ||||||||
6793 | if (CE->getOperator() == OO_Equal) { | ||||||||
6794 | Expr *LHS = CE->getArg(0); | ||||||||
6795 | if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { | ||||||||
6796 | if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) | ||||||||
6797 | if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) | ||||||||
6798 | return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), | ||||||||
6799 | EmitDiags); | ||||||||
6800 | return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); | ||||||||
6801 | } | ||||||||
6802 | if (auto *ME = dyn_cast<MemberExpr>(LHS)) { | ||||||||
6803 | if (ME->isArrow() && | ||||||||
6804 | isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) | ||||||||
6805 | return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), | ||||||||
6806 | EmitDiags); | ||||||||
6807 | } | ||||||||
6808 | } | ||||||||
6809 | } | ||||||||
6810 | |||||||||
6811 | if (dependent() || SemaRef.CurContext->isDependentContext()) | ||||||||
6812 | return false; | ||||||||
6813 | if (EmitDiags) { | ||||||||
6814 | SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) | ||||||||
6815 | << S->getSourceRange(); | ||||||||
6816 | } | ||||||||
6817 | return true; | ||||||||
6818 | } | ||||||||
6819 | |||||||||
6820 | /// Ignore parenthesizes, implicit casts, copy constructor and return the | ||||||||
6821 | /// variable (which may be the loop variable) if possible. | ||||||||
6822 | static const ValueDecl *getInitLCDecl(const Expr *E) { | ||||||||
6823 | if (!E) | ||||||||
6824 | return nullptr; | ||||||||
6825 | E = getExprAsWritten(E); | ||||||||
6826 | if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) | ||||||||
6827 | if (const CXXConstructorDecl *Ctor = CE->getConstructor()) | ||||||||
6828 | if ((Ctor->isCopyOrMoveConstructor() || | ||||||||
6829 | Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && | ||||||||
6830 | CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) | ||||||||
6831 | E = CE->getArg(0)->IgnoreParenImpCasts(); | ||||||||
6832 | if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { | ||||||||
6833 | if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) | ||||||||
6834 | return getCanonicalDecl(VD); | ||||||||
6835 | } | ||||||||
6836 | if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) | ||||||||
6837 | if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) | ||||||||
6838 | return getCanonicalDecl(ME->getMemberDecl()); | ||||||||
6839 | return nullptr; | ||||||||
6840 | } | ||||||||
6841 | |||||||||
6842 | bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { | ||||||||
6843 | // Check test-expr for canonical form, save upper-bound UB, flags for | ||||||||
6844 | // less/greater and for strict/non-strict comparison. | ||||||||
6845 | // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: | ||||||||
6846 | // var relational-op b | ||||||||
6847 | // b relational-op var | ||||||||
6848 | // | ||||||||
6849 | bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; | ||||||||
6850 | if (!S) { | ||||||||
6851 | SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) | ||||||||
6852 | << (IneqCondIsCanonical ? 1 : 0) << LCDecl; | ||||||||
6853 | return true; | ||||||||
6854 | } | ||||||||
6855 | Condition = S; | ||||||||
6856 | S = getExprAsWritten(S); | ||||||||
6857 | SourceLocation CondLoc = S->getBeginLoc(); | ||||||||
6858 | if (auto *BO = dyn_cast<BinaryOperator>(S)) { | ||||||||
6859 | if (BO->isRelationalOp()) { | ||||||||
6860 | if (getInitLCDecl(BO->getLHS()) == LCDecl) | ||||||||
6861 | return setUB(BO->getRHS(), | ||||||||
6862 | (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), | ||||||||
6863 | (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), | ||||||||
6864 | BO->getSourceRange(), BO->getOperatorLoc()); | ||||||||
6865 | if (getInitLCDecl(BO->getRHS()) == LCDecl) | ||||||||
6866 | return setUB(BO->getLHS(), | ||||||||
6867 | (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), | ||||||||
6868 | (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), | ||||||||
6869 | BO->getSourceRange(), BO->getOperatorLoc()); | ||||||||
6870 | } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) | ||||||||
6871 | return setUB( | ||||||||
6872 | getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), | ||||||||
6873 | /*LessOp=*/llvm::None, | ||||||||
6874 | /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); | ||||||||
6875 | } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { | ||||||||
6876 | if (CE->getNumArgs() == 2) { | ||||||||
6877 | auto Op = CE->getOperator(); | ||||||||
6878 | switch (Op) { | ||||||||
6879 | case OO_Greater: | ||||||||
6880 | case OO_GreaterEqual: | ||||||||
6881 | case OO_Less: | ||||||||
6882 | case OO_LessEqual: | ||||||||
6883 | if (getInitLCDecl(CE->getArg(0)) == LCDecl) | ||||||||
6884 | return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, | ||||||||
6885 | Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), | ||||||||
6886 | CE->getOperatorLoc()); | ||||||||
6887 | if (getInitLCDecl(CE->getArg(1)) == LCDecl) | ||||||||
6888 | return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, | ||||||||
6889 | Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), | ||||||||
6890 | CE->getOperatorLoc()); | ||||||||
6891 | break; | ||||||||
6892 | case OO_ExclaimEqual: | ||||||||
6893 | if (IneqCondIsCanonical) | ||||||||
6894 | return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) | ||||||||
6895 | : CE->getArg(0), | ||||||||
6896 | /*LessOp=*/llvm::None, | ||||||||
6897 | /*StrictOp=*/true, CE->getSourceRange(), | ||||||||
6898 | CE->getOperatorLoc()); | ||||||||
6899 | break; | ||||||||
6900 | default: | ||||||||
6901 | break; | ||||||||
6902 | } | ||||||||
6903 | } | ||||||||
6904 | } | ||||||||
6905 | if (dependent() || SemaRef.CurContext->isDependentContext()) | ||||||||
6906 | return false; | ||||||||
6907 | SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) | ||||||||
6908 | << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; | ||||||||
6909 | return true; | ||||||||
6910 | } | ||||||||
6911 | |||||||||
6912 | bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { | ||||||||
6913 | // RHS of canonical loop form increment can be: | ||||||||
6914 | // var + incr | ||||||||
6915 | // incr + var | ||||||||
6916 | // var - incr | ||||||||
6917 | // | ||||||||
6918 | RHS = RHS->IgnoreParenImpCasts(); | ||||||||
6919 | if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { | ||||||||
6920 | if (BO->isAdditiveOp()) { | ||||||||
6921 | bool IsAdd = BO->getOpcode() == BO_Add; | ||||||||
6922 | if (getInitLCDecl(BO->getLHS()) == LCDecl) | ||||||||
6923 | return setStep(BO->getRHS(), !IsAdd); | ||||||||
6924 | if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) | ||||||||
6925 | return setStep(BO->getLHS(), /*Subtract=*/false); | ||||||||
6926 | } | ||||||||
6927 | } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { | ||||||||
6928 | bool IsAdd = CE->getOperator() == OO_Plus; | ||||||||
6929 | if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { | ||||||||
6930 | if (getInitLCDecl(CE->getArg(0)) == LCDecl) | ||||||||
6931 | return setStep(CE->getArg(1), !IsAdd); | ||||||||
6932 | if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) | ||||||||
6933 | return setStep(CE->getArg(0), /*Subtract=*/false); | ||||||||
6934 | } | ||||||||
6935 | } | ||||||||
6936 | if (dependent() || SemaRef.CurContext->isDependentContext()) | ||||||||
6937 | return false; | ||||||||
6938 | SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) | ||||||||
6939 | << RHS->getSourceRange() << LCDecl; | ||||||||
6940 | return true; | ||||||||
6941 | } | ||||||||
6942 | |||||||||
6943 | bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { | ||||||||
6944 | // Check incr-expr for canonical loop form and return true if it | ||||||||
6945 | // does not conform. | ||||||||
6946 | // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: | ||||||||
6947 | // ++var | ||||||||
6948 | // var++ | ||||||||
6949 | // --var | ||||||||
6950 | // var-- | ||||||||
6951 | // var += incr | ||||||||
6952 | // var -= incr | ||||||||
6953 | // var = var + incr | ||||||||
6954 | // var = incr + var | ||||||||
6955 | // var = var - incr | ||||||||
6956 | // | ||||||||
6957 | if (!S) { | ||||||||
6958 | SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; | ||||||||
6959 | return true; | ||||||||
6960 | } | ||||||||
6961 | if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) | ||||||||
6962 | if (!ExprTemp->cleanupsHaveSideEffects()) | ||||||||
6963 | S = ExprTemp->getSubExpr(); | ||||||||
6964 | |||||||||
6965 | IncrementSrcRange = S->getSourceRange(); | ||||||||
6966 | S = S->IgnoreParens(); | ||||||||
6967 | if (auto *UO = dyn_cast<UnaryOperator>(S)) { | ||||||||
6968 | if (UO->isIncrementDecrementOp() && | ||||||||
6969 | getInitLCDecl(UO->getSubExpr()) == LCDecl) | ||||||||
6970 | return setStep(SemaRef | ||||||||
6971 | .ActOnIntegerConstant(UO->getBeginLoc(), | ||||||||
6972 | (UO->isDecrementOp() ? -1 : 1)) | ||||||||
6973 | .get(), | ||||||||
6974 | /*Subtract=*/false); | ||||||||
6975 | } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { | ||||||||
6976 | switch (BO->getOpcode()) { | ||||||||
6977 | case BO_AddAssign: | ||||||||
6978 | case BO_SubAssign: | ||||||||
6979 | if (getInitLCDecl(BO->getLHS()) == LCDecl) | ||||||||
6980 | return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); | ||||||||
6981 | break; | ||||||||
6982 | case BO_Assign: | ||||||||
6983 | if (getInitLCDecl(BO->getLHS()) == LCDecl) | ||||||||
6984 | return checkAndSetIncRHS(BO->getRHS()); | ||||||||
6985 | break; | ||||||||
6986 | default: | ||||||||
6987 | break; | ||||||||
6988 | } | ||||||||
6989 | } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { | ||||||||
6990 | switch (CE->getOperator()) { | ||||||||
6991 | case OO_PlusPlus: | ||||||||
6992 | case OO_MinusMinus: | ||||||||
6993 | if (getInitLCDecl(CE->getArg(0)) == LCDecl) | ||||||||
6994 | return setStep(SemaRef | ||||||||
6995 | .ActOnIntegerConstant( | ||||||||
6996 | CE->getBeginLoc(), | ||||||||
6997 | ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) | ||||||||
6998 | .get(), | ||||||||
6999 | /*Subtract=*/false); | ||||||||
7000 | break; | ||||||||
7001 | case OO_PlusEqual: | ||||||||
7002 | case OO_MinusEqual: | ||||||||
7003 | if (getInitLCDecl(CE->getArg(0)) == LCDecl) | ||||||||
7004 | return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); | ||||||||
7005 | break; | ||||||||
7006 | case OO_Equal: | ||||||||
7007 | if (getInitLCDecl(CE->getArg(0)) == LCDecl) | ||||||||
7008 | return checkAndSetIncRHS(CE->getArg(1)); | ||||||||
7009 | break; | ||||||||
7010 | default: | ||||||||
7011 | break; | ||||||||
7012 | } | ||||||||
7013 | } | ||||||||
7014 | if (dependent() || SemaRef.CurContext->isDependentContext()) | ||||||||
7015 | return false; | ||||||||
7016 | SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) | ||||||||
7017 | << S->getSourceRange() << LCDecl; | ||||||||
7018 | return true; | ||||||||
7019 | } | ||||||||
7020 | |||||||||
7021 | static ExprResult | ||||||||
7022 | tryBuildCapture(Sema &SemaRef, Expr *Capture, | ||||||||
7023 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { | ||||||||
7024 | if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors()) | ||||||||
7025 | return Capture; | ||||||||
7026 | if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) | ||||||||
7027 | return SemaRef.PerformImplicitConversion( | ||||||||
7028 | Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, | ||||||||
7029 | /*AllowExplicit=*/true); | ||||||||
7030 | auto I = Captures.find(Capture); | ||||||||
7031 | if (I != Captures.end()) | ||||||||
7032 | return buildCapture(SemaRef, Capture, I->second); | ||||||||
7033 | DeclRefExpr *Ref = nullptr; | ||||||||
7034 | ExprResult Res = buildCapture(SemaRef, Capture, Ref); | ||||||||
7035 | Captures[Capture] = Ref; | ||||||||
7036 | return Res; | ||||||||
7037 | } | ||||||||
7038 | |||||||||
7039 | /// Calculate number of iterations, transforming to unsigned, if number of | ||||||||
7040 | /// iterations may be larger than the original type. | ||||||||
7041 | static Expr * | ||||||||
7042 | calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc, | ||||||||
7043 | Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy, | ||||||||
7044 | bool TestIsStrictOp, bool RoundToStep, | ||||||||
7045 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { | ||||||||
7046 | ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); | ||||||||
7047 | if (!NewStep.isUsable()) | ||||||||
7048 | return nullptr; | ||||||||
7049 | llvm::APSInt LRes, SRes; | ||||||||
7050 | bool IsLowerConst = false, IsStepConst = false; | ||||||||
7051 | if (Optional<llvm::APSInt> Res = Lower->getIntegerConstantExpr(SemaRef.Context)) { | ||||||||
7052 | LRes = *Res; | ||||||||
7053 | IsLowerConst = true; | ||||||||
7054 | } | ||||||||
7055 | if (Optional<llvm::APSInt> Res = Step->getIntegerConstantExpr(SemaRef.Context)) { | ||||||||
7056 | SRes = *Res; | ||||||||
7057 | IsStepConst = true; | ||||||||
7058 | } | ||||||||
7059 | bool NoNeedToConvert = IsLowerConst && !RoundToStep && | ||||||||
7060 | ((!TestIsStrictOp && LRes.isNonNegative()) || | ||||||||
7061 | (TestIsStrictOp && LRes.isStrictlyPositive())); | ||||||||
7062 | bool NeedToReorganize = false; | ||||||||
7063 | // Check if any subexpressions in Lower -Step [+ 1] lead to overflow. | ||||||||
7064 | if (!NoNeedToConvert && IsLowerConst && | ||||||||
7065 | (TestIsStrictOp || (RoundToStep && IsStepConst))) { | ||||||||
7066 | NoNeedToConvert = true; | ||||||||
7067 | if (RoundToStep) { | ||||||||
7068 | unsigned BW = LRes.getBitWidth() > SRes.getBitWidth() | ||||||||
7069 | ? LRes.getBitWidth() | ||||||||
7070 | : SRes.getBitWidth(); | ||||||||
7071 | LRes = LRes.extend(BW + 1); | ||||||||
7072 | LRes.setIsSigned(true); | ||||||||
7073 | SRes = SRes.extend(BW + 1); | ||||||||
7074 | SRes.setIsSigned(true); | ||||||||
7075 | LRes -= SRes; | ||||||||
7076 | NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes; | ||||||||
7077 | LRes = LRes.trunc(BW); | ||||||||
7078 | } | ||||||||
7079 | if (TestIsStrictOp) { | ||||||||
7080 | unsigned BW = LRes.getBitWidth(); | ||||||||
7081 | LRes = LRes.extend(BW + 1); | ||||||||
7082 | LRes.setIsSigned(true); | ||||||||
7083 | ++LRes; | ||||||||
7084 | NoNeedToConvert = | ||||||||
7085 | NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes; | ||||||||
7086 | // truncate to the original bitwidth. | ||||||||
7087 | LRes = LRes.trunc(BW); | ||||||||
7088 | } | ||||||||
7089 | NeedToReorganize = NoNeedToConvert; | ||||||||
7090 | } | ||||||||
7091 | llvm::APSInt URes; | ||||||||
7092 | bool IsUpperConst = false; | ||||||||
7093 | if (Optional<llvm::APSInt> Res = Upper->getIntegerConstantExpr(SemaRef.Context)) { | ||||||||
7094 | URes = *Res; | ||||||||
7095 | IsUpperConst = true; | ||||||||
7096 | } | ||||||||
7097 | if (NoNeedToConvert && IsLowerConst && IsUpperConst && | ||||||||
7098 | (!RoundToStep || IsStepConst)) { | ||||||||
7099 | unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth() | ||||||||
7100 | : URes.getBitWidth(); | ||||||||
7101 | LRes = LRes.extend(BW + 1); | ||||||||
7102 | LRes.setIsSigned(true); | ||||||||
7103 | URes = URes.extend(BW + 1); | ||||||||
7104 | URes.setIsSigned(true); | ||||||||
7105 | URes -= LRes; | ||||||||
7106 | NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes; | ||||||||
7107 | NeedToReorganize = NoNeedToConvert; | ||||||||
7108 | } | ||||||||
7109 | // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant | ||||||||
7110 | // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to | ||||||||
7111 | // unsigned. | ||||||||
7112 | if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) && | ||||||||
7113 | !LCTy->isDependentType() && LCTy->isIntegerType()) { | ||||||||
7114 | QualType LowerTy = Lower->getType(); | ||||||||
7115 | QualType UpperTy = Upper->getType(); | ||||||||
7116 | uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy); | ||||||||
7117 | uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy); | ||||||||
7118 | if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) || | ||||||||
7119 | (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) { | ||||||||
7120 | QualType CastType = SemaRef.Context.getIntTypeForBitwidth( | ||||||||
7121 | LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0); | ||||||||
7122 | Upper = | ||||||||
7123 | SemaRef | ||||||||
7124 | .PerformImplicitConversion( | ||||||||
7125 | SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), | ||||||||
7126 | CastType, Sema::AA_Converting) | ||||||||
7127 | .get(); | ||||||||
7128 | Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(); | ||||||||
7129 | NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get()); | ||||||||
7130 | } | ||||||||
7131 | } | ||||||||
7132 | if (!Lower || !Upper || NewStep.isInvalid()) | ||||||||
7133 | return nullptr; | ||||||||
7134 | |||||||||
7135 | ExprResult Diff; | ||||||||
7136 | // If need to reorganize, then calculate the form as Upper - (Lower - Step [+ | ||||||||
7137 | // 1]). | ||||||||
7138 | if (NeedToReorganize) { | ||||||||
7139 | Diff = Lower; | ||||||||
7140 | |||||||||
7141 | if (RoundToStep) { | ||||||||
7142 | // Lower - Step | ||||||||
7143 | Diff = | ||||||||
7144 | SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get()); | ||||||||
7145 | if (!Diff.isUsable()) | ||||||||
7146 | return nullptr; | ||||||||
7147 | } | ||||||||
7148 | |||||||||
7149 | // Lower - Step [+ 1] | ||||||||
7150 | if (TestIsStrictOp) | ||||||||
7151 | Diff = SemaRef.BuildBinOp( | ||||||||
7152 | S, DefaultLoc, BO_Add, Diff.get(), | ||||||||
7153 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); | ||||||||
7154 | if (!Diff.isUsable()) | ||||||||
7155 | return nullptr; | ||||||||
7156 | |||||||||
7157 | Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); | ||||||||
7158 | if (!Diff.isUsable()) | ||||||||
7159 | return nullptr; | ||||||||
7160 | |||||||||
7161 | // Upper - (Lower - Step [+ 1]). | ||||||||
7162 | Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); | ||||||||
7163 | if (!Diff.isUsable()) | ||||||||
7164 | return nullptr; | ||||||||
7165 | } else { | ||||||||
7166 | Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); | ||||||||
7167 | |||||||||
7168 | if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) { | ||||||||
7169 | // BuildBinOp already emitted error, this one is to point user to upper | ||||||||
7170 | // and lower bound, and to tell what is passed to 'operator-'. | ||||||||
7171 | SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) | ||||||||
7172 | << Upper->getSourceRange() << Lower->getSourceRange(); | ||||||||
7173 | return nullptr; | ||||||||
7174 | } | ||||||||
7175 | |||||||||
7176 | if (!Diff.isUsable()) | ||||||||
7177 | return nullptr; | ||||||||
7178 | |||||||||
7179 | // Upper - Lower [- 1] | ||||||||
7180 | if (TestIsStrictOp) | ||||||||
7181 | Diff = SemaRef.BuildBinOp( | ||||||||
7182 | S, DefaultLoc, BO_Sub, Diff.get(), | ||||||||
7183 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); | ||||||||
7184 | if (!Diff.isUsable()) | ||||||||
7185 | return nullptr; | ||||||||
7186 | |||||||||
7187 | if (RoundToStep) { | ||||||||
7188 | // Upper - Lower [- 1] + Step | ||||||||
7189 | Diff = | ||||||||
7190 | SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); | ||||||||
7191 | if (!Diff.isUsable()) | ||||||||
7192 | return nullptr; | ||||||||
7193 | } | ||||||||
7194 | } | ||||||||
7195 | |||||||||
7196 | // Parentheses (for dumping/debugging purposes only). | ||||||||
7197 | Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); | ||||||||
7198 | if (!Diff.isUsable()) | ||||||||
7199 | return nullptr; | ||||||||
7200 | |||||||||
7201 | // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step | ||||||||
7202 | Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); | ||||||||
7203 | if (!Diff.isUsable()) | ||||||||
7204 | return nullptr; | ||||||||
7205 | |||||||||
7206 | return Diff.get(); | ||||||||
7207 | } | ||||||||
7208 | |||||||||
7209 | /// Build the expression to calculate the number of iterations. | ||||||||
7210 | Expr *OpenMPIterationSpaceChecker::buildNumIterations( | ||||||||
7211 | Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, | ||||||||
7212 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { | ||||||||
7213 | QualType VarType = LCDecl->getType().getNonReferenceType(); | ||||||||
7214 | if (!VarType->isIntegerType() && !VarType->isPointerType() && | ||||||||
7215 | !SemaRef.getLangOpts().CPlusPlus) | ||||||||
7216 | return nullptr; | ||||||||
7217 | Expr *LBVal = LB; | ||||||||
7218 | Expr *UBVal = UB; | ||||||||
7219 | // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : | ||||||||
7220 | // max(LB(MinVal), LB(MaxVal)) | ||||||||
7221 | if (InitDependOnLC) { | ||||||||
7222 | const LoopIterationSpace &IS = | ||||||||
7223 | ResultIterSpaces[ResultIterSpaces.size() - 1 - | ||||||||
7224 | InitDependOnLC.getValueOr( | ||||||||
7225 | CondDependOnLC.getValueOr(0))]; | ||||||||
7226 | if (!IS.MinValue || !IS.MaxValue) | ||||||||
7227 | return nullptr; | ||||||||
7228 | // OuterVar = Min | ||||||||
7229 | ExprResult MinValue = | ||||||||
7230 | SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); | ||||||||
7231 | if (!MinValue.isUsable()) | ||||||||
7232 | return nullptr; | ||||||||
7233 | |||||||||
7234 | ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, | ||||||||
7235 | IS.CounterVar, MinValue.get()); | ||||||||
7236 | if (!LBMinVal.isUsable()) | ||||||||
7237 | return nullptr; | ||||||||
7238 | // OuterVar = Min, LBVal | ||||||||
7239 | LBMinVal = | ||||||||
7240 | SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); | ||||||||
7241 | if (!LBMinVal.isUsable()) | ||||||||
7242 | return nullptr; | ||||||||
7243 | // (OuterVar = Min, LBVal) | ||||||||
7244 | LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); | ||||||||
7245 | if (!LBMinVal.isUsable()) | ||||||||
7246 | return nullptr; | ||||||||
7247 | |||||||||
7248 | // OuterVar = Max | ||||||||
7249 | ExprResult MaxValue = | ||||||||
7250 | SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); | ||||||||
7251 | if (!MaxValue.isUsable()) | ||||||||
7252 | return nullptr; | ||||||||
7253 | |||||||||
7254 | ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, | ||||||||
7255 | IS.CounterVar, MaxValue.get()); | ||||||||
7256 | if (!LBMaxVal.isUsable()) | ||||||||
7257 | return nullptr; | ||||||||
7258 | // OuterVar = Max, LBVal | ||||||||
7259 | LBMaxVal = | ||||||||
7260 | SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); | ||||||||
7261 | if (!LBMaxVal.isUsable()) | ||||||||
7262 | return nullptr; | ||||||||
7263 | // (OuterVar = Max, LBVal) | ||||||||
7264 | LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); | ||||||||
7265 | if (!LBMaxVal.isUsable()) | ||||||||
7266 | return nullptr; | ||||||||
7267 | |||||||||
7268 | Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); | ||||||||
7269 | Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); | ||||||||
7270 | if (!LBMin || !LBMax) | ||||||||
7271 | return nullptr; | ||||||||
7272 | // LB(MinVal) < LB(MaxVal) | ||||||||
7273 | ExprResult MinLessMaxRes = | ||||||||
7274 | SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); | ||||||||
7275 | if (!MinLessMaxRes.isUsable()) | ||||||||
7276 | return nullptr; | ||||||||
7277 | Expr *MinLessMax = | ||||||||
7278 | tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); | ||||||||
7279 | if (!MinLessMax) | ||||||||
7280 | return nullptr; | ||||||||
7281 | if (TestIsLessOp.getValue()) { | ||||||||
7282 | // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), | ||||||||
7283 | // LB(MaxVal)) | ||||||||
7284 | ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, | ||||||||
7285 | MinLessMax, LBMin, LBMax); | ||||||||
7286 | if (!MinLB.isUsable()) | ||||||||
7287 | return nullptr; | ||||||||
7288 | LBVal = MinLB.get(); | ||||||||
7289 | } else { | ||||||||
7290 | // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), | ||||||||
7291 | // LB(MaxVal)) | ||||||||
7292 | ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, | ||||||||
7293 | MinLessMax, LBMax, LBMin); | ||||||||
7294 | if (!MaxLB.isUsable()) | ||||||||
7295 | return nullptr; | ||||||||
7296 | LBVal = MaxLB.get(); | ||||||||
7297 | } | ||||||||
7298 | } | ||||||||
7299 | // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : | ||||||||
7300 | // min(UB(MinVal), UB(MaxVal)) | ||||||||
7301 | if (CondDependOnLC) { | ||||||||
7302 | const LoopIterationSpace &IS = | ||||||||
7303 | ResultIterSpaces[ResultIterSpaces.size() - 1 - | ||||||||
7304 | InitDependOnLC.getValueOr( | ||||||||
7305 | CondDependOnLC.getValueOr(0))]; | ||||||||
7306 | if (!IS.MinValue || !IS.MaxValue) | ||||||||
7307 | return nullptr; | ||||||||
7308 | // OuterVar = Min | ||||||||
7309 | ExprResult MinValue = | ||||||||
7310 | SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); | ||||||||
7311 | if (!MinValue.isUsable()) | ||||||||
7312 | return nullptr; | ||||||||
7313 | |||||||||
7314 | ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, | ||||||||
7315 | IS.CounterVar, MinValue.get()); | ||||||||
7316 | if (!UBMinVal.isUsable()) | ||||||||
7317 | return nullptr; | ||||||||
7318 | // OuterVar = Min, UBVal | ||||||||
7319 | UBMinVal = | ||||||||
7320 | SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); | ||||||||
7321 | if (!UBMinVal.isUsable()) | ||||||||
7322 | return nullptr; | ||||||||
7323 | // (OuterVar = Min, UBVal) | ||||||||
7324 | UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); | ||||||||
7325 | if (!UBMinVal.isUsable()) | ||||||||
7326 | return nullptr; | ||||||||
7327 | |||||||||
7328 | // OuterVar = Max | ||||||||
7329 | ExprResult MaxValue = | ||||||||
7330 | SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); | ||||||||
7331 | if (!MaxValue.isUsable()) | ||||||||
7332 | return nullptr; | ||||||||
7333 | |||||||||
7334 | ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, | ||||||||
7335 | IS.CounterVar, MaxValue.get()); | ||||||||
7336 | if (!UBMaxVal.isUsable()) | ||||||||
7337 | return nullptr; | ||||||||
7338 | // OuterVar = Max, UBVal | ||||||||
7339 | UBMaxVal = | ||||||||
7340 | SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); | ||||||||
7341 | if (!UBMaxVal.isUsable()) | ||||||||
7342 | return nullptr; | ||||||||
7343 | // (OuterVar = Max, UBVal) | ||||||||
7344 | UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); | ||||||||
7345 | if (!UBMaxVal.isUsable()) | ||||||||
7346 | return nullptr; | ||||||||
7347 | |||||||||
7348 | Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); | ||||||||
7349 | Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); | ||||||||
7350 | if (!UBMin || !UBMax) | ||||||||
7351 | return nullptr; | ||||||||
7352 | // UB(MinVal) > UB(MaxVal) | ||||||||
7353 | ExprResult MinGreaterMaxRes = | ||||||||
7354 | SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); | ||||||||
7355 | if (!MinGreaterMaxRes.isUsable()) | ||||||||
7356 | return nullptr; | ||||||||
7357 | Expr *MinGreaterMax = | ||||||||
7358 | tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); | ||||||||
7359 | if (!MinGreaterMax) | ||||||||
7360 | return nullptr; | ||||||||
7361 | if (TestIsLessOp.getValue()) { | ||||||||
7362 | // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), | ||||||||
7363 | // UB(MaxVal)) | ||||||||
7364 | ExprResult MaxUB = SemaRef.ActOnConditionalOp( | ||||||||
7365 | DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); | ||||||||
7366 | if (!MaxUB.isUsable()) | ||||||||
7367 | return nullptr; | ||||||||
7368 | UBVal = MaxUB.get(); | ||||||||
7369 | } else { | ||||||||
7370 | // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), | ||||||||
7371 | // UB(MaxVal)) | ||||||||
7372 | ExprResult MinUB = SemaRef.ActOnConditionalOp( | ||||||||
7373 | DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); | ||||||||
7374 | if (!MinUB.isUsable()) | ||||||||
7375 | return nullptr; | ||||||||
7376 | UBVal = MinUB.get(); | ||||||||
7377 | } | ||||||||
7378 | } | ||||||||
7379 | Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; | ||||||||
7380 | Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; | ||||||||
7381 | Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); | ||||||||
7382 | Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); | ||||||||
7383 | if (!Upper || !Lower) | ||||||||
7384 | return nullptr; | ||||||||
7385 | |||||||||
7386 | ExprResult Diff = | ||||||||
7387 | calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType, | ||||||||
7388 | TestIsStrictOp, /*RoundToStep=*/true, Captures); | ||||||||
7389 | if (!Diff.isUsable()) | ||||||||
7390 | return nullptr; | ||||||||
7391 | |||||||||
7392 | // OpenMP runtime requires 32-bit or 64-bit loop variables. | ||||||||
7393 | QualType Type = Diff.get()->getType(); | ||||||||
7394 | ASTContext &C = SemaRef.Context; | ||||||||
7395 | bool UseVarType = VarType->hasIntegerRepresentation() && | ||||||||
7396 | C.getTypeSize(Type) > C.getTypeSize(VarType); | ||||||||
7397 | if (!Type->isIntegerType() || UseVarType) { | ||||||||
7398 | unsigned NewSize = | ||||||||
7399 | UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); | ||||||||
7400 | bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() | ||||||||
7401 | : Type->hasSignedIntegerRepresentation(); | ||||||||
7402 | Type = C.getIntTypeForBitwidth(NewSize, IsSigned); | ||||||||
7403 | if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { | ||||||||
7404 | Diff = SemaRef.PerformImplicitConversion( | ||||||||
7405 | Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); | ||||||||
7406 | if (!Diff.isUsable()) | ||||||||
7407 | return nullptr; | ||||||||
7408 | } | ||||||||
7409 | } | ||||||||
7410 | if (LimitedType) { | ||||||||
7411 | unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; | ||||||||
7412 | if (NewSize != C.getTypeSize(Type)) { | ||||||||
7413 | if (NewSize < C.getTypeSize(Type)) { | ||||||||
7414 | assert(NewSize == 64 && "incorrect loop var size")((NewSize == 64 && "incorrect loop var size") ? static_cast <void> (0) : __assert_fail ("NewSize == 64 && \"incorrect loop var size\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 7414, __PRETTY_FUNCTION__)); | ||||||||
7415 | SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) | ||||||||
7416 | << InitSrcRange << ConditionSrcRange; | ||||||||
7417 | } | ||||||||
7418 | QualType NewType = C.getIntTypeForBitwidth( | ||||||||
7419 | NewSize, Type->hasSignedIntegerRepresentation() || | ||||||||
7420 | C.getTypeSize(Type) < NewSize); | ||||||||
7421 | if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { | ||||||||
7422 | Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, | ||||||||
7423 | Sema::AA_Converting, true); | ||||||||
7424 | if (!Diff.isUsable()) | ||||||||
7425 | return nullptr; | ||||||||
7426 | } | ||||||||
7427 | } | ||||||||
7428 | } | ||||||||
7429 | |||||||||
7430 | return Diff.get(); | ||||||||
7431 | } | ||||||||
7432 | |||||||||
7433 | std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( | ||||||||
7434 | Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { | ||||||||
7435 | // Do not build for iterators, they cannot be used in non-rectangular loop | ||||||||
7436 | // nests. | ||||||||
7437 | if (LCDecl->getType()->isRecordType()) | ||||||||
7438 | return std::make_pair(nullptr, nullptr); | ||||||||
7439 | // If we subtract, the min is in the condition, otherwise the min is in the | ||||||||
7440 | // init value. | ||||||||
7441 | Expr *MinExpr = nullptr; | ||||||||
7442 | Expr *MaxExpr = nullptr; | ||||||||
7443 | Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; | ||||||||
7444 | Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; | ||||||||
7445 | bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() | ||||||||
7446 | : CondDependOnLC.hasValue(); | ||||||||
7447 | bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() | ||||||||
7448 | : InitDependOnLC.hasValue(); | ||||||||
7449 | Expr *Lower = | ||||||||
7450 | LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); | ||||||||
7451 | Expr *Upper = | ||||||||
7452 | UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); | ||||||||
7453 | if (!Upper || !Lower) | ||||||||
7454 | return std::make_pair(nullptr, nullptr); | ||||||||
7455 | |||||||||
7456 | if (TestIsLessOp.getValue()) | ||||||||
7457 | MinExpr = Lower; | ||||||||
7458 | else | ||||||||
7459 | MaxExpr = Upper; | ||||||||
7460 | |||||||||
7461 | // Build minimum/maximum value based on number of iterations. | ||||||||
7462 | QualType VarType = LCDecl->getType().getNonReferenceType(); | ||||||||
7463 | |||||||||
7464 | ExprResult Diff = | ||||||||
7465 | calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType, | ||||||||
7466 | TestIsStrictOp, /*RoundToStep=*/false, Captures); | ||||||||
7467 | if (!Diff.isUsable()) | ||||||||
7468 | return std::make_pair(nullptr, nullptr); | ||||||||
7469 | |||||||||
7470 | // ((Upper - Lower [- 1]) / Step) * Step | ||||||||
7471 | // Parentheses (for dumping/debugging purposes only). | ||||||||
7472 | Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); | ||||||||
7473 | if (!Diff.isUsable()) | ||||||||
7474 | return std::make_pair(nullptr, nullptr); | ||||||||
7475 | |||||||||
7476 | ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); | ||||||||
7477 | if (!NewStep.isUsable()) | ||||||||
7478 | return std::make_pair(nullptr, nullptr); | ||||||||
7479 | Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); | ||||||||
7480 | if (!Diff.isUsable()) | ||||||||
7481 | return std::make_pair(nullptr, nullptr); | ||||||||
7482 | |||||||||
7483 | // Parentheses (for dumping/debugging purposes only). | ||||||||
7484 | Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); | ||||||||
7485 | if (!Diff.isUsable()) | ||||||||
7486 | return std::make_pair(nullptr, nullptr); | ||||||||
7487 | |||||||||
7488 | // Convert to the ptrdiff_t, if original type is pointer. | ||||||||
7489 | if (VarType->isAnyPointerType() && | ||||||||
7490 | !SemaRef.Context.hasSameType( | ||||||||
7491 | Diff.get()->getType(), | ||||||||
7492 | SemaRef.Context.getUnsignedPointerDiffType())) { | ||||||||
7493 | Diff = SemaRef.PerformImplicitConversion( | ||||||||
7494 | Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), | ||||||||
7495 | Sema::AA_Converting, /*AllowExplicit=*/true); | ||||||||
7496 | } | ||||||||
7497 | if (!Diff.isUsable()) | ||||||||
7498 | return std::make_pair(nullptr, nullptr); | ||||||||
7499 | |||||||||
7500 | if (TestIsLessOp.getValue()) { | ||||||||
7501 | // MinExpr = Lower; | ||||||||
7502 | // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) | ||||||||
7503 | Diff = SemaRef.BuildBinOp( | ||||||||
7504 | S, DefaultLoc, BO_Add, | ||||||||
7505 | SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(), | ||||||||
7506 | Diff.get()); | ||||||||
7507 | if (!Diff.isUsable()) | ||||||||
7508 | return std::make_pair(nullptr, nullptr); | ||||||||
7509 | } else { | ||||||||
7510 | // MaxExpr = Upper; | ||||||||
7511 | // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) | ||||||||
7512 | Diff = SemaRef.BuildBinOp( | ||||||||
7513 | S, DefaultLoc, BO_Sub, | ||||||||
7514 | SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), | ||||||||
7515 | Diff.get()); | ||||||||
7516 | if (!Diff.isUsable()) | ||||||||
7517 | return std::make_pair(nullptr, nullptr); | ||||||||
7518 | } | ||||||||
7519 | |||||||||
7520 | // Convert to the original type. | ||||||||
7521 | if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) | ||||||||
7522 | Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType, | ||||||||
7523 | Sema::AA_Converting, | ||||||||
7524 | /*AllowExplicit=*/true); | ||||||||
7525 | if (!Diff.isUsable()) | ||||||||
7526 | return std::make_pair(nullptr, nullptr); | ||||||||
7527 | |||||||||
7528 | Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false); | ||||||||
7529 | if (!Diff.isUsable()) | ||||||||
7530 | return std::make_pair(nullptr, nullptr); | ||||||||
7531 | |||||||||
7532 | if (TestIsLessOp.getValue()) | ||||||||
7533 | MaxExpr = Diff.get(); | ||||||||
7534 | else | ||||||||
7535 | MinExpr = Diff.get(); | ||||||||
7536 | |||||||||
7537 | return std::make_pair(MinExpr, MaxExpr); | ||||||||
7538 | } | ||||||||
7539 | |||||||||
7540 | Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { | ||||||||
7541 | if (InitDependOnLC || CondDependOnLC) | ||||||||
7542 | return Condition; | ||||||||
7543 | return nullptr; | ||||||||
7544 | } | ||||||||
7545 | |||||||||
7546 | Expr *OpenMPIterationSpaceChecker::buildPreCond( | ||||||||
7547 | Scope *S, Expr *Cond, | ||||||||
7548 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { | ||||||||
7549 | // Do not build a precondition when the condition/initialization is dependent | ||||||||
7550 | // to prevent pessimistic early loop exit. | ||||||||
7551 | // TODO: this can be improved by calculating min/max values but not sure that | ||||||||
7552 | // it will be very effective. | ||||||||
7553 | if (CondDependOnLC || InitDependOnLC) | ||||||||
7554 | return SemaRef.PerformImplicitConversion( | ||||||||
7555 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), | ||||||||
7556 | SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, | ||||||||
7557 | /*AllowExplicit=*/true).get(); | ||||||||
7558 | |||||||||
7559 | // Try to build LB <op> UB, where <op> is <, >, <=, or >=. | ||||||||
7560 | Sema::TentativeAnalysisScope Trap(SemaRef); | ||||||||
7561 | |||||||||
7562 | ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); | ||||||||
7563 | ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); | ||||||||
7564 | if (!NewLB.isUsable() || !NewUB.isUsable()) | ||||||||
7565 | return nullptr; | ||||||||
7566 | |||||||||
7567 | ExprResult CondExpr = | ||||||||
7568 | SemaRef.BuildBinOp(S, DefaultLoc, | ||||||||
7569 | TestIsLessOp.getValue() ? | ||||||||
7570 | (TestIsStrictOp ? BO_LT : BO_LE) : | ||||||||
7571 | (TestIsStrictOp ? BO_GT : BO_GE), | ||||||||
7572 | NewLB.get(), NewUB.get()); | ||||||||
7573 | if (CondExpr.isUsable()) { | ||||||||
7574 | if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), | ||||||||
7575 | SemaRef.Context.BoolTy)) | ||||||||
7576 | CondExpr = SemaRef.PerformImplicitConversion( | ||||||||
7577 | CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, | ||||||||
7578 | /*AllowExplicit=*/true); | ||||||||
7579 | } | ||||||||
7580 | |||||||||
7581 | // Otherwise use original loop condition and evaluate it in runtime. | ||||||||
7582 | return CondExpr.isUsable() ? CondExpr.get() : Cond; | ||||||||
7583 | } | ||||||||
7584 | |||||||||
7585 | /// Build reference expression to the counter be used for codegen. | ||||||||
7586 | DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( | ||||||||
7587 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, | ||||||||
7588 | DSAStackTy &DSA) const { | ||||||||
7589 | auto *VD = dyn_cast<VarDecl>(LCDecl); | ||||||||
7590 | if (!VD) { | ||||||||
7591 | VD = SemaRef.isOpenMPCapturedDecl(LCDecl); | ||||||||
7592 | DeclRefExpr *Ref = buildDeclRefExpr( | ||||||||
7593 | SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); | ||||||||
7594 | const DSAStackTy::DSAVarData Data = | ||||||||
7595 | DSA.getTopDSA(LCDecl, /*FromParent=*/false); | ||||||||
7596 | // If the loop control decl is explicitly marked as private, do not mark it | ||||||||
7597 | // as captured again. | ||||||||
7598 | if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) | ||||||||
7599 | Captures.insert(std::make_pair(LCRef, Ref)); | ||||||||
7600 | return Ref; | ||||||||
7601 | } | ||||||||
7602 | return cast<DeclRefExpr>(LCRef); | ||||||||
7603 | } | ||||||||
7604 | |||||||||
7605 | Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { | ||||||||
7606 | if (LCDecl && !LCDecl->isInvalidDecl()) { | ||||||||
7607 | QualType Type = LCDecl->getType().getNonReferenceType(); | ||||||||
7608 | VarDecl *PrivateVar = buildVarDecl( | ||||||||
7609 | SemaRef, DefaultLoc, Type, LCDecl->getName(), | ||||||||
7610 | LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, | ||||||||
7611 | isa<VarDecl>(LCDecl) | ||||||||
7612 | ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) | ||||||||
7613 | : nullptr); | ||||||||
7614 | if (PrivateVar->isInvalidDecl()) | ||||||||
7615 | return nullptr; | ||||||||
7616 | return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); | ||||||||
7617 | } | ||||||||
7618 | return nullptr; | ||||||||
7619 | } | ||||||||
7620 | |||||||||
7621 | /// Build initialization of the counter to be used for codegen. | ||||||||
7622 | Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } | ||||||||
7623 | |||||||||
7624 | /// Build step of the counter be used for codegen. | ||||||||
7625 | Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } | ||||||||
7626 | |||||||||
7627 | Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( | ||||||||
7628 | Scope *S, Expr *Counter, | ||||||||
7629 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, | ||||||||
7630 | Expr *Inc, OverloadedOperatorKind OOK) { | ||||||||
7631 | Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); | ||||||||
7632 | if (!Cnt) | ||||||||
7633 | return nullptr; | ||||||||
7634 | if (Inc) { | ||||||||
7635 | assert((OOK == OO_Plus || OOK == OO_Minus) &&(((OOK == OO_Plus || OOK == OO_Minus) && "Expected only + or - operations for depend clauses." ) ? static_cast<void> (0) : __assert_fail ("(OOK == OO_Plus || OOK == OO_Minus) && \"Expected only + or - operations for depend clauses.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 7636, __PRETTY_FUNCTION__)) | ||||||||
7636 | "Expected only + or - operations for depend clauses.")(((OOK == OO_Plus || OOK == OO_Minus) && "Expected only + or - operations for depend clauses." ) ? static_cast<void> (0) : __assert_fail ("(OOK == OO_Plus || OOK == OO_Minus) && \"Expected only + or - operations for depend clauses.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 7636, __PRETTY_FUNCTION__)); | ||||||||
7637 | BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; | ||||||||
7638 | Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); | ||||||||
7639 | if (!Cnt) | ||||||||
7640 | return nullptr; | ||||||||
7641 | } | ||||||||
7642 | QualType VarType = LCDecl->getType().getNonReferenceType(); | ||||||||
7643 | if (!VarType->isIntegerType() && !VarType->isPointerType() && | ||||||||
7644 | !SemaRef.getLangOpts().CPlusPlus) | ||||||||
7645 | return nullptr; | ||||||||
7646 | // Upper - Lower | ||||||||
7647 | Expr *Upper = TestIsLessOp.getValue() | ||||||||
7648 | ? Cnt | ||||||||
7649 | : tryBuildCapture(SemaRef, LB, Captures).get(); | ||||||||
7650 | Expr *Lower = TestIsLessOp.getValue() | ||||||||
7651 | ? tryBuildCapture(SemaRef, LB, Captures).get() | ||||||||
7652 | : Cnt; | ||||||||
7653 | if (!Upper || !Lower) | ||||||||
7654 | return nullptr; | ||||||||
7655 | |||||||||
7656 | ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, | ||||||||
7657 | Step, VarType, /*TestIsStrictOp=*/false, | ||||||||
7658 | /*RoundToStep=*/false, Captures); | ||||||||
7659 | if (!Diff.isUsable()) | ||||||||
7660 | return nullptr; | ||||||||
7661 | |||||||||
7662 | return Diff.get(); | ||||||||
7663 | } | ||||||||
7664 | } // namespace | ||||||||
7665 | |||||||||
7666 | void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { | ||||||||
7667 | assert(getLangOpts().OpenMP && "OpenMP is not active.")((getLangOpts().OpenMP && "OpenMP is not active.") ? static_cast <void> (0) : __assert_fail ("getLangOpts().OpenMP && \"OpenMP is not active.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 7667, __PRETTY_FUNCTION__)); | ||||||||
7668 | assert(Init && "Expected loop in canonical form.")((Init && "Expected loop in canonical form.") ? static_cast <void> (0) : __assert_fail ("Init && \"Expected loop in canonical form.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 7668, __PRETTY_FUNCTION__)); | ||||||||
7669 | unsigned AssociatedLoops = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getAssociatedLoops(); | ||||||||
7670 | if (AssociatedLoops > 0 && | ||||||||
7671 | isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective())) { | ||||||||
7672 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->loopStart(); | ||||||||
7673 | OpenMPIterationSpaceChecker ISC(*this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), ForLoc); | ||||||||
7674 | if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { | ||||||||
7675 | if (ValueDecl *D = ISC.getLoopDecl()) { | ||||||||
7676 | auto *VD = dyn_cast<VarDecl>(D); | ||||||||
7677 | DeclRefExpr *PrivateRef = nullptr; | ||||||||
7678 | if (!VD) { | ||||||||
7679 | if (VarDecl *Private = isOpenMPCapturedDecl(D)) { | ||||||||
7680 | VD = Private; | ||||||||
7681 | } else { | ||||||||
7682 | PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), | ||||||||
7683 | /*WithInit=*/false); | ||||||||
7684 | VD = cast<VarDecl>(PrivateRef->getDecl()); | ||||||||
7685 | } | ||||||||
7686 | } | ||||||||
7687 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addLoopControlVariable(D, VD); | ||||||||
7688 | const Decl *LD = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getPossiblyLoopCunter(); | ||||||||
7689 | if (LD != D->getCanonicalDecl()) { | ||||||||
7690 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->resetPossibleLoopCounter(); | ||||||||
7691 | if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) | ||||||||
7692 | MarkDeclarationsReferencedInExpr( | ||||||||
7693 | buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), | ||||||||
7694 | Var->getType().getNonLValueExprType(Context), | ||||||||
7695 | ForLoc, /*RefersToCapture=*/true)); | ||||||||
7696 | } | ||||||||
7697 | OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); | ||||||||
7698 | // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables | ||||||||
7699 | // Referenced in a Construct, C/C++]. The loop iteration variable in the | ||||||||
7700 | // associated for-loop of a simd construct with just one associated | ||||||||
7701 | // for-loop may be listed in a linear clause with a constant-linear-step | ||||||||
7702 | // that is the increment of the associated for-loop. The loop iteration | ||||||||
7703 | // variable(s) in the associated for-loop(s) of a for or parallel for | ||||||||
7704 | // construct may be listed in a private or lastprivate clause. | ||||||||
7705 | DSAStackTy::DSAVarData DVar = | ||||||||
7706 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); | ||||||||
7707 | // If LoopVarRefExpr is nullptr it means the corresponding loop variable | ||||||||
7708 | // is declared in the loop and it is predetermined as a private. | ||||||||
7709 | Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); | ||||||||
7710 | OpenMPClauseKind PredeterminedCKind = | ||||||||
7711 | isOpenMPSimdDirective(DKind) | ||||||||
7712 | ? (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) | ||||||||
7713 | : OMPC_private; | ||||||||
7714 | if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && | ||||||||
7715 | DVar.CKind != PredeterminedCKind && DVar.RefExpr && | ||||||||
7716 | (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && | ||||||||
7717 | DVar.CKind != OMPC_private))) || | ||||||||
7718 | ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || | ||||||||
7719 | DKind == OMPD_master_taskloop || | ||||||||
7720 | DKind == OMPD_parallel_master_taskloop || | ||||||||
7721 | isOpenMPDistributeDirective(DKind)) && | ||||||||
7722 | !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && | ||||||||
7723 | DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && | ||||||||
7724 | (DVar.CKind != OMPC_private || DVar.RefExpr)) { | ||||||||
7725 | Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) | ||||||||
7726 | << getOpenMPClauseName(DVar.CKind) | ||||||||
7727 | << getOpenMPDirectiveName(DKind) | ||||||||
7728 | << getOpenMPClauseName(PredeterminedCKind); | ||||||||
7729 | if (DVar.RefExpr == nullptr) | ||||||||
7730 | DVar.CKind = PredeterminedCKind; | ||||||||
7731 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar, | ||||||||
7732 | /*IsLoopIterVar=*/true); | ||||||||
7733 | } else if (LoopDeclRefExpr) { | ||||||||
7734 | // Make the loop iteration variable private (for worksharing | ||||||||
7735 | // constructs), linear (for simd directives with the only one | ||||||||
7736 | // associated loop) or lastprivate (for simd directives with several | ||||||||
7737 | // collapsed or ordered loops). | ||||||||
7738 | if (DVar.CKind == OMPC_unknown) | ||||||||
7739 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, | ||||||||
7740 | PrivateRef); | ||||||||
7741 | } | ||||||||
7742 | } | ||||||||
7743 | } | ||||||||
7744 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setAssociatedLoops(AssociatedLoops - 1); | ||||||||
7745 | } | ||||||||
7746 | } | ||||||||
7747 | |||||||||
7748 | /// Called on a for stmt to check and extract its iteration space | ||||||||
7749 | /// for further processing (such as collapsing). | ||||||||
7750 | static bool checkOpenMPIterationSpace( | ||||||||
7751 | OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, | ||||||||
7752 | unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, | ||||||||
7753 | unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, | ||||||||
7754 | Expr *OrderedLoopCountExpr, | ||||||||
7755 | Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, | ||||||||
7756 | llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, | ||||||||
7757 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { | ||||||||
7758 | // OpenMP [2.9.1, Canonical Loop Form] | ||||||||
7759 | // for (init-expr; test-expr; incr-expr) structured-block | ||||||||
7760 | // for (range-decl: range-expr) structured-block | ||||||||
7761 | auto *For = dyn_cast_or_null<ForStmt>(S); | ||||||||
7762 | auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); | ||||||||
7763 | // Ranged for is supported only in OpenMP 5.0. | ||||||||
7764 | if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { | ||||||||
7765 | SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) | ||||||||
7766 | << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) | ||||||||
7767 | << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount | ||||||||
7768 | << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; | ||||||||
7769 | if (TotalNestedLoopCount > 1) { | ||||||||
7770 | if (CollapseLoopCountExpr && OrderedLoopCountExpr) | ||||||||
7771 | SemaRef.Diag(DSA.getConstructLoc(), | ||||||||
7772 | diag::note_omp_collapse_ordered_expr) | ||||||||
7773 | << 2 << CollapseLoopCountExpr->getSourceRange() | ||||||||
7774 | << OrderedLoopCountExpr->getSourceRange(); | ||||||||
7775 | else if (CollapseLoopCountExpr) | ||||||||
7776 | SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), | ||||||||
7777 | diag::note_omp_collapse_ordered_expr) | ||||||||
7778 | << 0 << CollapseLoopCountExpr->getSourceRange(); | ||||||||
7779 | else | ||||||||
7780 | SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), | ||||||||
7781 | diag::note_omp_collapse_ordered_expr) | ||||||||
7782 | << 1 << OrderedLoopCountExpr->getSourceRange(); | ||||||||
7783 | } | ||||||||
7784 | return true; | ||||||||
7785 | } | ||||||||
7786 | assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&((((For && For->getBody()) || (CXXFor && CXXFor ->getBody())) && "No loop body.") ? static_cast< void> (0) : __assert_fail ("((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && \"No loop body.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 7787, __PRETTY_FUNCTION__)) | ||||||||
7787 | "No loop body.")((((For && For->getBody()) || (CXXFor && CXXFor ->getBody())) && "No loop body.") ? static_cast< void> (0) : __assert_fail ("((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && \"No loop body.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 7787, __PRETTY_FUNCTION__)); | ||||||||
7788 | |||||||||
7789 | OpenMPIterationSpaceChecker ISC(SemaRef, DSA, | ||||||||
7790 | For ? For->getForLoc() : CXXFor->getForLoc()); | ||||||||
7791 | |||||||||
7792 | // Check init. | ||||||||
7793 | Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); | ||||||||
7794 | if (ISC.checkAndSetInit(Init)) | ||||||||
7795 | return true; | ||||||||
7796 | |||||||||
7797 | bool HasErrors = false; | ||||||||
7798 | |||||||||
7799 | // Check loop variable's type. | ||||||||
7800 | if (ValueDecl *LCDecl = ISC.getLoopDecl()) { | ||||||||
7801 | // OpenMP [2.6, Canonical Loop Form] | ||||||||
7802 | // Var is one of the following: | ||||||||
7803 | // A variable of signed or unsigned integer type. | ||||||||
7804 | // For C++, a variable of a random access iterator type. | ||||||||
7805 | // For C, a variable of a pointer type. | ||||||||
7806 | QualType VarType = LCDecl->getType().getNonReferenceType(); | ||||||||
7807 | if (!VarType->isDependentType() && !VarType->isIntegerType() && | ||||||||
7808 | !VarType->isPointerType() && | ||||||||
7809 | !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { | ||||||||
7810 | SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) | ||||||||
7811 | << SemaRef.getLangOpts().CPlusPlus; | ||||||||
7812 | HasErrors = true; | ||||||||
7813 | } | ||||||||
7814 | |||||||||
7815 | // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in | ||||||||
7816 | // a Construct | ||||||||
7817 | // The loop iteration variable(s) in the associated for-loop(s) of a for or | ||||||||
7818 | // parallel for construct is (are) private. | ||||||||
7819 | // The loop iteration variable in the associated for-loop of a simd | ||||||||
7820 | // construct with just one associated for-loop is linear with a | ||||||||
7821 | // constant-linear-step that is the increment of the associated for-loop. | ||||||||
7822 | // Exclude loop var from the list of variables with implicitly defined data | ||||||||
7823 | // sharing attributes. | ||||||||
7824 | VarsWithImplicitDSA.erase(LCDecl); | ||||||||
7825 | |||||||||
7826 | assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars")((isOpenMPLoopDirective(DKind) && "DSA for non-loop vars" ) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(DKind) && \"DSA for non-loop vars\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 7826, __PRETTY_FUNCTION__)); | ||||||||
7827 | |||||||||
7828 | // Check test-expr. | ||||||||
7829 | HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); | ||||||||
7830 | |||||||||
7831 | // Check incr-expr. | ||||||||
7832 | HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); | ||||||||
7833 | } | ||||||||
7834 | |||||||||
7835 | if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) | ||||||||
7836 | return HasErrors; | ||||||||
7837 | |||||||||
7838 | // Build the loop's iteration space representation. | ||||||||
7839 | ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( | ||||||||
7840 | DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); | ||||||||
7841 | ResultIterSpaces[CurrentNestedLoopCount].NumIterations = | ||||||||
7842 | ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, | ||||||||
7843 | (isOpenMPWorksharingDirective(DKind) || | ||||||||
7844 | isOpenMPTaskLoopDirective(DKind) || | ||||||||
7845 | isOpenMPDistributeDirective(DKind)), | ||||||||
7846 | Captures); | ||||||||
7847 | ResultIterSpaces[CurrentNestedLoopCount].CounterVar = | ||||||||
7848 | ISC.buildCounterVar(Captures, DSA); | ||||||||
7849 | ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = | ||||||||
7850 | ISC.buildPrivateCounterVar(); | ||||||||
7851 | ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); | ||||||||
7852 | ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); | ||||||||
7853 | ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); | ||||||||
7854 | ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = | ||||||||
7855 | ISC.getConditionSrcRange(); | ||||||||
7856 | ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = | ||||||||
7857 | ISC.getIncrementSrcRange(); | ||||||||
7858 | ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); | ||||||||
7859 | ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = | ||||||||
7860 | ISC.isStrictTestOp(); | ||||||||
7861 | std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, | ||||||||
7862 | ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = | ||||||||
7863 | ISC.buildMinMaxValues(DSA.getCurScope(), Captures); | ||||||||
7864 | ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = | ||||||||
7865 | ISC.buildFinalCondition(DSA.getCurScope()); | ||||||||
7866 | ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = | ||||||||
7867 | ISC.doesInitDependOnLC(); | ||||||||
7868 | ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = | ||||||||
7869 | ISC.doesCondDependOnLC(); | ||||||||
7870 | ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = | ||||||||
7871 | ISC.getLoopDependentIdx(); | ||||||||
7872 | |||||||||
7873 | HasErrors |= | ||||||||
7874 | (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || | ||||||||
7875 | ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || | ||||||||
7876 | ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || | ||||||||
7877 | ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || | ||||||||
7878 | ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || | ||||||||
7879 | ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); | ||||||||
7880 | if (!HasErrors && DSA.isOrderedRegion()) { | ||||||||
7881 | if (DSA.getOrderedRegionParam().second->getNumForLoops()) { | ||||||||
7882 | if (CurrentNestedLoopCount < | ||||||||
7883 | DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { | ||||||||
7884 | DSA.getOrderedRegionParam().second->setLoopNumIterations( | ||||||||
7885 | CurrentNestedLoopCount, | ||||||||
7886 | ResultIterSpaces[CurrentNestedLoopCount].NumIterations); | ||||||||
7887 | DSA.getOrderedRegionParam().second->setLoopCounter( | ||||||||
7888 | CurrentNestedLoopCount, | ||||||||
7889 | ResultIterSpaces[CurrentNestedLoopCount].CounterVar); | ||||||||
7890 | } | ||||||||
7891 | } | ||||||||
7892 | for (auto &Pair : DSA.getDoacrossDependClauses()) { | ||||||||
7893 | if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { | ||||||||
7894 | // Erroneous case - clause has some problems. | ||||||||
7895 | continue; | ||||||||
7896 | } | ||||||||
7897 | if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && | ||||||||
7898 | Pair.second.size() <= CurrentNestedLoopCount) { | ||||||||
7899 | // Erroneous case - clause has some problems. | ||||||||
7900 | Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); | ||||||||
7901 | continue; | ||||||||
7902 | } | ||||||||
7903 | Expr *CntValue; | ||||||||
7904 | if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) | ||||||||
7905 | CntValue = ISC.buildOrderedLoopData( | ||||||||
7906 | DSA.getCurScope(), | ||||||||
7907 | ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, | ||||||||
7908 | Pair.first->getDependencyLoc()); | ||||||||
7909 | else | ||||||||
7910 | CntValue = ISC.buildOrderedLoopData( | ||||||||
7911 | DSA.getCurScope(), | ||||||||
7912 | ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, | ||||||||
7913 | Pair.first->getDependencyLoc(), | ||||||||
7914 | Pair.second[CurrentNestedLoopCount].first, | ||||||||
7915 | Pair.second[CurrentNestedLoopCount].second); | ||||||||
7916 | Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); | ||||||||
7917 | } | ||||||||
7918 | } | ||||||||
7919 | |||||||||
7920 | return HasErrors; | ||||||||
7921 | } | ||||||||
7922 | |||||||||
7923 | /// Build 'VarRef = Start. | ||||||||
7924 | static ExprResult | ||||||||
7925 | buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, | ||||||||
7926 | ExprResult Start, bool IsNonRectangularLB, | ||||||||
7927 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { | ||||||||
7928 | // Build 'VarRef = Start. | ||||||||
7929 | ExprResult NewStart = IsNonRectangularLB | ||||||||
7930 | ? Start.get() | ||||||||
7931 | : tryBuildCapture(SemaRef, Start.get(), Captures); | ||||||||
7932 | if (!NewStart.isUsable()) | ||||||||
7933 | return ExprError(); | ||||||||
7934 | if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), | ||||||||
7935 | VarRef.get()->getType())) { | ||||||||
7936 | NewStart = SemaRef.PerformImplicitConversion( | ||||||||
7937 | NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, | ||||||||
7938 | /*AllowExplicit=*/true); | ||||||||
7939 | if (!NewStart.isUsable()) | ||||||||
7940 | return ExprError(); | ||||||||
7941 | } | ||||||||
7942 | |||||||||
7943 | ExprResult Init = | ||||||||
7944 | SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); | ||||||||
7945 | return Init; | ||||||||
7946 | } | ||||||||
7947 | |||||||||
7948 | /// Build 'VarRef = Start + Iter * Step'. | ||||||||
7949 | static ExprResult buildCounterUpdate( | ||||||||
7950 | Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, | ||||||||
7951 | ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, | ||||||||
7952 | bool IsNonRectangularLB, | ||||||||
7953 | llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { | ||||||||
7954 | // Add parentheses (for debugging purposes only). | ||||||||
7955 | Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); | ||||||||
7956 | if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || | ||||||||
7957 | !Step.isUsable()) | ||||||||
7958 | return ExprError(); | ||||||||
7959 | |||||||||
7960 | ExprResult NewStep = Step; | ||||||||
7961 | if (Captures) | ||||||||
7962 | NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); | ||||||||
7963 | if (NewStep.isInvalid()) | ||||||||
7964 | return ExprError(); | ||||||||
7965 | ExprResult Update = | ||||||||
7966 | SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); | ||||||||
7967 | if (!Update.isUsable()) | ||||||||
7968 | return ExprError(); | ||||||||
7969 | |||||||||
7970 | // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or | ||||||||
7971 | // 'VarRef = Start (+|-) Iter * Step'. | ||||||||
7972 | if (!Start.isUsable()) | ||||||||
7973 | return ExprError(); | ||||||||
7974 | ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); | ||||||||
7975 | if (!NewStart.isUsable()) | ||||||||
7976 | return ExprError(); | ||||||||
7977 | if (Captures && !IsNonRectangularLB) | ||||||||
7978 | NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); | ||||||||
7979 | if (NewStart.isInvalid()) | ||||||||
7980 | return ExprError(); | ||||||||
7981 | |||||||||
7982 | // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. | ||||||||
7983 | ExprResult SavedUpdate = Update; | ||||||||
7984 | ExprResult UpdateVal; | ||||||||
7985 | if (VarRef.get()->getType()->isOverloadableType() || | ||||||||
7986 | NewStart.get()->getType()->isOverloadableType() || | ||||||||
7987 | Update.get()->getType()->isOverloadableType()) { | ||||||||
7988 | Sema::TentativeAnalysisScope Trap(SemaRef); | ||||||||
7989 | |||||||||
7990 | Update = | ||||||||
7991 | SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); | ||||||||
7992 | if (Update.isUsable()) { | ||||||||
7993 | UpdateVal = | ||||||||
7994 | SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, | ||||||||
7995 | VarRef.get(), SavedUpdate.get()); | ||||||||
7996 | if (UpdateVal.isUsable()) { | ||||||||
7997 | Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), | ||||||||
7998 | UpdateVal.get()); | ||||||||
7999 | } | ||||||||
8000 | } | ||||||||
8001 | } | ||||||||
8002 | |||||||||
8003 | // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. | ||||||||
8004 | if (!Update.isUsable() || !UpdateVal.isUsable()) { | ||||||||
8005 | Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, | ||||||||
8006 | NewStart.get(), SavedUpdate.get()); | ||||||||
8007 | if (!Update.isUsable()) | ||||||||
8008 | return ExprError(); | ||||||||
8009 | |||||||||
8010 | if (!SemaRef.Context.hasSameType(Update.get()->getType(), | ||||||||
8011 | VarRef.get()->getType())) { | ||||||||
8012 | Update = SemaRef.PerformImplicitConversion( | ||||||||
8013 | Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); | ||||||||
8014 | if (!Update.isUsable()) | ||||||||
8015 | return ExprError(); | ||||||||
8016 | } | ||||||||
8017 | |||||||||
8018 | Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); | ||||||||
8019 | } | ||||||||
8020 | return Update; | ||||||||
8021 | } | ||||||||
8022 | |||||||||
8023 | /// Convert integer expression \a E to make it have at least \a Bits | ||||||||
8024 | /// bits. | ||||||||
8025 | static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { | ||||||||
8026 | if (E == nullptr) | ||||||||
8027 | return ExprError(); | ||||||||
8028 | ASTContext &C = SemaRef.Context; | ||||||||
8029 | QualType OldType = E->getType(); | ||||||||
8030 | unsigned HasBits = C.getTypeSize(OldType); | ||||||||
8031 | if (HasBits >= Bits) | ||||||||
8032 | return ExprResult(E); | ||||||||
8033 | // OK to convert to signed, because new type has more bits than old. | ||||||||
8034 | QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); | ||||||||
8035 | return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, | ||||||||
8036 | true); | ||||||||
8037 | } | ||||||||
8038 | |||||||||
8039 | /// Check if the given expression \a E is a constant integer that fits | ||||||||
8040 | /// into \a Bits bits. | ||||||||
8041 | static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { | ||||||||
8042 | if (E == nullptr) | ||||||||
8043 | return false; | ||||||||
8044 | if (Optional<llvm::APSInt> Result = | ||||||||
8045 | E->getIntegerConstantExpr(SemaRef.Context)) | ||||||||
8046 | return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits); | ||||||||
8047 | return false; | ||||||||
8048 | } | ||||||||
8049 | |||||||||
8050 | /// Build preinits statement for the given declarations. | ||||||||
8051 | static Stmt *buildPreInits(ASTContext &Context, | ||||||||
8052 | MutableArrayRef<Decl *> PreInits) { | ||||||||
8053 | if (!PreInits.empty()) { | ||||||||
8054 | return new (Context) DeclStmt( | ||||||||
8055 | DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), | ||||||||
8056 | SourceLocation(), SourceLocation()); | ||||||||
8057 | } | ||||||||
8058 | return nullptr; | ||||||||
8059 | } | ||||||||
8060 | |||||||||
8061 | /// Build preinits statement for the given declarations. | ||||||||
8062 | static Stmt * | ||||||||
8063 | buildPreInits(ASTContext &Context, | ||||||||
8064 | const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { | ||||||||
8065 | if (!Captures.empty()) { | ||||||||
8066 | SmallVector<Decl *, 16> PreInits; | ||||||||
8067 | for (const auto &Pair : Captures) | ||||||||
8068 | PreInits.push_back(Pair.second->getDecl()); | ||||||||
8069 | return buildPreInits(Context, PreInits); | ||||||||
8070 | } | ||||||||
8071 | return nullptr; | ||||||||
8072 | } | ||||||||
8073 | |||||||||
8074 | /// Build postupdate expression for the given list of postupdates expressions. | ||||||||
8075 | static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { | ||||||||
8076 | Expr *PostUpdate = nullptr; | ||||||||
8077 | if (!PostUpdates.empty()) { | ||||||||
8078 | for (Expr *E : PostUpdates) { | ||||||||
8079 | Expr *ConvE = S.BuildCStyleCastExpr( | ||||||||
8080 | E->getExprLoc(), | ||||||||
8081 | S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), | ||||||||
8082 | E->getExprLoc(), E) | ||||||||
8083 | .get(); | ||||||||
8084 | PostUpdate = PostUpdate | ||||||||
8085 | ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, | ||||||||
8086 | PostUpdate, ConvE) | ||||||||
8087 | .get() | ||||||||
8088 | : ConvE; | ||||||||
8089 | } | ||||||||
8090 | } | ||||||||
8091 | return PostUpdate; | ||||||||
8092 | } | ||||||||
8093 | |||||||||
8094 | /// Called on a for stmt to check itself and nested loops (if any). | ||||||||
8095 | /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, | ||||||||
8096 | /// number of collapsed loops otherwise. | ||||||||
8097 | static unsigned | ||||||||
8098 | checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, | ||||||||
8099 | Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, | ||||||||
8100 | DSAStackTy &DSA, | ||||||||
8101 | Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, | ||||||||
8102 | OMPLoopDirective::HelperExprs &Built) { | ||||||||
8103 | unsigned NestedLoopCount = 1; | ||||||||
8104 | if (CollapseLoopCountExpr) { | ||||||||
8105 | // Found 'collapse' clause - calculate collapse number. | ||||||||
8106 | Expr::EvalResult Result; | ||||||||
8107 | if (!CollapseLoopCountExpr->isValueDependent() && | ||||||||
8108 | CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { | ||||||||
8109 | NestedLoopCount = Result.Val.getInt().getLimitedValue(); | ||||||||
8110 | } else { | ||||||||
8111 | Built.clear(/*Size=*/1); | ||||||||
8112 | return 1; | ||||||||
8113 | } | ||||||||
8114 | } | ||||||||
8115 | unsigned OrderedLoopCount = 1; | ||||||||
8116 | if (OrderedLoopCountExpr) { | ||||||||
8117 | // Found 'ordered' clause - calculate collapse number. | ||||||||
8118 | Expr::EvalResult EVResult; | ||||||||
8119 | if (!OrderedLoopCountExpr->isValueDependent() && | ||||||||
8120 | OrderedLoopCountExpr->EvaluateAsInt(EVResult, | ||||||||
8121 | SemaRef.getASTContext())) { | ||||||||
8122 | llvm::APSInt Result = EVResult.Val.getInt(); | ||||||||
8123 | if (Result.getLimitedValue() < NestedLoopCount) { | ||||||||
8124 | SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), | ||||||||
8125 | diag::err_omp_wrong_ordered_loop_count) | ||||||||
8126 | << OrderedLoopCountExpr->getSourceRange(); | ||||||||
8127 | SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), | ||||||||
8128 | diag::note_collapse_loop_count) | ||||||||
8129 | << CollapseLoopCountExpr->getSourceRange(); | ||||||||
8130 | } | ||||||||
8131 | OrderedLoopCount = Result.getLimitedValue(); | ||||||||
8132 | } else { | ||||||||
8133 | Built.clear(/*Size=*/1); | ||||||||
8134 | return 1; | ||||||||
8135 | } | ||||||||
8136 | } | ||||||||
8137 | // This is helper routine for loop directives (e.g., 'for', 'simd', | ||||||||
8138 | // 'for simd', etc.). | ||||||||
8139 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; | ||||||||
8140 | SmallVector<LoopIterationSpace, 4> IterSpaces( | ||||||||
8141 | std::max(OrderedLoopCount, NestedLoopCount)); | ||||||||
8142 | Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); | ||||||||
8143 | for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { | ||||||||
8144 | if (checkOpenMPIterationSpace( | ||||||||
8145 | DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, | ||||||||
8146 | std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, | ||||||||
8147 | OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) | ||||||||
8148 | return 0; | ||||||||
8149 | // Move on to the next nested for loop, or to the loop body. | ||||||||
8150 | // OpenMP [2.8.1, simd construct, Restrictions] | ||||||||
8151 | // All loops associated with the construct must be perfectly nested; that | ||||||||
8152 | // is, there must be no intervening code nor any OpenMP directive between | ||||||||
8153 | // any two loops. | ||||||||
8154 | if (auto *For = dyn_cast<ForStmt>(CurStmt)) { | ||||||||
8155 | CurStmt = For->getBody(); | ||||||||
8156 | } else { | ||||||||
8157 | assert(isa<CXXForRangeStmt>(CurStmt) &&((isa<CXXForRangeStmt>(CurStmt) && "Expected canonical for or range-based for loops." ) ? static_cast<void> (0) : __assert_fail ("isa<CXXForRangeStmt>(CurStmt) && \"Expected canonical for or range-based for loops.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 8158, __PRETTY_FUNCTION__)) | ||||||||
8158 | "Expected canonical for or range-based for loops.")((isa<CXXForRangeStmt>(CurStmt) && "Expected canonical for or range-based for loops." ) ? static_cast<void> (0) : __assert_fail ("isa<CXXForRangeStmt>(CurStmt) && \"Expected canonical for or range-based for loops.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 8158, __PRETTY_FUNCTION__)); | ||||||||
8159 | CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); | ||||||||
8160 | } | ||||||||
8161 | CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( | ||||||||
8162 | CurStmt, SemaRef.LangOpts.OpenMP >= 50); | ||||||||
8163 | } | ||||||||
8164 | for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { | ||||||||
8165 | if (checkOpenMPIterationSpace( | ||||||||
8166 | DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, | ||||||||
8167 | std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, | ||||||||
8168 | OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) | ||||||||
8169 | return 0; | ||||||||
8170 | if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { | ||||||||
8171 | // Handle initialization of captured loop iterator variables. | ||||||||
8172 | auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); | ||||||||
8173 | if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { | ||||||||
8174 | Captures[DRE] = DRE; | ||||||||
8175 | } | ||||||||
8176 | } | ||||||||
8177 | // Move on to the next nested for loop, or to the loop body. | ||||||||
8178 | // OpenMP [2.8.1, simd construct, Restrictions] | ||||||||
8179 | // All loops associated with the construct must be perfectly nested; that | ||||||||
8180 | // is, there must be no intervening code nor any OpenMP directive between | ||||||||
8181 | // any two loops. | ||||||||
8182 | if (auto *For = dyn_cast<ForStmt>(CurStmt)) { | ||||||||
8183 | CurStmt = For->getBody(); | ||||||||
8184 | } else { | ||||||||
8185 | assert(isa<CXXForRangeStmt>(CurStmt) &&((isa<CXXForRangeStmt>(CurStmt) && "Expected canonical for or range-based for loops." ) ? static_cast<void> (0) : __assert_fail ("isa<CXXForRangeStmt>(CurStmt) && \"Expected canonical for or range-based for loops.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 8186, __PRETTY_FUNCTION__)) | ||||||||
8186 | "Expected canonical for or range-based for loops.")((isa<CXXForRangeStmt>(CurStmt) && "Expected canonical for or range-based for loops." ) ? static_cast<void> (0) : __assert_fail ("isa<CXXForRangeStmt>(CurStmt) && \"Expected canonical for or range-based for loops.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 8186, __PRETTY_FUNCTION__)); | ||||||||
8187 | CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); | ||||||||
8188 | } | ||||||||
8189 | CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( | ||||||||
8190 | CurStmt, SemaRef.LangOpts.OpenMP >= 50); | ||||||||
8191 | } | ||||||||
8192 | |||||||||
8193 | Built.clear(/* size */ NestedLoopCount); | ||||||||
8194 | |||||||||
8195 | if (SemaRef.CurContext->isDependentContext()) | ||||||||
8196 | return NestedLoopCount; | ||||||||
8197 | |||||||||
8198 | // An example of what is generated for the following code: | ||||||||
8199 | // | ||||||||
8200 | // #pragma omp simd collapse(2) ordered(2) | ||||||||
8201 | // for (i = 0; i < NI; ++i) | ||||||||
8202 | // for (k = 0; k < NK; ++k) | ||||||||
8203 | // for (j = J0; j < NJ; j+=2) { | ||||||||
8204 | // <loop body> | ||||||||
8205 | // } | ||||||||
8206 | // | ||||||||
8207 | // We generate the code below. | ||||||||
8208 | // Note: the loop body may be outlined in CodeGen. | ||||||||
8209 | // Note: some counters may be C++ classes, operator- is used to find number of | ||||||||
8210 | // iterations and operator+= to calculate counter value. | ||||||||
8211 | // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 | ||||||||
8212 | // or i64 is currently supported). | ||||||||
8213 | // | ||||||||
8214 | // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) | ||||||||
8215 | // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { | ||||||||
8216 | // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); | ||||||||
8217 | // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; | ||||||||
8218 | // // similar updates for vars in clauses (e.g. 'linear') | ||||||||
8219 | // <loop body (using local i and j)> | ||||||||
8220 | // } | ||||||||
8221 | // i = NI; // assign final values of counters | ||||||||
8222 | // j = NJ; | ||||||||
8223 | // | ||||||||
8224 | |||||||||
8225 | // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are | ||||||||
8226 | // the iteration counts of the collapsed for loops. | ||||||||
8227 | // Precondition tests if there is at least one iteration (all conditions are | ||||||||
8228 | // true). | ||||||||
8229 | auto PreCond = ExprResult(IterSpaces[0].PreCond); | ||||||||
8230 | Expr *N0 = IterSpaces[0].NumIterations; | ||||||||
8231 | ExprResult LastIteration32 = | ||||||||
8232 | widenIterationCount(/*Bits=*/32, | ||||||||
8233 | SemaRef | ||||||||
8234 | .PerformImplicitConversion( | ||||||||
8235 | N0->IgnoreImpCasts(), N0->getType(), | ||||||||
8236 | Sema::AA_Converting, /*AllowExplicit=*/true) | ||||||||
8237 | .get(), | ||||||||
8238 | SemaRef); | ||||||||
8239 | ExprResult LastIteration64 = widenIterationCount( | ||||||||
8240 | /*Bits=*/64, | ||||||||
8241 | SemaRef | ||||||||
8242 | .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), | ||||||||
8243 | Sema::AA_Converting, | ||||||||
8244 | /*AllowExplicit=*/true) | ||||||||
8245 | .get(), | ||||||||
8246 | SemaRef); | ||||||||
8247 | |||||||||
8248 | if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) | ||||||||
8249 | return NestedLoopCount; | ||||||||
8250 | |||||||||
8251 | ASTContext &C = SemaRef.Context; | ||||||||
8252 | bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; | ||||||||
8253 | |||||||||
8254 | Scope *CurScope = DSA.getCurScope(); | ||||||||
8255 | for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { | ||||||||
8256 | if (PreCond.isUsable()) { | ||||||||
8257 | PreCond = | ||||||||
8258 | SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, | ||||||||
8259 | PreCond.get(), IterSpaces[Cnt].PreCond); | ||||||||
8260 | } | ||||||||
8261 | Expr *N = IterSpaces[Cnt].NumIterations; | ||||||||
8262 | SourceLocation Loc = N->getExprLoc(); | ||||||||
8263 | AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; | ||||||||
8264 | if (LastIteration32.isUsable()) | ||||||||
8265 | LastIteration32 = SemaRef.BuildBinOp( | ||||||||
8266 | CurScope, Loc, BO_Mul, LastIteration32.get(), | ||||||||
8267 | SemaRef | ||||||||
8268 | .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), | ||||||||
8269 | Sema::AA_Converting, | ||||||||
8270 | /*AllowExplicit=*/true) | ||||||||
8271 | .get()); | ||||||||
8272 | if (LastIteration64.isUsable()) | ||||||||
8273 | LastIteration64 = SemaRef.BuildBinOp( | ||||||||
8274 | CurScope, Loc, BO_Mul, LastIteration64.get(), | ||||||||
8275 | SemaRef | ||||||||
8276 | .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), | ||||||||
8277 | Sema::AA_Converting, | ||||||||
8278 | /*AllowExplicit=*/true) | ||||||||
8279 | .get()); | ||||||||
8280 | } | ||||||||
8281 | |||||||||
8282 | // Choose either the 32-bit or 64-bit version. | ||||||||
8283 | ExprResult LastIteration = LastIteration64; | ||||||||
8284 | if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || | ||||||||
8285 | (LastIteration32.isUsable() && | ||||||||
8286 | C.getTypeSize(LastIteration32.get()->getType()) == 32 && | ||||||||
8287 | (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || | ||||||||
8288 | fitsInto( | ||||||||
8289 | /*Bits=*/32, | ||||||||
8290 | LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), | ||||||||
8291 | LastIteration64.get(), SemaRef)))) | ||||||||
8292 | LastIteration = LastIteration32; | ||||||||
8293 | QualType VType = LastIteration.get()->getType(); | ||||||||
8294 | QualType RealVType = VType; | ||||||||
8295 | QualType StrideVType = VType; | ||||||||
8296 | if (isOpenMPTaskLoopDirective(DKind)) { | ||||||||
8297 | VType = | ||||||||
8298 | SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); | ||||||||
8299 | StrideVType = | ||||||||
8300 | SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); | ||||||||
8301 | } | ||||||||
8302 | |||||||||
8303 | if (!LastIteration.isUsable()) | ||||||||
8304 | return 0; | ||||||||
8305 | |||||||||
8306 | // Save the number of iterations. | ||||||||
8307 | ExprResult NumIterations = LastIteration; | ||||||||
8308 | { | ||||||||
8309 | LastIteration = SemaRef.BuildBinOp( | ||||||||
8310 | CurScope, LastIteration.get()->getExprLoc(), BO_Sub, | ||||||||
8311 | LastIteration.get(), | ||||||||
8312 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); | ||||||||
8313 | if (!LastIteration.isUsable()) | ||||||||
8314 | return 0; | ||||||||
8315 | } | ||||||||
8316 | |||||||||
8317 | // Calculate the last iteration number beforehand instead of doing this on | ||||||||
8318 | // each iteration. Do not do this if the number of iterations may be kfold-ed. | ||||||||
8319 | bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context); | ||||||||
8320 | ExprResult CalcLastIteration; | ||||||||
8321 | if (!IsConstant) { | ||||||||
8322 | ExprResult SaveRef = | ||||||||
8323 | tryBuildCapture(SemaRef, LastIteration.get(), Captures); | ||||||||
8324 | LastIteration = SaveRef; | ||||||||
8325 | |||||||||
8326 | // Prepare SaveRef + 1. | ||||||||
8327 | NumIterations = SemaRef.BuildBinOp( | ||||||||
8328 | CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), | ||||||||
8329 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); | ||||||||
8330 | if (!NumIterations.isUsable()) | ||||||||
8331 | return 0; | ||||||||
8332 | } | ||||||||
8333 | |||||||||
8334 | SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); | ||||||||
8335 | |||||||||
8336 | // Build variables passed into runtime, necessary for worksharing directives. | ||||||||
8337 | ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; | ||||||||
8338 | if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || | ||||||||
8339 | isOpenMPDistributeDirective(DKind)) { | ||||||||
8340 | // Lower bound variable, initialized with zero. | ||||||||
8341 | VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); | ||||||||
8342 | LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); | ||||||||
8343 | SemaRef.AddInitializerToDecl(LBDecl, | ||||||||
8344 | SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), | ||||||||
8345 | /*DirectInit*/ false); | ||||||||
8346 | |||||||||
8347 | // Upper bound variable, initialized with last iteration number. | ||||||||
8348 | VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); | ||||||||
8349 | UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); | ||||||||
8350 | SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), | ||||||||
8351 | /*DirectInit*/ false); | ||||||||
8352 | |||||||||
8353 | // A 32-bit variable-flag where runtime returns 1 for the last iteration. | ||||||||
8354 | // This will be used to implement clause 'lastprivate'. | ||||||||
8355 | QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); | ||||||||
8356 | VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); | ||||||||
8357 | IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); | ||||||||
8358 | SemaRef.AddInitializerToDecl(ILDecl, | ||||||||
8359 | SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), | ||||||||
8360 | /*DirectInit*/ false); | ||||||||
8361 | |||||||||
8362 | // Stride variable returned by runtime (we initialize it to 1 by default). | ||||||||
8363 | VarDecl *STDecl = | ||||||||
8364 | buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); | ||||||||
8365 | ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); | ||||||||
8366 | SemaRef.AddInitializerToDecl(STDecl, | ||||||||
8367 | SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), | ||||||||
8368 | /*DirectInit*/ false); | ||||||||
8369 | |||||||||
8370 | // Build expression: UB = min(UB, LastIteration) | ||||||||
8371 | // It is necessary for CodeGen of directives with static scheduling. | ||||||||
8372 | ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, | ||||||||
8373 | UB.get(), LastIteration.get()); | ||||||||
8374 | ExprResult CondOp = SemaRef.ActOnConditionalOp( | ||||||||
8375 | LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), | ||||||||
8376 | LastIteration.get(), UB.get()); | ||||||||
8377 | EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), | ||||||||
8378 | CondOp.get()); | ||||||||
8379 | EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); | ||||||||
8380 | |||||||||
8381 | // If we have a combined directive that combines 'distribute', 'for' or | ||||||||
8382 | // 'simd' we need to be able to access the bounds of the schedule of the | ||||||||
8383 | // enclosing region. E.g. in 'distribute parallel for' the bounds obtained | ||||||||
8384 | // by scheduling 'distribute' have to be passed to the schedule of 'for'. | ||||||||
8385 | if (isOpenMPLoopBoundSharingDirective(DKind)) { | ||||||||
8386 | // Lower bound variable, initialized with zero. | ||||||||
8387 | VarDecl *CombLBDecl = | ||||||||
8388 | buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); | ||||||||
8389 | CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); | ||||||||
8390 | SemaRef.AddInitializerToDecl( | ||||||||
8391 | CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), | ||||||||
8392 | /*DirectInit*/ false); | ||||||||
8393 | |||||||||
8394 | // Upper bound variable, initialized with last iteration number. | ||||||||
8395 | VarDecl *CombUBDecl = | ||||||||
8396 | buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); | ||||||||
8397 | CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); | ||||||||
8398 | SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), | ||||||||
8399 | /*DirectInit*/ false); | ||||||||
8400 | |||||||||
8401 | ExprResult CombIsUBGreater = SemaRef.BuildBinOp( | ||||||||
8402 | CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); | ||||||||
8403 | ExprResult CombCondOp = | ||||||||
8404 | SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), | ||||||||
8405 | LastIteration.get(), CombUB.get()); | ||||||||
8406 | CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), | ||||||||
8407 | CombCondOp.get()); | ||||||||
8408 | CombEUB = | ||||||||
8409 | SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); | ||||||||
8410 | |||||||||
8411 | const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); | ||||||||
8412 | // We expect to have at least 2 more parameters than the 'parallel' | ||||||||
8413 | // directive does - the lower and upper bounds of the previous schedule. | ||||||||
8414 | assert(CD->getNumParams() >= 4 &&((CD->getNumParams() >= 4 && "Unexpected number of parameters in loop combined directive" ) ? static_cast<void> (0) : __assert_fail ("CD->getNumParams() >= 4 && \"Unexpected number of parameters in loop combined directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 8415, __PRETTY_FUNCTION__)) | ||||||||
8415 | "Unexpected number of parameters in loop combined directive")((CD->getNumParams() >= 4 && "Unexpected number of parameters in loop combined directive" ) ? static_cast<void> (0) : __assert_fail ("CD->getNumParams() >= 4 && \"Unexpected number of parameters in loop combined directive\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 8415, __PRETTY_FUNCTION__)); | ||||||||
8416 | |||||||||
8417 | // Set the proper type for the bounds given what we learned from the | ||||||||
8418 | // enclosed loops. | ||||||||
8419 | ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); | ||||||||
8420 | ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); | ||||||||
8421 | |||||||||
8422 | // Previous lower and upper bounds are obtained from the region | ||||||||
8423 | // parameters. | ||||||||
8424 | PrevLB = | ||||||||
8425 | buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); | ||||||||
8426 | PrevUB = | ||||||||
8427 | buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); | ||||||||
8428 | } | ||||||||
8429 | } | ||||||||
8430 | |||||||||
8431 | // Build the iteration variable and its initialization before loop. | ||||||||
8432 | ExprResult IV; | ||||||||
8433 | ExprResult Init, CombInit; | ||||||||
8434 | { | ||||||||
8435 | VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); | ||||||||
8436 | IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); | ||||||||
8437 | Expr *RHS = | ||||||||
8438 | (isOpenMPWorksharingDirective(DKind) || | ||||||||
8439 | isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) | ||||||||
8440 | ? LB.get() | ||||||||
8441 | : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); | ||||||||
8442 | Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); | ||||||||
8443 | Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); | ||||||||
8444 | |||||||||
8445 | if (isOpenMPLoopBoundSharingDirective(DKind)) { | ||||||||
8446 | Expr *CombRHS = | ||||||||
8447 | (isOpenMPWorksharingDirective(DKind) || | ||||||||
8448 | isOpenMPTaskLoopDirective(DKind) || | ||||||||
8449 | isOpenMPDistributeDirective(DKind)) | ||||||||
8450 | ? CombLB.get() | ||||||||
8451 | : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); | ||||||||
8452 | CombInit = | ||||||||
8453 | SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); | ||||||||
8454 | CombInit = | ||||||||
8455 | SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); | ||||||||
8456 | } | ||||||||
8457 | } | ||||||||
8458 | |||||||||
8459 | bool UseStrictCompare = | ||||||||
8460 | RealVType->hasUnsignedIntegerRepresentation() && | ||||||||
8461 | llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { | ||||||||
8462 | return LIS.IsStrictCompare; | ||||||||
8463 | }); | ||||||||
8464 | // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for | ||||||||
8465 | // unsigned IV)) for worksharing loops. | ||||||||
8466 | SourceLocation CondLoc = AStmt->getBeginLoc(); | ||||||||
8467 | Expr *BoundUB = UB.get(); | ||||||||
8468 | if (UseStrictCompare) { | ||||||||
8469 | BoundUB = | ||||||||
8470 | SemaRef | ||||||||
8471 | .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, | ||||||||
8472 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) | ||||||||
8473 | .get(); | ||||||||
8474 | BoundUB = | ||||||||
8475 | SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); | ||||||||
8476 | } | ||||||||
8477 | ExprResult Cond = | ||||||||
8478 | (isOpenMPWorksharingDirective(DKind) || | ||||||||
8479 | isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) | ||||||||
8480 | ? SemaRef.BuildBinOp(CurScope, CondLoc, | ||||||||
8481 | UseStrictCompare ? BO_LT : BO_LE, IV.get(), | ||||||||
8482 | BoundUB) | ||||||||
8483 | : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), | ||||||||
8484 | NumIterations.get()); | ||||||||
8485 | ExprResult CombDistCond; | ||||||||
8486 | if (isOpenMPLoopBoundSharingDirective(DKind)) { | ||||||||
8487 | CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), | ||||||||
8488 | NumIterations.get()); | ||||||||
8489 | } | ||||||||
8490 | |||||||||
8491 | ExprResult CombCond; | ||||||||
8492 | if (isOpenMPLoopBoundSharingDirective(DKind)) { | ||||||||
8493 | Expr *BoundCombUB = CombUB.get(); | ||||||||
8494 | if (UseStrictCompare) { | ||||||||
8495 | BoundCombUB = | ||||||||
8496 | SemaRef | ||||||||
8497 | .BuildBinOp( | ||||||||
8498 | CurScope, CondLoc, BO_Add, BoundCombUB, | ||||||||
8499 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) | ||||||||
8500 | .get(); | ||||||||
8501 | BoundCombUB = | ||||||||
8502 | SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) | ||||||||
8503 | .get(); | ||||||||
8504 | } | ||||||||
8505 | CombCond = | ||||||||
8506 | SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, | ||||||||
8507 | IV.get(), BoundCombUB); | ||||||||
8508 | } | ||||||||
8509 | // Loop increment (IV = IV + 1) | ||||||||
8510 | SourceLocation IncLoc = AStmt->getBeginLoc(); | ||||||||
8511 | ExprResult Inc = | ||||||||
8512 | SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), | ||||||||
8513 | SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); | ||||||||
8514 | if (!Inc.isUsable()) | ||||||||
8515 | return 0; | ||||||||
8516 | Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); | ||||||||
8517 | Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); | ||||||||
8518 | if (!Inc.isUsable()) | ||||||||
8519 | return 0; | ||||||||
8520 | |||||||||
8521 | // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). | ||||||||
8522 | // Used for directives with static scheduling. | ||||||||
8523 | // In combined construct, add combined version that use CombLB and CombUB | ||||||||
8524 | // base variables for the update | ||||||||
8525 | ExprResult NextLB, NextUB, CombNextLB, CombNextUB; | ||||||||
8526 | if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || | ||||||||
8527 | isOpenMPDistributeDirective(DKind)) { | ||||||||
8528 | // LB + ST | ||||||||
8529 | NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); | ||||||||
8530 | if (!NextLB.isUsable()) | ||||||||
8531 | return 0; | ||||||||
8532 | // LB = LB + ST | ||||||||
8533 | NextLB = | ||||||||
8534 | SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); | ||||||||
8535 | NextLB = | ||||||||
8536 | SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); | ||||||||
8537 | if (!NextLB.isUsable()) | ||||||||
8538 | return 0; | ||||||||
8539 | // UB + ST | ||||||||
8540 | NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); | ||||||||
8541 | if (!NextUB.isUsable()) | ||||||||
8542 | return 0; | ||||||||
8543 | // UB = UB + ST | ||||||||
8544 | NextUB = | ||||||||
8545 | SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); | ||||||||
8546 | NextUB = | ||||||||
8547 | SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); | ||||||||
8548 | if (!NextUB.isUsable()) | ||||||||
8549 | return 0; | ||||||||
8550 | if (isOpenMPLoopBoundSharingDirective(DKind)) { | ||||||||
8551 | CombNextLB = | ||||||||
8552 | SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); | ||||||||
8553 | if (!NextLB.isUsable()) | ||||||||
8554 | return 0; | ||||||||
8555 | // LB = LB + ST | ||||||||
8556 | CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), | ||||||||
8557 | CombNextLB.get()); | ||||||||
8558 | CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), | ||||||||
8559 | /*DiscardedValue*/ false); | ||||||||
8560 | if (!CombNextLB.isUsable()) | ||||||||
8561 | return 0; | ||||||||
8562 | // UB + ST | ||||||||
8563 | CombNextUB = | ||||||||
8564 | SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); | ||||||||
8565 | if (!CombNextUB.isUsable()) | ||||||||
8566 | return 0; | ||||||||
8567 | // UB = UB + ST | ||||||||
8568 | CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), | ||||||||
8569 | CombNextUB.get()); | ||||||||
8570 | CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), | ||||||||
8571 | /*DiscardedValue*/ false); | ||||||||
8572 | if (!CombNextUB.isUsable()) | ||||||||
8573 | return 0; | ||||||||
8574 | } | ||||||||
8575 | } | ||||||||
8576 | |||||||||
8577 | // Create increment expression for distribute loop when combined in a same | ||||||||
8578 | // directive with for as IV = IV + ST; ensure upper bound expression based | ||||||||
8579 | // on PrevUB instead of NumIterations - used to implement 'for' when found | ||||||||
8580 | // in combination with 'distribute', like in 'distribute parallel for' | ||||||||
8581 | SourceLocation DistIncLoc = AStmt->getBeginLoc(); | ||||||||
8582 | ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; | ||||||||
8583 | if (isOpenMPLoopBoundSharingDirective(DKind)) { | ||||||||
8584 | DistCond = SemaRef.BuildBinOp( | ||||||||
8585 | CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); | ||||||||
8586 | assert(DistCond.isUsable() && "distribute cond expr was not built")((DistCond.isUsable() && "distribute cond expr was not built" ) ? static_cast<void> (0) : __assert_fail ("DistCond.isUsable() && \"distribute cond expr was not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 8586, __PRETTY_FUNCTION__)); | ||||||||
8587 | |||||||||
8588 | DistInc = | ||||||||
8589 | SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); | ||||||||
8590 | assert(DistInc.isUsable() && "distribute inc expr was not built")((DistInc.isUsable() && "distribute inc expr was not built" ) ? static_cast<void> (0) : __assert_fail ("DistInc.isUsable() && \"distribute inc expr was not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 8590, __PRETTY_FUNCTION__)); | ||||||||
8591 | DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), | ||||||||
8592 | DistInc.get()); | ||||||||
8593 | DistInc = | ||||||||
8594 | SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); | ||||||||
8595 | assert(DistInc.isUsable() && "distribute inc expr was not built")((DistInc.isUsable() && "distribute inc expr was not built" ) ? static_cast<void> (0) : __assert_fail ("DistInc.isUsable() && \"distribute inc expr was not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 8595, __PRETTY_FUNCTION__)); | ||||||||
8596 | |||||||||
8597 | // Build expression: UB = min(UB, prevUB) for #for in composite or combined | ||||||||
8598 | // construct | ||||||||
8599 | SourceLocation DistEUBLoc = AStmt->getBeginLoc(); | ||||||||
8600 | ExprResult IsUBGreater = | ||||||||
8601 | SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); | ||||||||
8602 | ExprResult CondOp = SemaRef.ActOnConditionalOp( | ||||||||
8603 | DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); | ||||||||
8604 | PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), | ||||||||
8605 | CondOp.get()); | ||||||||
8606 | PrevEUB = | ||||||||
8607 | SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); | ||||||||
8608 | |||||||||
8609 | // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in | ||||||||
8610 | // parallel for is in combination with a distribute directive with | ||||||||
8611 | // schedule(static, 1) | ||||||||
8612 | Expr *BoundPrevUB = PrevUB.get(); | ||||||||
8613 | if (UseStrictCompare) { | ||||||||
8614 | BoundPrevUB = | ||||||||
8615 | SemaRef | ||||||||
8616 | .BuildBinOp( | ||||||||
8617 | CurScope, CondLoc, BO_Add, BoundPrevUB, | ||||||||
8618 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) | ||||||||
8619 | .get(); | ||||||||
8620 | BoundPrevUB = | ||||||||
8621 | SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) | ||||||||
8622 | .get(); | ||||||||
8623 | } | ||||||||
8624 | ParForInDistCond = | ||||||||
8625 | SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, | ||||||||
8626 | IV.get(), BoundPrevUB); | ||||||||
8627 | } | ||||||||
8628 | |||||||||
8629 | // Build updates and final values of the loop counters. | ||||||||
8630 | bool HasErrors = false; | ||||||||
8631 | Built.Counters.resize(NestedLoopCount); | ||||||||
8632 | Built.Inits.resize(NestedLoopCount); | ||||||||
8633 | Built.Updates.resize(NestedLoopCount); | ||||||||
8634 | Built.Finals.resize(NestedLoopCount); | ||||||||
8635 | Built.DependentCounters.resize(NestedLoopCount); | ||||||||
8636 | Built.DependentInits.resize(NestedLoopCount); | ||||||||
8637 | Built.FinalsConditions.resize(NestedLoopCount); | ||||||||
8638 | { | ||||||||
8639 | // We implement the following algorithm for obtaining the | ||||||||
8640 | // original loop iteration variable values based on the | ||||||||
8641 | // value of the collapsed loop iteration variable IV. | ||||||||
8642 | // | ||||||||
8643 | // Let n+1 be the number of collapsed loops in the nest. | ||||||||
8644 | // Iteration variables (I0, I1, .... In) | ||||||||
8645 | // Iteration counts (N0, N1, ... Nn) | ||||||||
8646 | // | ||||||||
8647 | // Acc = IV; | ||||||||
8648 | // | ||||||||
8649 | // To compute Ik for loop k, 0 <= k <= n, generate: | ||||||||
8650 | // Prod = N(k+1) * N(k+2) * ... * Nn; | ||||||||
8651 | // Ik = Acc / Prod; | ||||||||
8652 | // Acc -= Ik * Prod; | ||||||||
8653 | // | ||||||||
8654 | ExprResult Acc = IV; | ||||||||
8655 | for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { | ||||||||
8656 | LoopIterationSpace &IS = IterSpaces[Cnt]; | ||||||||
8657 | SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); | ||||||||
8658 | ExprResult Iter; | ||||||||
8659 | |||||||||
8660 | // Compute prod | ||||||||
8661 | ExprResult Prod = | ||||||||
8662 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); | ||||||||
8663 | for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) | ||||||||
8664 | Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), | ||||||||
8665 | IterSpaces[K].NumIterations); | ||||||||
8666 | |||||||||
8667 | // Iter = Acc / Prod | ||||||||
8668 | // If there is at least one more inner loop to avoid | ||||||||
8669 | // multiplication by 1. | ||||||||
8670 | if (Cnt + 1 < NestedLoopCount) | ||||||||
8671 | Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, | ||||||||
8672 | Acc.get(), Prod.get()); | ||||||||
8673 | else | ||||||||
8674 | Iter = Acc; | ||||||||
8675 | if (!Iter.isUsable()) { | ||||||||
8676 | HasErrors = true; | ||||||||
8677 | break; | ||||||||
8678 | } | ||||||||
8679 | |||||||||
8680 | // Update Acc: | ||||||||
8681 | // Acc -= Iter * Prod | ||||||||
8682 | // Check if there is at least one more inner loop to avoid | ||||||||
8683 | // multiplication by 1. | ||||||||
8684 | if (Cnt + 1 < NestedLoopCount) | ||||||||
8685 | Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, | ||||||||
8686 | Iter.get(), Prod.get()); | ||||||||
8687 | else | ||||||||
8688 | Prod = Iter; | ||||||||
8689 | Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, | ||||||||
8690 | Acc.get(), Prod.get()); | ||||||||
8691 | |||||||||
8692 | // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step | ||||||||
8693 | auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); | ||||||||
8694 | DeclRefExpr *CounterVar = buildDeclRefExpr( | ||||||||
8695 | SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), | ||||||||
8696 | /*RefersToCapture=*/true); | ||||||||
8697 | ExprResult Init = | ||||||||
8698 | buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, | ||||||||
8699 | IS.CounterInit, IS.IsNonRectangularLB, Captures); | ||||||||
8700 | if (!Init.isUsable()) { | ||||||||
8701 | HasErrors = true; | ||||||||
8702 | break; | ||||||||
8703 | } | ||||||||
8704 | ExprResult Update = buildCounterUpdate( | ||||||||
8705 | SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, | ||||||||
8706 | IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); | ||||||||
8707 | if (!Update.isUsable()) { | ||||||||
8708 | HasErrors = true; | ||||||||
8709 | break; | ||||||||
8710 | } | ||||||||
8711 | |||||||||
8712 | // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step | ||||||||
8713 | ExprResult Final = | ||||||||
8714 | buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, | ||||||||
8715 | IS.CounterInit, IS.NumIterations, IS.CounterStep, | ||||||||
8716 | IS.Subtract, IS.IsNonRectangularLB, &Captures); | ||||||||
8717 | if (!Final.isUsable()) { | ||||||||
8718 | HasErrors = true; | ||||||||
8719 | break; | ||||||||
8720 | } | ||||||||
8721 | |||||||||
8722 | if (!Update.isUsable() || !Final.isUsable()) { | ||||||||
8723 | HasErrors = true; | ||||||||
8724 | break; | ||||||||
8725 | } | ||||||||
8726 | // Save results | ||||||||
8727 | Built.Counters[Cnt] = IS.CounterVar; | ||||||||
8728 | Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; | ||||||||
8729 | Built.Inits[Cnt] = Init.get(); | ||||||||
8730 | Built.Updates[Cnt] = Update.get(); | ||||||||
8731 | Built.Finals[Cnt] = Final.get(); | ||||||||
8732 | Built.DependentCounters[Cnt] = nullptr; | ||||||||
8733 | Built.DependentInits[Cnt] = nullptr; | ||||||||
8734 | Built.FinalsConditions[Cnt] = nullptr; | ||||||||
8735 | if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { | ||||||||
8736 | Built.DependentCounters[Cnt] = | ||||||||
8737 | Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; | ||||||||
8738 | Built.DependentInits[Cnt] = | ||||||||
8739 | Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; | ||||||||
8740 | Built.FinalsConditions[Cnt] = IS.FinalCondition; | ||||||||
8741 | } | ||||||||
8742 | } | ||||||||
8743 | } | ||||||||
8744 | |||||||||
8745 | if (HasErrors) | ||||||||
8746 | return 0; | ||||||||
8747 | |||||||||
8748 | // Save results | ||||||||
8749 | Built.IterationVarRef = IV.get(); | ||||||||
8750 | Built.LastIteration = LastIteration.get(); | ||||||||
8751 | Built.NumIterations = NumIterations.get(); | ||||||||
8752 | Built.CalcLastIteration = SemaRef | ||||||||
8753 | .ActOnFinishFullExpr(CalcLastIteration.get(), | ||||||||
8754 | /*DiscardedValue=*/false) | ||||||||
8755 | .get(); | ||||||||
8756 | Built.PreCond = PreCond.get(); | ||||||||
8757 | Built.PreInits = buildPreInits(C, Captures); | ||||||||
8758 | Built.Cond = Cond.get(); | ||||||||
8759 | Built.Init = Init.get(); | ||||||||
8760 | Built.Inc = Inc.get(); | ||||||||
8761 | Built.LB = LB.get(); | ||||||||
8762 | Built.UB = UB.get(); | ||||||||
8763 | Built.IL = IL.get(); | ||||||||
8764 | Built.ST = ST.get(); | ||||||||
8765 | Built.EUB = EUB.get(); | ||||||||
8766 | Built.NLB = NextLB.get(); | ||||||||
8767 | Built.NUB = NextUB.get(); | ||||||||
8768 | Built.PrevLB = PrevLB.get(); | ||||||||
8769 | Built.PrevUB = PrevUB.get(); | ||||||||
8770 | Built.DistInc = DistInc.get(); | ||||||||
8771 | Built.PrevEUB = PrevEUB.get(); | ||||||||
8772 | Built.DistCombinedFields.LB = CombLB.get(); | ||||||||
8773 | Built.DistCombinedFields.UB = CombUB.get(); | ||||||||
8774 | Built.DistCombinedFields.EUB = CombEUB.get(); | ||||||||
8775 | Built.DistCombinedFields.Init = CombInit.get(); | ||||||||
8776 | Built.DistCombinedFields.Cond = CombCond.get(); | ||||||||
8777 | Built.DistCombinedFields.NLB = CombNextLB.get(); | ||||||||
8778 | Built.DistCombinedFields.NUB = CombNextUB.get(); | ||||||||
8779 | Built.DistCombinedFields.DistCond = CombDistCond.get(); | ||||||||
8780 | Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); | ||||||||
8781 | |||||||||
8782 | return NestedLoopCount; | ||||||||
8783 | } | ||||||||
8784 | |||||||||
8785 | static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { | ||||||||
8786 | auto CollapseClauses = | ||||||||
8787 | OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); | ||||||||
8788 | if (CollapseClauses.begin() != CollapseClauses.end()) | ||||||||
8789 | return (*CollapseClauses.begin())->getNumForLoops(); | ||||||||
8790 | return nullptr; | ||||||||
8791 | } | ||||||||
8792 | |||||||||
8793 | static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { | ||||||||
8794 | auto OrderedClauses = | ||||||||
8795 | OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); | ||||||||
8796 | if (OrderedClauses.begin() != OrderedClauses.end()) | ||||||||
8797 | return (*OrderedClauses.begin())->getNumForLoops(); | ||||||||
8798 | return nullptr; | ||||||||
8799 | } | ||||||||
8800 | |||||||||
8801 | static bool checkSimdlenSafelenSpecified(Sema &S, | ||||||||
8802 | const ArrayRef<OMPClause *> Clauses) { | ||||||||
8803 | const OMPSafelenClause *Safelen = nullptr; | ||||||||
8804 | const OMPSimdlenClause *Simdlen = nullptr; | ||||||||
8805 | |||||||||
8806 | for (const OMPClause *Clause : Clauses) { | ||||||||
8807 | if (Clause->getClauseKind() == OMPC_safelen) | ||||||||
8808 | Safelen = cast<OMPSafelenClause>(Clause); | ||||||||
8809 | else if (Clause->getClauseKind() == OMPC_simdlen) | ||||||||
8810 | Simdlen = cast<OMPSimdlenClause>(Clause); | ||||||||
8811 | if (Safelen && Simdlen) | ||||||||
8812 | break; | ||||||||
8813 | } | ||||||||
8814 | |||||||||
8815 | if (Simdlen && Safelen) { | ||||||||
8816 | const Expr *SimdlenLength = Simdlen->getSimdlen(); | ||||||||
8817 | const Expr *SafelenLength = Safelen->getSafelen(); | ||||||||
8818 | if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || | ||||||||
8819 | SimdlenLength->isInstantiationDependent() || | ||||||||
8820 | SimdlenLength->containsUnexpandedParameterPack()) | ||||||||
8821 | return false; | ||||||||
8822 | if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || | ||||||||
8823 | SafelenLength->isInstantiationDependent() || | ||||||||
8824 | SafelenLength->containsUnexpandedParameterPack()) | ||||||||
8825 | return false; | ||||||||
8826 | Expr::EvalResult SimdlenResult, SafelenResult; | ||||||||
8827 | SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); | ||||||||
8828 | SafelenLength->EvaluateAsInt(SafelenResult, S.Context); | ||||||||
8829 | llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); | ||||||||
8830 | llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); | ||||||||
8831 | // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] | ||||||||
8832 | // If both simdlen and safelen clauses are specified, the value of the | ||||||||
8833 | // simdlen parameter must be less than or equal to the value of the safelen | ||||||||
8834 | // parameter. | ||||||||
8835 | if (SimdlenRes > SafelenRes) { | ||||||||
8836 | S.Diag(SimdlenLength->getExprLoc(), | ||||||||
8837 | diag::err_omp_wrong_simdlen_safelen_values) | ||||||||
8838 | << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); | ||||||||
8839 | return true; | ||||||||
8840 | } | ||||||||
8841 | } | ||||||||
8842 | return false; | ||||||||
8843 | } | ||||||||
8844 | |||||||||
8845 | StmtResult | ||||||||
8846 | Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, | ||||||||
8847 | SourceLocation StartLoc, SourceLocation EndLoc, | ||||||||
8848 | VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||||
8849 | if (!AStmt) | ||||||||
8850 | return StmtError(); | ||||||||
8851 | |||||||||
8852 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 8852, __PRETTY_FUNCTION__)); | ||||||||
8853 | OMPLoopDirective::HelperExprs B; | ||||||||
8854 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||||||
8855 | // define the nested loops number. | ||||||||
8856 | unsigned NestedLoopCount = checkOpenMPLoop( | ||||||||
8857 | OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), | ||||||||
8858 | AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VarsWithImplicitDSA, B); | ||||||||
8859 | if (NestedLoopCount == 0) | ||||||||
8860 | return StmtError(); | ||||||||
8861 | |||||||||
8862 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp simd loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp simd loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 8863, __PRETTY_FUNCTION__)) | ||||||||
8863 | "omp simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp simd loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp simd loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 8863, __PRETTY_FUNCTION__)); | ||||||||
8864 | |||||||||
8865 | if (!CurContext->isDependentContext()) { | ||||||||
8866 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||||
8867 | for (OMPClause *C : Clauses) { | ||||||||
8868 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||||
8869 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||||
8870 | B.NumIterations, *this, CurScope, | ||||||||
8871 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||||
8872 | return StmtError(); | ||||||||
8873 | } | ||||||||
8874 | } | ||||||||
8875 | |||||||||
8876 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||||
8877 | return StmtError(); | ||||||||
8878 | |||||||||
8879 | setFunctionHasBranchProtectedScope(); | ||||||||
8880 | return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, | ||||||||
8881 | Clauses, AStmt, B); | ||||||||
8882 | } | ||||||||
8883 | |||||||||
8884 | StmtResult | ||||||||
8885 | Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, | ||||||||
8886 | SourceLocation StartLoc, SourceLocation EndLoc, | ||||||||
8887 | VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||||
8888 | if (!AStmt) | ||||||||
8889 | return StmtError(); | ||||||||
8890 | |||||||||
8891 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 8891, __PRETTY_FUNCTION__)); | ||||||||
8892 | OMPLoopDirective::HelperExprs B; | ||||||||
8893 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||||||
8894 | // define the nested loops number. | ||||||||
8895 | unsigned NestedLoopCount = checkOpenMPLoop( | ||||||||
8896 | OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), | ||||||||
8897 | AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VarsWithImplicitDSA, B); | ||||||||
8898 | if (NestedLoopCount == 0) | ||||||||
8899 | return StmtError(); | ||||||||
8900 | |||||||||
8901 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 8902, __PRETTY_FUNCTION__)) | ||||||||
8902 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 8902, __PRETTY_FUNCTION__)); | ||||||||
8903 | |||||||||
8904 | if (!CurContext->isDependentContext()) { | ||||||||
8905 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||||
8906 | for (OMPClause *C : Clauses) { | ||||||||
8907 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||||
8908 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||||
8909 | B.NumIterations, *this, CurScope, | ||||||||
8910 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||||
8911 | return StmtError(); | ||||||||
8912 | } | ||||||||
8913 | } | ||||||||
8914 | |||||||||
8915 | setFunctionHasBranchProtectedScope(); | ||||||||
8916 | return OMPForDirective::Create( | ||||||||
8917 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, | ||||||||
8918 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||||
8919 | } | ||||||||
8920 | |||||||||
8921 | StmtResult Sema::ActOnOpenMPForSimdDirective( | ||||||||
8922 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||||
8923 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||||
8924 | if (!AStmt) | ||||||||
8925 | return StmtError(); | ||||||||
8926 | |||||||||
8927 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 8927, __PRETTY_FUNCTION__)); | ||||||||
8928 | OMPLoopDirective::HelperExprs B; | ||||||||
8929 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||||||
8930 | // define the nested loops number. | ||||||||
8931 | unsigned NestedLoopCount = | ||||||||
8932 | checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), | ||||||||
8933 | getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||||
8934 | VarsWithImplicitDSA, B); | ||||||||
8935 | if (NestedLoopCount == 0) | ||||||||
8936 | return StmtError(); | ||||||||
8937 | |||||||||
8938 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for simd loop exprs were not built") ? static_cast<void > (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for simd loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 8939, __PRETTY_FUNCTION__)) | ||||||||
8939 | "omp for simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for simd loop exprs were not built") ? static_cast<void > (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for simd loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 8939, __PRETTY_FUNCTION__)); | ||||||||
8940 | |||||||||
8941 | if (!CurContext->isDependentContext()) { | ||||||||
8942 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||||
8943 | for (OMPClause *C : Clauses) { | ||||||||
8944 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||||
8945 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||||
8946 | B.NumIterations, *this, CurScope, | ||||||||
8947 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||||
8948 | return StmtError(); | ||||||||
8949 | } | ||||||||
8950 | } | ||||||||
8951 | |||||||||
8952 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||||
8953 | return StmtError(); | ||||||||
8954 | |||||||||
8955 | setFunctionHasBranchProtectedScope(); | ||||||||
8956 | return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, | ||||||||
8957 | Clauses, AStmt, B); | ||||||||
8958 | } | ||||||||
8959 | |||||||||
8960 | StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, | ||||||||
8961 | Stmt *AStmt, | ||||||||
8962 | SourceLocation StartLoc, | ||||||||
8963 | SourceLocation EndLoc) { | ||||||||
8964 | if (!AStmt) | ||||||||
8965 | return StmtError(); | ||||||||
8966 | |||||||||
8967 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 8967, __PRETTY_FUNCTION__)); | ||||||||
8968 | auto BaseStmt = AStmt; | ||||||||
8969 | while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) | ||||||||
8970 | BaseStmt = CS->getCapturedStmt(); | ||||||||
8971 | if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { | ||||||||
8972 | auto S = C->children(); | ||||||||
8973 | if (S.begin() == S.end()) | ||||||||
8974 | return StmtError(); | ||||||||
8975 | // All associated statements must be '#pragma omp section' except for | ||||||||
8976 | // the first one. | ||||||||
8977 | for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { | ||||||||
8978 | if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { | ||||||||
8979 | if (SectionStmt) | ||||||||
8980 | Diag(SectionStmt->getBeginLoc(), | ||||||||
8981 | diag::err_omp_sections_substmt_not_section); | ||||||||
8982 | return StmtError(); | ||||||||
8983 | } | ||||||||
8984 | cast<OMPSectionDirective>(SectionStmt) | ||||||||
8985 | ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||||
8986 | } | ||||||||
8987 | } else { | ||||||||
8988 | Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); | ||||||||
8989 | return StmtError(); | ||||||||
8990 | } | ||||||||
8991 | |||||||||
8992 | setFunctionHasBranchProtectedScope(); | ||||||||
8993 | |||||||||
8994 | return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, | ||||||||
8995 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), | ||||||||
8996 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||||
8997 | } | ||||||||
8998 | |||||||||
8999 | StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, | ||||||||
9000 | SourceLocation StartLoc, | ||||||||
9001 | SourceLocation EndLoc) { | ||||||||
9002 | if (!AStmt) | ||||||||
9003 | return StmtError(); | ||||||||
9004 | |||||||||
9005 | setFunctionHasBranchProtectedScope(); | ||||||||
9006 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentCancelRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||||
9007 | |||||||||
9008 | return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, | ||||||||
9009 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||||
9010 | } | ||||||||
9011 | |||||||||
9012 | StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, | ||||||||
9013 | Stmt *AStmt, | ||||||||
9014 | SourceLocation StartLoc, | ||||||||
9015 | SourceLocation EndLoc) { | ||||||||
9016 | if (!AStmt) | ||||||||
9017 | return StmtError(); | ||||||||
9018 | |||||||||
9019 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 9019, __PRETTY_FUNCTION__)); | ||||||||
9020 | |||||||||
9021 | setFunctionHasBranchProtectedScope(); | ||||||||
9022 | |||||||||
9023 | // OpenMP [2.7.3, single Construct, Restrictions] | ||||||||
9024 | // The copyprivate clause must not be used with the nowait clause. | ||||||||
9025 | const OMPClause *Nowait = nullptr; | ||||||||
9026 | const OMPClause *Copyprivate = nullptr; | ||||||||
9027 | for (const OMPClause *Clause : Clauses) { | ||||||||
9028 | if (Clause->getClauseKind() == OMPC_nowait) | ||||||||
9029 | Nowait = Clause; | ||||||||
9030 | else if (Clause->getClauseKind() == OMPC_copyprivate) | ||||||||
9031 | Copyprivate = Clause; | ||||||||
9032 | if (Copyprivate && Nowait) { | ||||||||
9033 | Diag(Copyprivate->getBeginLoc(), | ||||||||
9034 | diag::err_omp_single_copyprivate_with_nowait); | ||||||||
9035 | Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); | ||||||||
9036 | return StmtError(); | ||||||||
9037 | } | ||||||||
9038 | } | ||||||||
9039 | |||||||||
9040 | return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); | ||||||||
9041 | } | ||||||||
9042 | |||||||||
9043 | StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, | ||||||||
9044 | SourceLocation StartLoc, | ||||||||
9045 | SourceLocation EndLoc) { | ||||||||
9046 | if (!AStmt) | ||||||||
9047 | return StmtError(); | ||||||||
9048 | |||||||||
9049 | setFunctionHasBranchProtectedScope(); | ||||||||
9050 | |||||||||
9051 | return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); | ||||||||
9052 | } | ||||||||
9053 | |||||||||
9054 | StmtResult Sema::ActOnOpenMPCriticalDirective( | ||||||||
9055 | const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, | ||||||||
9056 | Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { | ||||||||
9057 | if (!AStmt) | ||||||||
9058 | return StmtError(); | ||||||||
9059 | |||||||||
9060 | bool ErrorFound = false; | ||||||||
9061 | llvm::APSInt Hint; | ||||||||
9062 | SourceLocation HintLoc; | ||||||||
9063 | bool DependentHint = false; | ||||||||
9064 | for (const OMPClause *C : Clauses) { | ||||||||
9065 | if (C->getClauseKind() == OMPC_hint) { | ||||||||
9066 | if (!DirName.getName()) { | ||||||||
9067 | Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); | ||||||||
9068 | ErrorFound = true; | ||||||||
9069 | } | ||||||||
9070 | Expr *E = cast<OMPHintClause>(C)->getHint(); | ||||||||
9071 | if (E->isTypeDependent() || E->isValueDependent() || | ||||||||
9072 | E->isInstantiationDependent()) { | ||||||||
9073 | DependentHint = true; | ||||||||
9074 | } else { | ||||||||
9075 | Hint = E->EvaluateKnownConstInt(Context); | ||||||||
9076 | HintLoc = C->getBeginLoc(); | ||||||||
9077 | } | ||||||||
9078 | } | ||||||||
9079 | } | ||||||||
9080 | if (ErrorFound) | ||||||||
9081 | return StmtError(); | ||||||||
9082 | const auto Pair = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCriticalWithHint(DirName); | ||||||||
9083 | if (Pair.first && DirName.getName() && !DependentHint) { | ||||||||
9084 | if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { | ||||||||
9085 | Diag(StartLoc, diag::err_omp_critical_with_hint); | ||||||||
9086 | if (HintLoc.isValid()) | ||||||||
9087 | Diag(HintLoc, diag::note_omp_critical_hint_here) | ||||||||
9088 | << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); | ||||||||
9089 | else | ||||||||
9090 | Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; | ||||||||
9091 | if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { | ||||||||
9092 | Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) | ||||||||
9093 | << 1 | ||||||||
9094 | << C->getHint()->EvaluateKnownConstInt(Context).toString( | ||||||||
9095 | /*Radix=*/10, /*Signed=*/false); | ||||||||
9096 | } else { | ||||||||
9097 | Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; | ||||||||
9098 | } | ||||||||
9099 | } | ||||||||
9100 | } | ||||||||
9101 | |||||||||
9102 | setFunctionHasBranchProtectedScope(); | ||||||||
9103 | |||||||||
9104 | auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, | ||||||||
9105 | Clauses, AStmt); | ||||||||
9106 | if (!Pair.first && DirName.getName() && !DependentHint) | ||||||||
9107 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addCriticalWithHint(Dir, Hint); | ||||||||
9108 | return Dir; | ||||||||
9109 | } | ||||||||
9110 | |||||||||
9111 | StmtResult Sema::ActOnOpenMPParallelForDirective( | ||||||||
9112 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||||
9113 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||||
9114 | if (!AStmt) | ||||||||
9115 | return StmtError(); | ||||||||
9116 | |||||||||
9117 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
9118 | // 1.2.2 OpenMP Language Terminology | ||||||||
9119 | // Structured block - An executable statement with a single entry at the | ||||||||
9120 | // top and a single exit at the bottom. | ||||||||
9121 | // The point of exit cannot be a branch out of the structured block. | ||||||||
9122 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
9123 | CS->getCapturedDecl()->setNothrow(); | ||||||||
9124 | |||||||||
9125 | OMPLoopDirective::HelperExprs B; | ||||||||
9126 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||||||
9127 | // define the nested loops number. | ||||||||
9128 | unsigned NestedLoopCount = | ||||||||
9129 | checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), | ||||||||
9130 | getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||||
9131 | VarsWithImplicitDSA, B); | ||||||||
9132 | if (NestedLoopCount == 0) | ||||||||
9133 | return StmtError(); | ||||||||
9134 | |||||||||
9135 | 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\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 9136, __PRETTY_FUNCTION__)) | ||||||||
9136 | "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\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 9136, __PRETTY_FUNCTION__)); | ||||||||
9137 | |||||||||
9138 | if (!CurContext->isDependentContext()) { | ||||||||
9139 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||||
9140 | for (OMPClause *C : Clauses) { | ||||||||
9141 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||||
9142 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||||
9143 | B.NumIterations, *this, CurScope, | ||||||||
9144 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||||
9145 | return StmtError(); | ||||||||
9146 | } | ||||||||
9147 | } | ||||||||
9148 | |||||||||
9149 | setFunctionHasBranchProtectedScope(); | ||||||||
9150 | return OMPParallelForDirective::Create( | ||||||||
9151 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, | ||||||||
9152 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||||
9153 | } | ||||||||
9154 | |||||||||
9155 | StmtResult Sema::ActOnOpenMPParallelForSimdDirective( | ||||||||
9156 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||||
9157 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||||
9158 | if (!AStmt) | ||||||||
9159 | return StmtError(); | ||||||||
9160 | |||||||||
9161 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
9162 | // 1.2.2 OpenMP Language Terminology | ||||||||
9163 | // Structured block - An executable statement with a single entry at the | ||||||||
9164 | // top and a single exit at the bottom. | ||||||||
9165 | // The point of exit cannot be a branch out of the structured block. | ||||||||
9166 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
9167 | CS->getCapturedDecl()->setNothrow(); | ||||||||
9168 | |||||||||
9169 | OMPLoopDirective::HelperExprs B; | ||||||||
9170 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||||||
9171 | // define the nested loops number. | ||||||||
9172 | unsigned NestedLoopCount = | ||||||||
9173 | checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), | ||||||||
9174 | getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||||
9175 | VarsWithImplicitDSA, B); | ||||||||
9176 | if (NestedLoopCount == 0) | ||||||||
9177 | return StmtError(); | ||||||||
9178 | |||||||||
9179 | if (!CurContext->isDependentContext()) { | ||||||||
9180 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||||
9181 | for (OMPClause *C : Clauses) { | ||||||||
9182 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||||
9183 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||||
9184 | B.NumIterations, *this, CurScope, | ||||||||
9185 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||||
9186 | return StmtError(); | ||||||||
9187 | } | ||||||||
9188 | } | ||||||||
9189 | |||||||||
9190 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||||
9191 | return StmtError(); | ||||||||
9192 | |||||||||
9193 | setFunctionHasBranchProtectedScope(); | ||||||||
9194 | return OMPParallelForSimdDirective::Create( | ||||||||
9195 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||||||
9196 | } | ||||||||
9197 | |||||||||
9198 | StmtResult | ||||||||
9199 | Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, | ||||||||
9200 | Stmt *AStmt, SourceLocation StartLoc, | ||||||||
9201 | SourceLocation EndLoc) { | ||||||||
9202 | if (!AStmt) | ||||||||
9203 | return StmtError(); | ||||||||
9204 | |||||||||
9205 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 9205, __PRETTY_FUNCTION__)); | ||||||||
9206 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
9207 | // 1.2.2 OpenMP Language Terminology | ||||||||
9208 | // Structured block - An executable statement with a single entry at the | ||||||||
9209 | // top and a single exit at the bottom. | ||||||||
9210 | // The point of exit cannot be a branch out of the structured block. | ||||||||
9211 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
9212 | CS->getCapturedDecl()->setNothrow(); | ||||||||
9213 | |||||||||
9214 | setFunctionHasBranchProtectedScope(); | ||||||||
9215 | |||||||||
9216 | return OMPParallelMasterDirective::Create( | ||||||||
9217 | Context, StartLoc, EndLoc, Clauses, AStmt, | ||||||||
9218 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef()); | ||||||||
9219 | } | ||||||||
9220 | |||||||||
9221 | StmtResult | ||||||||
9222 | Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, | ||||||||
9223 | Stmt *AStmt, SourceLocation StartLoc, | ||||||||
9224 | SourceLocation EndLoc) { | ||||||||
9225 | if (!AStmt) | ||||||||
9226 | return StmtError(); | ||||||||
9227 | |||||||||
9228 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 9228, __PRETTY_FUNCTION__)); | ||||||||
9229 | auto BaseStmt = AStmt; | ||||||||
9230 | while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) | ||||||||
9231 | BaseStmt = CS->getCapturedStmt(); | ||||||||
9232 | if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { | ||||||||
9233 | auto S = C->children(); | ||||||||
9234 | if (S.begin() == S.end()) | ||||||||
9235 | return StmtError(); | ||||||||
9236 | // All associated statements must be '#pragma omp section' except for | ||||||||
9237 | // the first one. | ||||||||
9238 | for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { | ||||||||
9239 | if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { | ||||||||
9240 | if (SectionStmt) | ||||||||
9241 | Diag(SectionStmt->getBeginLoc(), | ||||||||
9242 | diag::err_omp_parallel_sections_substmt_not_section); | ||||||||
9243 | return StmtError(); | ||||||||
9244 | } | ||||||||
9245 | cast<OMPSectionDirective>(SectionStmt) | ||||||||
9246 | ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||||
9247 | } | ||||||||
9248 | } else { | ||||||||
9249 | Diag(AStmt->getBeginLoc(), | ||||||||
9250 | diag::err_omp_parallel_sections_not_compound_stmt); | ||||||||
9251 | return StmtError(); | ||||||||
9252 | } | ||||||||
9253 | |||||||||
9254 | setFunctionHasBranchProtectedScope(); | ||||||||
9255 | |||||||||
9256 | return OMPParallelSectionsDirective::Create( | ||||||||
9257 | Context, StartLoc, EndLoc, Clauses, AStmt, | ||||||||
9258 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||||
9259 | } | ||||||||
9260 | |||||||||
9261 | /// detach and mergeable clauses are mutially exclusive, check for it. | ||||||||
9262 | static bool checkDetachMergeableClauses(Sema &S, | ||||||||
9263 | ArrayRef<OMPClause *> Clauses) { | ||||||||
9264 | const OMPClause *PrevClause = nullptr; | ||||||||
9265 | bool ErrorFound = false; | ||||||||
9266 | for (const OMPClause *C : Clauses) { | ||||||||
9267 | if (C->getClauseKind() == OMPC_detach || | ||||||||
9268 | C->getClauseKind() == OMPC_mergeable) { | ||||||||
9269 | if (!PrevClause) { | ||||||||
9270 | PrevClause = C; | ||||||||
9271 | } else if (PrevClause->getClauseKind() != C->getClauseKind()) { | ||||||||
9272 | S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) | ||||||||
9273 | << getOpenMPClauseName(C->getClauseKind()) | ||||||||
9274 | << getOpenMPClauseName(PrevClause->getClauseKind()); | ||||||||
9275 | S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) | ||||||||
9276 | << getOpenMPClauseName(PrevClause->getClauseKind()); | ||||||||
9277 | ErrorFound = true; | ||||||||
9278 | } | ||||||||
9279 | } | ||||||||
9280 | } | ||||||||
9281 | return ErrorFound; | ||||||||
9282 | } | ||||||||
9283 | |||||||||
9284 | StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, | ||||||||
9285 | Stmt *AStmt, SourceLocation StartLoc, | ||||||||
9286 | SourceLocation EndLoc) { | ||||||||
9287 | if (!AStmt) | ||||||||
9288 | return StmtError(); | ||||||||
9289 | |||||||||
9290 | // OpenMP 5.0, 2.10.1 task Construct | ||||||||
9291 | // If a detach clause appears on the directive, then a mergeable clause cannot | ||||||||
9292 | // appear on the same directive. | ||||||||
9293 | if (checkDetachMergeableClauses(*this, Clauses)) | ||||||||
9294 | return StmtError(); | ||||||||
9295 | |||||||||
9296 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
9297 | // 1.2.2 OpenMP Language Terminology | ||||||||
9298 | // Structured block - An executable statement with a single entry at the | ||||||||
9299 | // top and a single exit at the bottom. | ||||||||
9300 | // The point of exit cannot be a branch out of the structured block. | ||||||||
9301 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
9302 | CS->getCapturedDecl()->setNothrow(); | ||||||||
9303 | |||||||||
9304 | setFunctionHasBranchProtectedScope(); | ||||||||
9305 | |||||||||
9306 | return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, | ||||||||
9307 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||||
9308 | } | ||||||||
9309 | |||||||||
9310 | StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, | ||||||||
9311 | SourceLocation EndLoc) { | ||||||||
9312 | return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); | ||||||||
9313 | } | ||||||||
9314 | |||||||||
9315 | StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, | ||||||||
9316 | SourceLocation EndLoc) { | ||||||||
9317 | return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); | ||||||||
9318 | } | ||||||||
9319 | |||||||||
9320 | StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, | ||||||||
9321 | SourceLocation EndLoc) { | ||||||||
9322 | return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); | ||||||||
9323 | } | ||||||||
9324 | |||||||||
9325 | StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, | ||||||||
9326 | Stmt *AStmt, | ||||||||
9327 | SourceLocation StartLoc, | ||||||||
9328 | SourceLocation EndLoc) { | ||||||||
9329 | if (!AStmt) | ||||||||
9330 | return StmtError(); | ||||||||
9331 | |||||||||
9332 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 9332, __PRETTY_FUNCTION__)); | ||||||||
9333 | |||||||||
9334 | setFunctionHasBranchProtectedScope(); | ||||||||
9335 | |||||||||
9336 | return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, | ||||||||
9337 | AStmt, | ||||||||
9338 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef()); | ||||||||
9339 | } | ||||||||
9340 | |||||||||
9341 | StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, | ||||||||
9342 | SourceLocation StartLoc, | ||||||||
9343 | SourceLocation EndLoc) { | ||||||||
9344 | OMPFlushClause *FC = nullptr; | ||||||||
9345 | OMPClause *OrderClause = nullptr; | ||||||||
9346 | for (OMPClause *C : Clauses) { | ||||||||
9347 | if (C->getClauseKind() == OMPC_flush) | ||||||||
9348 | FC = cast<OMPFlushClause>(C); | ||||||||
9349 | else | ||||||||
9350 | OrderClause = C; | ||||||||
9351 | } | ||||||||
9352 | OpenMPClauseKind MemOrderKind = OMPC_unknown; | ||||||||
9353 | SourceLocation MemOrderLoc; | ||||||||
9354 | for (const OMPClause *C : Clauses) { | ||||||||
9355 | if (C->getClauseKind() == OMPC_acq_rel || | ||||||||
9356 | C->getClauseKind() == OMPC_acquire || | ||||||||
9357 | C->getClauseKind() == OMPC_release) { | ||||||||
9358 | if (MemOrderKind != OMPC_unknown) { | ||||||||
9359 | Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) | ||||||||
9360 | << getOpenMPDirectiveName(OMPD_flush) << 1 | ||||||||
9361 | << SourceRange(C->getBeginLoc(), C->getEndLoc()); | ||||||||
9362 | Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) | ||||||||
9363 | << getOpenMPClauseName(MemOrderKind); | ||||||||
9364 | } else { | ||||||||
9365 | MemOrderKind = C->getClauseKind(); | ||||||||
9366 | MemOrderLoc = C->getBeginLoc(); | ||||||||
9367 | } | ||||||||
9368 | } | ||||||||
9369 | } | ||||||||
9370 | if (FC && OrderClause) { | ||||||||
9371 | Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) | ||||||||
9372 | << getOpenMPClauseName(OrderClause->getClauseKind()); | ||||||||
9373 | Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) | ||||||||
9374 | << getOpenMPClauseName(OrderClause->getClauseKind()); | ||||||||
9375 | return StmtError(); | ||||||||
9376 | } | ||||||||
9377 | return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); | ||||||||
9378 | } | ||||||||
9379 | |||||||||
9380 | StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, | ||||||||
9381 | SourceLocation StartLoc, | ||||||||
9382 | SourceLocation EndLoc) { | ||||||||
9383 | if (Clauses.empty()) { | ||||||||
9384 | Diag(StartLoc, diag::err_omp_depobj_expected); | ||||||||
9385 | return StmtError(); | ||||||||
9386 | } else if (Clauses[0]->getClauseKind() != OMPC_depobj) { | ||||||||
9387 | Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected); | ||||||||
9388 | return StmtError(); | ||||||||
9389 | } | ||||||||
9390 | // Only depobj expression and another single clause is allowed. | ||||||||
9391 | if (Clauses.size() > 2) { | ||||||||
9392 | Diag(Clauses[2]->getBeginLoc(), | ||||||||
9393 | diag::err_omp_depobj_single_clause_expected); | ||||||||
9394 | return StmtError(); | ||||||||
9395 | } else if (Clauses.size() < 1) { | ||||||||
9396 | Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected); | ||||||||
9397 | return StmtError(); | ||||||||
9398 | } | ||||||||
9399 | return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses); | ||||||||
9400 | } | ||||||||
9401 | |||||||||
9402 | StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, | ||||||||
9403 | SourceLocation StartLoc, | ||||||||
9404 | SourceLocation EndLoc) { | ||||||||
9405 | // Check that exactly one clause is specified. | ||||||||
9406 | if (Clauses.size() != 1) { | ||||||||
9407 | Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(), | ||||||||
9408 | diag::err_omp_scan_single_clause_expected); | ||||||||
9409 | return StmtError(); | ||||||||
9410 | } | ||||||||
9411 | // Check that scan directive is used in the scopeof the OpenMP loop body. | ||||||||
9412 | if (Scope *S = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurScope()) { | ||||||||
9413 | Scope *ParentS = S->getParent(); | ||||||||
9414 | if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() || | ||||||||
9415 | !ParentS->getBreakParent()->isOpenMPLoopScope()) | ||||||||
9416 | return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive) | ||||||||
9417 | << getOpenMPDirectiveName(OMPD_scan) << 5); | ||||||||
9418 | } | ||||||||
9419 | // Check that only one instance of scan directives is used in the same outer | ||||||||
9420 | // region. | ||||||||
9421 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->doesParentHasScanDirective()) { | ||||||||
9422 | Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan"; | ||||||||
9423 | Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentScanDirectiveLoc(), | ||||||||
9424 | diag::note_omp_previous_directive) | ||||||||
9425 | << "scan"; | ||||||||
9426 | return StmtError(); | ||||||||
9427 | } | ||||||||
9428 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentHasScanDirective(StartLoc); | ||||||||
9429 | return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses); | ||||||||
9430 | } | ||||||||
9431 | |||||||||
9432 | StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, | ||||||||
9433 | Stmt *AStmt, | ||||||||
9434 | SourceLocation StartLoc, | ||||||||
9435 | SourceLocation EndLoc) { | ||||||||
9436 | const OMPClause *DependFound = nullptr; | ||||||||
9437 | const OMPClause *DependSourceClause = nullptr; | ||||||||
9438 | const OMPClause *DependSinkClause = nullptr; | ||||||||
9439 | bool ErrorFound = false; | ||||||||
9440 | const OMPThreadsClause *TC = nullptr; | ||||||||
9441 | const OMPSIMDClause *SC = nullptr; | ||||||||
9442 | for (const OMPClause *C : Clauses) { | ||||||||
9443 | if (auto *DC = dyn_cast<OMPDependClause>(C)) { | ||||||||
9444 | DependFound = C; | ||||||||
9445 | if (DC->getDependencyKind() == OMPC_DEPEND_source) { | ||||||||
9446 | if (DependSourceClause) { | ||||||||
9447 | Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) | ||||||||
9448 | << getOpenMPDirectiveName(OMPD_ordered) | ||||||||
9449 | << getOpenMPClauseName(OMPC_depend) << 2; | ||||||||
9450 | ErrorFound = true; | ||||||||
9451 | } else { | ||||||||
9452 | DependSourceClause = C; | ||||||||
9453 | } | ||||||||
9454 | if (DependSinkClause) { | ||||||||
9455 | Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) | ||||||||
9456 | << 0; | ||||||||
9457 | ErrorFound = true; | ||||||||
9458 | } | ||||||||
9459 | } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { | ||||||||
9460 | if (DependSourceClause) { | ||||||||
9461 | Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) | ||||||||
9462 | << 1; | ||||||||
9463 | ErrorFound = true; | ||||||||
9464 | } | ||||||||
9465 | DependSinkClause = C; | ||||||||
9466 | } | ||||||||
9467 | } else if (C->getClauseKind() == OMPC_threads) { | ||||||||
9468 | TC = cast<OMPThreadsClause>(C); | ||||||||
9469 | } else if (C->getClauseKind() == OMPC_simd) { | ||||||||
9470 | SC = cast<OMPSIMDClause>(C); | ||||||||
9471 | } | ||||||||
9472 | } | ||||||||
9473 | if (!ErrorFound && !SC && | ||||||||
9474 | isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentDirective())) { | ||||||||
9475 | // OpenMP [2.8.1,simd Construct, Restrictions] | ||||||||
9476 | // An ordered construct with the simd clause is the only OpenMP construct | ||||||||
9477 | // that can appear in the simd region. | ||||||||
9478 | Diag(StartLoc, diag::err_omp_prohibited_region_simd) | ||||||||
9479 | << (LangOpts.OpenMP >= 50 ? 1 : 0); | ||||||||
9480 | ErrorFound = true; | ||||||||
9481 | } else if (DependFound && (TC || SC)) { | ||||||||
9482 | Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) | ||||||||
9483 | << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); | ||||||||
9484 | ErrorFound = true; | ||||||||
9485 | } else if (DependFound && !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentOrderedRegionParam().first) { | ||||||||
9486 | Diag(DependFound->getBeginLoc(), | ||||||||
9487 | diag::err_omp_ordered_directive_without_param); | ||||||||
9488 | ErrorFound = true; | ||||||||
9489 | } else if (TC || Clauses.empty()) { | ||||||||
9490 | if (const Expr *Param = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentOrderedRegionParam().first) { | ||||||||
9491 | SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; | ||||||||
9492 | Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) | ||||||||
9493 | << (TC != nullptr); | ||||||||
9494 | Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; | ||||||||
9495 | ErrorFound = true; | ||||||||
9496 | } | ||||||||
9497 | } | ||||||||
9498 | if ((!AStmt && !DependFound) || ErrorFound) | ||||||||
9499 | return StmtError(); | ||||||||
9500 | |||||||||
9501 | // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions. | ||||||||
9502 | // During execution of an iteration of a worksharing-loop or a loop nest | ||||||||
9503 | // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread | ||||||||
9504 | // must not execute more than one ordered region corresponding to an ordered | ||||||||
9505 | // construct without a depend clause. | ||||||||
9506 | if (!DependFound) { | ||||||||
9507 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->doesParentHasOrderedDirective()) { | ||||||||
9508 | Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered"; | ||||||||
9509 | Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentOrderedDirectiveLoc(), | ||||||||
9510 | diag::note_omp_previous_directive) | ||||||||
9511 | << "ordered"; | ||||||||
9512 | return StmtError(); | ||||||||
9513 | } | ||||||||
9514 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentHasOrderedDirective(StartLoc); | ||||||||
9515 | } | ||||||||
9516 | |||||||||
9517 | if (AStmt) { | ||||||||
9518 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 9518, __PRETTY_FUNCTION__)); | ||||||||
9519 | |||||||||
9520 | setFunctionHasBranchProtectedScope(); | ||||||||
9521 | } | ||||||||
9522 | |||||||||
9523 | return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); | ||||||||
9524 | } | ||||||||
9525 | |||||||||
9526 | namespace { | ||||||||
9527 | /// Helper class for checking expression in 'omp atomic [update]' | ||||||||
9528 | /// construct. | ||||||||
9529 | class OpenMPAtomicUpdateChecker { | ||||||||
9530 | /// Error results for atomic update expressions. | ||||||||
9531 | enum ExprAnalysisErrorCode { | ||||||||
9532 | /// A statement is not an expression statement. | ||||||||
9533 | NotAnExpression, | ||||||||
9534 | /// Expression is not builtin binary or unary operation. | ||||||||
9535 | NotABinaryOrUnaryExpression, | ||||||||
9536 | /// Unary operation is not post-/pre- increment/decrement operation. | ||||||||
9537 | NotAnUnaryIncDecExpression, | ||||||||
9538 | /// An expression is not of scalar type. | ||||||||
9539 | NotAScalarType, | ||||||||
9540 | /// A binary operation is not an assignment operation. | ||||||||
9541 | NotAnAssignmentOp, | ||||||||
9542 | /// RHS part of the binary operation is not a binary expression. | ||||||||
9543 | NotABinaryExpression, | ||||||||
9544 | /// RHS part is not additive/multiplicative/shift/biwise binary | ||||||||
9545 | /// expression. | ||||||||
9546 | NotABinaryOperator, | ||||||||
9547 | /// RHS binary operation does not have reference to the updated LHS | ||||||||
9548 | /// part. | ||||||||
9549 | NotAnUpdateExpression, | ||||||||
9550 | /// No errors is found. | ||||||||
9551 | NoError | ||||||||
9552 | }; | ||||||||
9553 | /// Reference to Sema. | ||||||||
9554 | Sema &SemaRef; | ||||||||
9555 | /// A location for note diagnostics (when error is found). | ||||||||
9556 | SourceLocation NoteLoc; | ||||||||
9557 | /// 'x' lvalue part of the source atomic expression. | ||||||||
9558 | Expr *X; | ||||||||
9559 | /// 'expr' rvalue part of the source atomic expression. | ||||||||
9560 | Expr *E; | ||||||||
9561 | /// Helper expression of the form | ||||||||
9562 | /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or | ||||||||
9563 | /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. | ||||||||
9564 | Expr *UpdateExpr; | ||||||||
9565 | /// Is 'x' a LHS in a RHS part of full update expression. It is | ||||||||
9566 | /// important for non-associative operations. | ||||||||
9567 | bool IsXLHSInRHSPart; | ||||||||
9568 | BinaryOperatorKind Op; | ||||||||
9569 | SourceLocation OpLoc; | ||||||||
9570 | /// true if the source expression is a postfix unary operation, false | ||||||||
9571 | /// if it is a prefix unary operation. | ||||||||
9572 | bool IsPostfixUpdate; | ||||||||
9573 | |||||||||
9574 | public: | ||||||||
9575 | OpenMPAtomicUpdateChecker(Sema &SemaRef) | ||||||||
9576 | : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), | ||||||||
9577 | IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} | ||||||||
9578 | /// Check specified statement that it is suitable for 'atomic update' | ||||||||
9579 | /// constructs and extract 'x', 'expr' and Operation from the original | ||||||||
9580 | /// expression. If DiagId and NoteId == 0, then only check is performed | ||||||||
9581 | /// without error notification. | ||||||||
9582 | /// \param DiagId Diagnostic which should be emitted if error is found. | ||||||||
9583 | /// \param NoteId Diagnostic note for the main error message. | ||||||||
9584 | /// \return true if statement is not an update expression, false otherwise. | ||||||||
9585 | bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); | ||||||||
9586 | /// Return the 'x' lvalue part of the source atomic expression. | ||||||||
9587 | Expr *getX() const { return X; } | ||||||||
9588 | /// Return the 'expr' rvalue part of the source atomic expression. | ||||||||
9589 | Expr *getExpr() const { return E; } | ||||||||
9590 | /// Return the update expression used in calculation of the updated | ||||||||
9591 | /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or | ||||||||
9592 | /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. | ||||||||
9593 | Expr *getUpdateExpr() const { return UpdateExpr; } | ||||||||
9594 | /// Return true if 'x' is LHS in RHS part of full update expression, | ||||||||
9595 | /// false otherwise. | ||||||||
9596 | bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } | ||||||||
9597 | |||||||||
9598 | /// true if the source expression is a postfix unary operation, false | ||||||||
9599 | /// if it is a prefix unary operation. | ||||||||
9600 | bool isPostfixUpdate() const { return IsPostfixUpdate; } | ||||||||
9601 | |||||||||
9602 | private: | ||||||||
9603 | bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, | ||||||||
9604 | unsigned NoteId = 0); | ||||||||
9605 | }; | ||||||||
9606 | } // namespace | ||||||||
9607 | |||||||||
9608 | bool OpenMPAtomicUpdateChecker::checkBinaryOperation( | ||||||||
9609 | BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { | ||||||||
9610 | ExprAnalysisErrorCode ErrorFound = NoError; | ||||||||
9611 | SourceLocation ErrorLoc, NoteLoc; | ||||||||
9612 | SourceRange ErrorRange, NoteRange; | ||||||||
9613 | // Allowed constructs are: | ||||||||
9614 | // x = x binop expr; | ||||||||
9615 | // x = expr binop x; | ||||||||
9616 | if (AtomicBinOp->getOpcode() == BO_Assign) { | ||||||||
9617 | X = AtomicBinOp->getLHS(); | ||||||||
9618 | if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( | ||||||||
9619 | AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { | ||||||||
9620 | if (AtomicInnerBinOp->isMultiplicativeOp() || | ||||||||
9621 | AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || | ||||||||
9622 | AtomicInnerBinOp->isBitwiseOp()) { | ||||||||
9623 | Op = AtomicInnerBinOp->getOpcode(); | ||||||||
9624 | OpLoc = AtomicInnerBinOp->getOperatorLoc(); | ||||||||
9625 | Expr *LHS = AtomicInnerBinOp->getLHS(); | ||||||||
9626 | Expr *RHS = AtomicInnerBinOp->getRHS(); | ||||||||
9627 | llvm::FoldingSetNodeID XId, LHSId, RHSId; | ||||||||
9628 | X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), | ||||||||
9629 | /*Canonical=*/true); | ||||||||
9630 | LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), | ||||||||
9631 | /*Canonical=*/true); | ||||||||
9632 | RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), | ||||||||
9633 | /*Canonical=*/true); | ||||||||
9634 | if (XId == LHSId) { | ||||||||
9635 | E = RHS; | ||||||||
9636 | IsXLHSInRHSPart = true; | ||||||||
9637 | } else if (XId == RHSId) { | ||||||||
9638 | E = LHS; | ||||||||
9639 | IsXLHSInRHSPart = false; | ||||||||
9640 | } else { | ||||||||
9641 | ErrorLoc = AtomicInnerBinOp->getExprLoc(); | ||||||||
9642 | ErrorRange = AtomicInnerBinOp->getSourceRange(); | ||||||||
9643 | NoteLoc = X->getExprLoc(); | ||||||||
9644 | NoteRange = X->getSourceRange(); | ||||||||
9645 | ErrorFound = NotAnUpdateExpression; | ||||||||
9646 | } | ||||||||
9647 | } else { | ||||||||
9648 | ErrorLoc = AtomicInnerBinOp->getExprLoc(); | ||||||||
9649 | ErrorRange = AtomicInnerBinOp->getSourceRange(); | ||||||||
9650 | NoteLoc = AtomicInnerBinOp->getOperatorLoc(); | ||||||||
9651 | NoteRange = SourceRange(NoteLoc, NoteLoc); | ||||||||
9652 | ErrorFound = NotABinaryOperator; | ||||||||
9653 | } | ||||||||
9654 | } else { | ||||||||
9655 | NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); | ||||||||
9656 | NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); | ||||||||
9657 | ErrorFound = NotABinaryExpression; | ||||||||
9658 | } | ||||||||
9659 | } else { | ||||||||
9660 | ErrorLoc = AtomicBinOp->getExprLoc(); | ||||||||
9661 | ErrorRange = AtomicBinOp->getSourceRange(); | ||||||||
9662 | NoteLoc = AtomicBinOp->getOperatorLoc(); | ||||||||
9663 | NoteRange = SourceRange(NoteLoc, NoteLoc); | ||||||||
9664 | ErrorFound = NotAnAssignmentOp; | ||||||||
9665 | } | ||||||||
9666 | if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { | ||||||||
9667 | SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; | ||||||||
9668 | SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; | ||||||||
9669 | return true; | ||||||||
9670 | } | ||||||||
9671 | if (SemaRef.CurContext->isDependentContext()) | ||||||||
9672 | E = X = UpdateExpr = nullptr; | ||||||||
9673 | return ErrorFound != NoError; | ||||||||
9674 | } | ||||||||
9675 | |||||||||
9676 | bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, | ||||||||
9677 | unsigned NoteId) { | ||||||||
9678 | ExprAnalysisErrorCode ErrorFound = NoError; | ||||||||
9679 | SourceLocation ErrorLoc, NoteLoc; | ||||||||
9680 | SourceRange ErrorRange, NoteRange; | ||||||||
9681 | // Allowed constructs are: | ||||||||
9682 | // x++; | ||||||||
9683 | // x--; | ||||||||
9684 | // ++x; | ||||||||
9685 | // --x; | ||||||||
9686 | // x binop= expr; | ||||||||
9687 | // x = x binop expr; | ||||||||
9688 | // x = expr binop x; | ||||||||
9689 | if (auto *AtomicBody = dyn_cast<Expr>(S)) { | ||||||||
9690 | AtomicBody = AtomicBody->IgnoreParenImpCasts(); | ||||||||
9691 | if (AtomicBody->getType()->isScalarType() || | ||||||||
9692 | AtomicBody->isInstantiationDependent()) { | ||||||||
9693 | if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( | ||||||||
9694 | AtomicBody->IgnoreParenImpCasts())) { | ||||||||
9695 | // Check for Compound Assignment Operation | ||||||||
9696 | Op = BinaryOperator::getOpForCompoundAssignment( | ||||||||
9697 | AtomicCompAssignOp->getOpcode()); | ||||||||
9698 | OpLoc = AtomicCompAssignOp->getOperatorLoc(); | ||||||||
9699 | E = AtomicCompAssignOp->getRHS(); | ||||||||
9700 | X = AtomicCompAssignOp->getLHS()->IgnoreParens(); | ||||||||
9701 | IsXLHSInRHSPart = true; | ||||||||
9702 | } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( | ||||||||
9703 | AtomicBody->IgnoreParenImpCasts())) { | ||||||||
9704 | // Check for Binary Operation | ||||||||
9705 | if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) | ||||||||
9706 | return true; | ||||||||
9707 | } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( | ||||||||
9708 | AtomicBody->IgnoreParenImpCasts())) { | ||||||||
9709 | // Check for Unary Operation | ||||||||
9710 | if (AtomicUnaryOp->isIncrementDecrementOp()) { | ||||||||
9711 | IsPostfixUpdate = AtomicUnaryOp->isPostfix(); | ||||||||
9712 | Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; | ||||||||
9713 | OpLoc = AtomicUnaryOp->getOperatorLoc(); | ||||||||
9714 | X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); | ||||||||
9715 | E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); | ||||||||
9716 | IsXLHSInRHSPart = true; | ||||||||
9717 | } else { | ||||||||
9718 | ErrorFound = NotAnUnaryIncDecExpression; | ||||||||
9719 | ErrorLoc = AtomicUnaryOp->getExprLoc(); | ||||||||
9720 | ErrorRange = AtomicUnaryOp->getSourceRange(); | ||||||||
9721 | NoteLoc = AtomicUnaryOp->getOperatorLoc(); | ||||||||
9722 | NoteRange = SourceRange(NoteLoc, NoteLoc); | ||||||||
9723 | } | ||||||||
9724 | } else if (!AtomicBody->isInstantiationDependent()) { | ||||||||
9725 | ErrorFound = NotABinaryOrUnaryExpression; | ||||||||
9726 | NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); | ||||||||
9727 | NoteRange = ErrorRange = AtomicBody->getSourceRange(); | ||||||||
9728 | } | ||||||||
9729 | } else { | ||||||||
9730 | ErrorFound = NotAScalarType; | ||||||||
9731 | NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); | ||||||||
9732 | NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); | ||||||||
9733 | } | ||||||||
9734 | } else { | ||||||||
9735 | ErrorFound = NotAnExpression; | ||||||||
9736 | NoteLoc = ErrorLoc = S->getBeginLoc(); | ||||||||
9737 | NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); | ||||||||
9738 | } | ||||||||
9739 | if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { | ||||||||
9740 | SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; | ||||||||
9741 | SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; | ||||||||
9742 | return true; | ||||||||
9743 | } | ||||||||
9744 | if (SemaRef.CurContext->isDependentContext()) | ||||||||
9745 | E = X = UpdateExpr = nullptr; | ||||||||
9746 | if (ErrorFound == NoError && E && X) { | ||||||||
9747 | // Build an update expression of form 'OpaqueValueExpr(x) binop | ||||||||
9748 | // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop | ||||||||
9749 | // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. | ||||||||
9750 | auto *OVEX = new (SemaRef.getASTContext()) | ||||||||
9751 | OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); | ||||||||
9752 | auto *OVEExpr = new (SemaRef.getASTContext()) | ||||||||
9753 | OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); | ||||||||
9754 | ExprResult Update = | ||||||||
9755 | SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, | ||||||||
9756 | IsXLHSInRHSPart ? OVEExpr : OVEX); | ||||||||
9757 | if (Update.isInvalid()) | ||||||||
9758 | return true; | ||||||||
9759 | Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), | ||||||||
9760 | Sema::AA_Casting); | ||||||||
9761 | if (Update.isInvalid()) | ||||||||
9762 | return true; | ||||||||
9763 | UpdateExpr = Update.get(); | ||||||||
9764 | } | ||||||||
9765 | return ErrorFound != NoError; | ||||||||
9766 | } | ||||||||
9767 | |||||||||
9768 | StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, | ||||||||
9769 | Stmt *AStmt, | ||||||||
9770 | SourceLocation StartLoc, | ||||||||
9771 | SourceLocation EndLoc) { | ||||||||
9772 | // Register location of the first atomic directive. | ||||||||
9773 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addAtomicDirectiveLoc(StartLoc); | ||||||||
9774 | if (!AStmt) | ||||||||
9775 | return StmtError(); | ||||||||
9776 | |||||||||
9777 | // 1.2.2 OpenMP Language Terminology | ||||||||
9778 | // Structured block - An executable statement with a single entry at the | ||||||||
9779 | // top and a single exit at the bottom. | ||||||||
9780 | // The point of exit cannot be a branch out of the structured block. | ||||||||
9781 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
9782 | OpenMPClauseKind AtomicKind = OMPC_unknown; | ||||||||
9783 | SourceLocation AtomicKindLoc; | ||||||||
9784 | OpenMPClauseKind MemOrderKind = OMPC_unknown; | ||||||||
9785 | SourceLocation MemOrderLoc; | ||||||||
9786 | for (const OMPClause *C : Clauses) { | ||||||||
9787 | if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || | ||||||||
9788 | C->getClauseKind() == OMPC_update || | ||||||||
9789 | C->getClauseKind() == OMPC_capture) { | ||||||||
9790 | if (AtomicKind != OMPC_unknown) { | ||||||||
9791 | Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) | ||||||||
9792 | << SourceRange(C->getBeginLoc(), C->getEndLoc()); | ||||||||
9793 | Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) | ||||||||
9794 | << getOpenMPClauseName(AtomicKind); | ||||||||
9795 | } else { | ||||||||
9796 | AtomicKind = C->getClauseKind(); | ||||||||
9797 | AtomicKindLoc = C->getBeginLoc(); | ||||||||
9798 | } | ||||||||
9799 | } | ||||||||
9800 | if (C->getClauseKind() == OMPC_seq_cst || | ||||||||
9801 | C->getClauseKind() == OMPC_acq_rel || | ||||||||
9802 | C->getClauseKind() == OMPC_acquire || | ||||||||
9803 | C->getClauseKind() == OMPC_release || | ||||||||
9804 | C->getClauseKind() == OMPC_relaxed) { | ||||||||
9805 | if (MemOrderKind != OMPC_unknown) { | ||||||||
9806 | Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) | ||||||||
9807 | << getOpenMPDirectiveName(OMPD_atomic) << 0 | ||||||||
9808 | << SourceRange(C->getBeginLoc(), C->getEndLoc()); | ||||||||
9809 | Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) | ||||||||
9810 | << getOpenMPClauseName(MemOrderKind); | ||||||||
9811 | } else { | ||||||||
9812 | MemOrderKind = C->getClauseKind(); | ||||||||
9813 | MemOrderLoc = C->getBeginLoc(); | ||||||||
9814 | } | ||||||||
9815 | } | ||||||||
9816 | } | ||||||||
9817 | // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions | ||||||||
9818 | // If atomic-clause is read then memory-order-clause must not be acq_rel or | ||||||||
9819 | // release. | ||||||||
9820 | // If atomic-clause is write then memory-order-clause must not be acq_rel or | ||||||||
9821 | // acquire. | ||||||||
9822 | // If atomic-clause is update or not present then memory-order-clause must not | ||||||||
9823 | // be acq_rel or acquire. | ||||||||
9824 | if ((AtomicKind == OMPC_read && | ||||||||
9825 | (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || | ||||||||
9826 | ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || | ||||||||
9827 | AtomicKind == OMPC_unknown) && | ||||||||
9828 | (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { | ||||||||
9829 | SourceLocation Loc = AtomicKindLoc; | ||||||||
9830 | if (AtomicKind == OMPC_unknown) | ||||||||
9831 | Loc = StartLoc; | ||||||||
9832 | Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) | ||||||||
9833 | << getOpenMPClauseName(AtomicKind) | ||||||||
9834 | << (AtomicKind == OMPC_unknown ? 1 : 0) | ||||||||
9835 | << getOpenMPClauseName(MemOrderKind); | ||||||||
9836 | Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) | ||||||||
9837 | << getOpenMPClauseName(MemOrderKind); | ||||||||
9838 | } | ||||||||
9839 | |||||||||
9840 | Stmt *Body = AStmt; | ||||||||
9841 | if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) | ||||||||
9842 | Body = EWC->getSubExpr(); | ||||||||
9843 | |||||||||
9844 | Expr *X = nullptr; | ||||||||
9845 | Expr *V = nullptr; | ||||||||
9846 | Expr *E = nullptr; | ||||||||
9847 | Expr *UE = nullptr; | ||||||||
9848 | bool IsXLHSInRHSPart = false; | ||||||||
9849 | bool IsPostfixUpdate = false; | ||||||||
9850 | // OpenMP [2.12.6, atomic Construct] | ||||||||
9851 | // In the next expressions: | ||||||||
9852 | // * x and v (as applicable) are both l-value expressions with scalar type. | ||||||||
9853 | // * During the execution of an atomic region, multiple syntactic | ||||||||
9854 | // occurrences of x must designate the same storage location. | ||||||||
9855 | // * Neither of v and expr (as applicable) may access the storage location | ||||||||
9856 | // designated by x. | ||||||||
9857 | // * Neither of x and expr (as applicable) may access the storage location | ||||||||
9858 | // designated by v. | ||||||||
9859 | // * expr is an expression with scalar type. | ||||||||
9860 | // * binop is one of +, *, -, /, &, ^, |, <<, or >>. | ||||||||
9861 | // * binop, binop=, ++, and -- are not overloaded operators. | ||||||||
9862 | // * The expression x binop expr must be numerically equivalent to x binop | ||||||||
9863 | // (expr). This requirement is satisfied if the operators in expr have | ||||||||
9864 | // precedence greater than binop, or by using parentheses around expr or | ||||||||
9865 | // subexpressions of expr. | ||||||||
9866 | // * The expression expr binop x must be numerically equivalent to (expr) | ||||||||
9867 | // binop x. This requirement is satisfied if the operators in expr have | ||||||||
9868 | // precedence equal to or greater than binop, or by using parentheses around | ||||||||
9869 | // expr or subexpressions of expr. | ||||||||
9870 | // * For forms that allow multiple occurrences of x, the number of times | ||||||||
9871 | // that x is evaluated is unspecified. | ||||||||
9872 | if (AtomicKind == OMPC_read) { | ||||||||
9873 | enum { | ||||||||
9874 | NotAnExpression, | ||||||||
9875 | NotAnAssignmentOp, | ||||||||
9876 | NotAScalarType, | ||||||||
9877 | NotAnLValue, | ||||||||
9878 | NoError | ||||||||
9879 | } ErrorFound = NoError; | ||||||||
9880 | SourceLocation ErrorLoc, NoteLoc; | ||||||||
9881 | SourceRange ErrorRange, NoteRange; | ||||||||
9882 | // If clause is read: | ||||||||
9883 | // v = x; | ||||||||
9884 | if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { | ||||||||
9885 | const auto *AtomicBinOp = | ||||||||
9886 | dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); | ||||||||
9887 | if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { | ||||||||
9888 | X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); | ||||||||
9889 | V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); | ||||||||
9890 | if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && | ||||||||
9891 | (V->isInstantiationDependent() || V->getType()->isScalarType())) { | ||||||||
9892 | if (!X->isLValue() || !V->isLValue()) { | ||||||||
9893 | const Expr *NotLValueExpr = X->isLValue() ? V : X; | ||||||||
9894 | ErrorFound = NotAnLValue; | ||||||||
9895 | ErrorLoc = AtomicBinOp->getExprLoc(); | ||||||||
9896 | ErrorRange = AtomicBinOp->getSourceRange(); | ||||||||
9897 | NoteLoc = NotLValueExpr->getExprLoc(); | ||||||||
9898 | NoteRange = NotLValueExpr->getSourceRange(); | ||||||||
9899 | } | ||||||||
9900 | } else if (!X->isInstantiationDependent() || | ||||||||
9901 | !V->isInstantiationDependent()) { | ||||||||
9902 | const Expr *NotScalarExpr = | ||||||||
9903 | (X->isInstantiationDependent() || X->getType()->isScalarType()) | ||||||||
9904 | ? V | ||||||||
9905 | : X; | ||||||||
9906 | ErrorFound = NotAScalarType; | ||||||||
9907 | ErrorLoc = AtomicBinOp->getExprLoc(); | ||||||||
9908 | ErrorRange = AtomicBinOp->getSourceRange(); | ||||||||
9909 | NoteLoc = NotScalarExpr->getExprLoc(); | ||||||||
9910 | NoteRange = NotScalarExpr->getSourceRange(); | ||||||||
9911 | } | ||||||||
9912 | } else if (!AtomicBody->isInstantiationDependent()) { | ||||||||
9913 | ErrorFound = NotAnAssignmentOp; | ||||||||
9914 | ErrorLoc = AtomicBody->getExprLoc(); | ||||||||
9915 | ErrorRange = AtomicBody->getSourceRange(); | ||||||||
9916 | NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() | ||||||||
9917 | : AtomicBody->getExprLoc(); | ||||||||
9918 | NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() | ||||||||
9919 | : AtomicBody->getSourceRange(); | ||||||||
9920 | } | ||||||||
9921 | } else { | ||||||||
9922 | ErrorFound = NotAnExpression; | ||||||||
9923 | NoteLoc = ErrorLoc = Body->getBeginLoc(); | ||||||||
9924 | NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); | ||||||||
9925 | } | ||||||||
9926 | if (ErrorFound != NoError) { | ||||||||
9927 | Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) | ||||||||
9928 | << ErrorRange; | ||||||||
9929 | Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound | ||||||||
9930 | << NoteRange; | ||||||||
9931 | return StmtError(); | ||||||||
9932 | } | ||||||||
9933 | if (CurContext->isDependentContext()) | ||||||||
9934 | V = X = nullptr; | ||||||||
9935 | } else if (AtomicKind == OMPC_write) { | ||||||||
9936 | enum { | ||||||||
9937 | NotAnExpression, | ||||||||
9938 | NotAnAssignmentOp, | ||||||||
9939 | NotAScalarType, | ||||||||
9940 | NotAnLValue, | ||||||||
9941 | NoError | ||||||||
9942 | } ErrorFound = NoError; | ||||||||
9943 | SourceLocation ErrorLoc, NoteLoc; | ||||||||
9944 | SourceRange ErrorRange, NoteRange; | ||||||||
9945 | // If clause is write: | ||||||||
9946 | // x = expr; | ||||||||
9947 | if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { | ||||||||
9948 | const auto *AtomicBinOp = | ||||||||
9949 | dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); | ||||||||
9950 | if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { | ||||||||
9951 | X = AtomicBinOp->getLHS(); | ||||||||
9952 | E = AtomicBinOp->getRHS(); | ||||||||
9953 | if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && | ||||||||
9954 | (E->isInstantiationDependent() || E->getType()->isScalarType())) { | ||||||||
9955 | if (!X->isLValue()) { | ||||||||
9956 | ErrorFound = NotAnLValue; | ||||||||
9957 | ErrorLoc = AtomicBinOp->getExprLoc(); | ||||||||
9958 | ErrorRange = AtomicBinOp->getSourceRange(); | ||||||||
9959 | NoteLoc = X->getExprLoc(); | ||||||||
9960 | NoteRange = X->getSourceRange(); | ||||||||
9961 | } | ||||||||
9962 | } else if (!X->isInstantiationDependent() || | ||||||||
9963 | !E->isInstantiationDependent()) { | ||||||||
9964 | const Expr *NotScalarExpr = | ||||||||
9965 | (X->isInstantiationDependent() || X->getType()->isScalarType()) | ||||||||
9966 | ? E | ||||||||
9967 | : X; | ||||||||
9968 | ErrorFound = NotAScalarType; | ||||||||
9969 | ErrorLoc = AtomicBinOp->getExprLoc(); | ||||||||
9970 | ErrorRange = AtomicBinOp->getSourceRange(); | ||||||||
9971 | NoteLoc = NotScalarExpr->getExprLoc(); | ||||||||
9972 | NoteRange = NotScalarExpr->getSourceRange(); | ||||||||
9973 | } | ||||||||
9974 | } else if (!AtomicBody->isInstantiationDependent()) { | ||||||||
9975 | ErrorFound = NotAnAssignmentOp; | ||||||||
9976 | ErrorLoc = AtomicBody->getExprLoc(); | ||||||||
9977 | ErrorRange = AtomicBody->getSourceRange(); | ||||||||
9978 | NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() | ||||||||
9979 | : AtomicBody->getExprLoc(); | ||||||||
9980 | NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() | ||||||||
9981 | : AtomicBody->getSourceRange(); | ||||||||
9982 | } | ||||||||
9983 | } else { | ||||||||
9984 | ErrorFound = NotAnExpression; | ||||||||
9985 | NoteLoc = ErrorLoc = Body->getBeginLoc(); | ||||||||
9986 | NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); | ||||||||
9987 | } | ||||||||
9988 | if (ErrorFound != NoError) { | ||||||||
9989 | Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) | ||||||||
9990 | << ErrorRange; | ||||||||
9991 | Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound | ||||||||
9992 | << NoteRange; | ||||||||
9993 | return StmtError(); | ||||||||
9994 | } | ||||||||
9995 | if (CurContext->isDependentContext()) | ||||||||
9996 | E = X = nullptr; | ||||||||
9997 | } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { | ||||||||
9998 | // If clause is update: | ||||||||
9999 | // x++; | ||||||||
10000 | // x--; | ||||||||
10001 | // ++x; | ||||||||
10002 | // --x; | ||||||||
10003 | // x binop= expr; | ||||||||
10004 | // x = x binop expr; | ||||||||
10005 | // x = expr binop x; | ||||||||
10006 | OpenMPAtomicUpdateChecker Checker(*this); | ||||||||
10007 | if (Checker.checkStatement( | ||||||||
10008 | Body, (AtomicKind == OMPC_update) | ||||||||
10009 | ? diag::err_omp_atomic_update_not_expression_statement | ||||||||
10010 | : diag::err_omp_atomic_not_expression_statement, | ||||||||
10011 | diag::note_omp_atomic_update)) | ||||||||
10012 | return StmtError(); | ||||||||
10013 | if (!CurContext->isDependentContext()) { | ||||||||
10014 | E = Checker.getExpr(); | ||||||||
10015 | X = Checker.getX(); | ||||||||
10016 | UE = Checker.getUpdateExpr(); | ||||||||
10017 | IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); | ||||||||
10018 | } | ||||||||
10019 | } else if (AtomicKind == OMPC_capture) { | ||||||||
10020 | enum { | ||||||||
10021 | NotAnAssignmentOp, | ||||||||
10022 | NotACompoundStatement, | ||||||||
10023 | NotTwoSubstatements, | ||||||||
10024 | NotASpecificExpression, | ||||||||
10025 | NoError | ||||||||
10026 | } ErrorFound = NoError; | ||||||||
10027 | SourceLocation ErrorLoc, NoteLoc; | ||||||||
10028 | SourceRange ErrorRange, NoteRange; | ||||||||
10029 | if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { | ||||||||
10030 | // If clause is a capture: | ||||||||
10031 | // v = x++; | ||||||||
10032 | // v = x--; | ||||||||
10033 | // v = ++x; | ||||||||
10034 | // v = --x; | ||||||||
10035 | // v = x binop= expr; | ||||||||
10036 | // v = x = x binop expr; | ||||||||
10037 | // v = x = expr binop x; | ||||||||
10038 | const auto *AtomicBinOp = | ||||||||
10039 | dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); | ||||||||
10040 | if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { | ||||||||
10041 | V = AtomicBinOp->getLHS(); | ||||||||
10042 | Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); | ||||||||
10043 | OpenMPAtomicUpdateChecker Checker(*this); | ||||||||
10044 | if (Checker.checkStatement( | ||||||||
10045 | Body, diag::err_omp_atomic_capture_not_expression_statement, | ||||||||
10046 | diag::note_omp_atomic_update)) | ||||||||
10047 | return StmtError(); | ||||||||
10048 | E = Checker.getExpr(); | ||||||||
10049 | X = Checker.getX(); | ||||||||
10050 | UE = Checker.getUpdateExpr(); | ||||||||
10051 | IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); | ||||||||
10052 | IsPostfixUpdate = Checker.isPostfixUpdate(); | ||||||||
10053 | } else if (!AtomicBody->isInstantiationDependent()) { | ||||||||
10054 | ErrorLoc = AtomicBody->getExprLoc(); | ||||||||
10055 | ErrorRange = AtomicBody->getSourceRange(); | ||||||||
10056 | NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() | ||||||||
10057 | : AtomicBody->getExprLoc(); | ||||||||
10058 | NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() | ||||||||
10059 | : AtomicBody->getSourceRange(); | ||||||||
10060 | ErrorFound = NotAnAssignmentOp; | ||||||||
10061 | } | ||||||||
10062 | if (ErrorFound != NoError) { | ||||||||
10063 | Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) | ||||||||
10064 | << ErrorRange; | ||||||||
10065 | Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; | ||||||||
10066 | return StmtError(); | ||||||||
10067 | } | ||||||||
10068 | if (CurContext->isDependentContext()) | ||||||||
10069 | UE = V = E = X = nullptr; | ||||||||
10070 | } else { | ||||||||
10071 | // If clause is a capture: | ||||||||
10072 | // { v = x; x = expr; } | ||||||||
10073 | // { v = x; x++; } | ||||||||
10074 | // { v = x; x--; } | ||||||||
10075 | // { v = x; ++x; } | ||||||||
10076 | // { v = x; --x; } | ||||||||
10077 | // { v = x; x binop= expr; } | ||||||||
10078 | // { v = x; x = x binop expr; } | ||||||||
10079 | // { v = x; x = expr binop x; } | ||||||||
10080 | // { x++; v = x; } | ||||||||
10081 | // { x--; v = x; } | ||||||||
10082 | // { ++x; v = x; } | ||||||||
10083 | // { --x; v = x; } | ||||||||
10084 | // { x binop= expr; v = x; } | ||||||||
10085 | // { x = x binop expr; v = x; } | ||||||||
10086 | // { x = expr binop x; v = x; } | ||||||||
10087 | if (auto *CS = dyn_cast<CompoundStmt>(Body)) { | ||||||||
10088 | // Check that this is { expr1; expr2; } | ||||||||
10089 | if (CS->size() == 2) { | ||||||||
10090 | Stmt *First = CS->body_front(); | ||||||||
10091 | Stmt *Second = CS->body_back(); | ||||||||
10092 | if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) | ||||||||
10093 | First = EWC->getSubExpr()->IgnoreParenImpCasts(); | ||||||||
10094 | if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) | ||||||||
10095 | Second = EWC->getSubExpr()->IgnoreParenImpCasts(); | ||||||||
10096 | // Need to find what subexpression is 'v' and what is 'x'. | ||||||||
10097 | OpenMPAtomicUpdateChecker Checker(*this); | ||||||||
10098 | bool IsUpdateExprFound = !Checker.checkStatement(Second); | ||||||||
10099 | BinaryOperator *BinOp = nullptr; | ||||||||
10100 | if (IsUpdateExprFound) { | ||||||||
10101 | BinOp = dyn_cast<BinaryOperator>(First); | ||||||||
10102 | IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; | ||||||||
10103 | } | ||||||||
10104 | if (IsUpdateExprFound && !CurContext->isDependentContext()) { | ||||||||
10105 | // { v = x; x++; } | ||||||||
10106 | // { v = x; x--; } | ||||||||
10107 | // { v = x; ++x; } | ||||||||
10108 | // { v = x; --x; } | ||||||||
10109 | // { v = x; x binop= expr; } | ||||||||
10110 | // { v = x; x = x binop expr; } | ||||||||
10111 | // { v = x; x = expr binop x; } | ||||||||
10112 | // Check that the first expression has form v = x. | ||||||||
10113 | Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); | ||||||||
10114 | llvm::FoldingSetNodeID XId, PossibleXId; | ||||||||
10115 | Checker.getX()->Profile(XId, Context, /*Canonical=*/true); | ||||||||
10116 | PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); | ||||||||
10117 | IsUpdateExprFound = XId == PossibleXId; | ||||||||
10118 | if (IsUpdateExprFound) { | ||||||||
10119 | V = BinOp->getLHS(); | ||||||||
10120 | X = Checker.getX(); | ||||||||
10121 | E = Checker.getExpr(); | ||||||||
10122 | UE = Checker.getUpdateExpr(); | ||||||||
10123 | IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); | ||||||||
10124 | IsPostfixUpdate = true; | ||||||||
10125 | } | ||||||||
10126 | } | ||||||||
10127 | if (!IsUpdateExprFound) { | ||||||||
10128 | IsUpdateExprFound = !Checker.checkStatement(First); | ||||||||
10129 | BinOp = nullptr; | ||||||||
10130 | if (IsUpdateExprFound) { | ||||||||
10131 | BinOp = dyn_cast<BinaryOperator>(Second); | ||||||||
10132 | IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; | ||||||||
10133 | } | ||||||||
10134 | if (IsUpdateExprFound && !CurContext->isDependentContext()) { | ||||||||
10135 | // { x++; v = x; } | ||||||||
10136 | // { x--; v = x; } | ||||||||
10137 | // { ++x; v = x; } | ||||||||
10138 | // { --x; v = x; } | ||||||||
10139 | // { x binop= expr; v = x; } | ||||||||
10140 | // { x = x binop expr; v = x; } | ||||||||
10141 | // { x = expr binop x; v = x; } | ||||||||
10142 | // Check that the second expression has form v = x. | ||||||||
10143 | Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); | ||||||||
10144 | llvm::FoldingSetNodeID XId, PossibleXId; | ||||||||
10145 | Checker.getX()->Profile(XId, Context, /*Canonical=*/true); | ||||||||
10146 | PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); | ||||||||
10147 | IsUpdateExprFound = XId == PossibleXId; | ||||||||
10148 | if (IsUpdateExprFound) { | ||||||||
10149 | V = BinOp->getLHS(); | ||||||||
10150 | X = Checker.getX(); | ||||||||
10151 | E = Checker.getExpr(); | ||||||||
10152 | UE = Checker.getUpdateExpr(); | ||||||||
10153 | IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); | ||||||||
10154 | IsPostfixUpdate = false; | ||||||||
10155 | } | ||||||||
10156 | } | ||||||||
10157 | } | ||||||||
10158 | if (!IsUpdateExprFound) { | ||||||||
10159 | // { v = x; x = expr; } | ||||||||
10160 | auto *FirstExpr = dyn_cast<Expr>(First); | ||||||||
10161 | auto *SecondExpr = dyn_cast<Expr>(Second); | ||||||||
10162 | if (!FirstExpr || !SecondExpr || | ||||||||
10163 | !(FirstExpr->isInstantiationDependent() || | ||||||||
10164 | SecondExpr->isInstantiationDependent())) { | ||||||||
10165 | auto *FirstBinOp = dyn_cast<BinaryOperator>(First); | ||||||||
10166 | if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { | ||||||||
10167 | ErrorFound = NotAnAssignmentOp; | ||||||||
10168 | NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() | ||||||||
10169 | : First->getBeginLoc(); | ||||||||
10170 | NoteRange = ErrorRange = FirstBinOp | ||||||||
10171 | ? FirstBinOp->getSourceRange() | ||||||||
10172 | : SourceRange(ErrorLoc, ErrorLoc); | ||||||||
10173 | } else { | ||||||||
10174 | auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); | ||||||||
10175 | if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { | ||||||||
10176 | ErrorFound = NotAnAssignmentOp; | ||||||||
10177 | NoteLoc = ErrorLoc = SecondBinOp | ||||||||
10178 | ? SecondBinOp->getOperatorLoc() | ||||||||
10179 | : Second->getBeginLoc(); | ||||||||
10180 | NoteRange = ErrorRange = | ||||||||
10181 | SecondBinOp ? SecondBinOp->getSourceRange() | ||||||||
10182 | : SourceRange(ErrorLoc, ErrorLoc); | ||||||||
10183 | } else { | ||||||||
10184 | Expr *PossibleXRHSInFirst = | ||||||||
10185 | FirstBinOp->getRHS()->IgnoreParenImpCasts(); | ||||||||
10186 | Expr *PossibleXLHSInSecond = | ||||||||
10187 | SecondBinOp->getLHS()->IgnoreParenImpCasts(); | ||||||||
10188 | llvm::FoldingSetNodeID X1Id, X2Id; | ||||||||
10189 | PossibleXRHSInFirst->Profile(X1Id, Context, | ||||||||
10190 | /*Canonical=*/true); | ||||||||
10191 | PossibleXLHSInSecond->Profile(X2Id, Context, | ||||||||
10192 | /*Canonical=*/true); | ||||||||
10193 | IsUpdateExprFound = X1Id == X2Id; | ||||||||
10194 | if (IsUpdateExprFound) { | ||||||||
10195 | V = FirstBinOp->getLHS(); | ||||||||
10196 | X = SecondBinOp->getLHS(); | ||||||||
10197 | E = SecondBinOp->getRHS(); | ||||||||
10198 | UE = nullptr; | ||||||||
10199 | IsXLHSInRHSPart = false; | ||||||||
10200 | IsPostfixUpdate = true; | ||||||||
10201 | } else { | ||||||||
10202 | ErrorFound = NotASpecificExpression; | ||||||||
10203 | ErrorLoc = FirstBinOp->getExprLoc(); | ||||||||
10204 | ErrorRange = FirstBinOp->getSourceRange(); | ||||||||
10205 | NoteLoc = SecondBinOp->getLHS()->getExprLoc(); | ||||||||
10206 | NoteRange = SecondBinOp->getRHS()->getSourceRange(); | ||||||||
10207 | } | ||||||||
10208 | } | ||||||||
10209 | } | ||||||||
10210 | } | ||||||||
10211 | } | ||||||||
10212 | } else { | ||||||||
10213 | NoteLoc = ErrorLoc = Body->getBeginLoc(); | ||||||||
10214 | NoteRange = ErrorRange = | ||||||||
10215 | SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); | ||||||||
10216 | ErrorFound = NotTwoSubstatements; | ||||||||
10217 | } | ||||||||
10218 | } else { | ||||||||
10219 | NoteLoc = ErrorLoc = Body->getBeginLoc(); | ||||||||
10220 | NoteRange = ErrorRange = | ||||||||
10221 | SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); | ||||||||
10222 | ErrorFound = NotACompoundStatement; | ||||||||
10223 | } | ||||||||
10224 | if (ErrorFound != NoError) { | ||||||||
10225 | Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) | ||||||||
10226 | << ErrorRange; | ||||||||
10227 | Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; | ||||||||
10228 | return StmtError(); | ||||||||
10229 | } | ||||||||
10230 | if (CurContext->isDependentContext()) | ||||||||
10231 | UE = V = E = X = nullptr; | ||||||||
10232 | } | ||||||||
10233 | } | ||||||||
10234 | |||||||||
10235 | setFunctionHasBranchProtectedScope(); | ||||||||
10236 | |||||||||
10237 | return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, | ||||||||
10238 | X, V, E, UE, IsXLHSInRHSPart, | ||||||||
10239 | IsPostfixUpdate); | ||||||||
10240 | } | ||||||||
10241 | |||||||||
10242 | StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, | ||||||||
10243 | Stmt *AStmt, | ||||||||
10244 | SourceLocation StartLoc, | ||||||||
10245 | SourceLocation EndLoc) { | ||||||||
10246 | if (!AStmt) | ||||||||
10247 | return StmtError(); | ||||||||
10248 | |||||||||
10249 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
10250 | // 1.2.2 OpenMP Language Terminology | ||||||||
10251 | // Structured block - An executable statement with a single entry at the | ||||||||
10252 | // top and a single exit at the bottom. | ||||||||
10253 | // The point of exit cannot be a branch out of the structured block. | ||||||||
10254 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
10255 | CS->getCapturedDecl()->setNothrow(); | ||||||||
10256 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); | ||||||||
10257 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||||
10258 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||||
10259 | // 1.2.2 OpenMP Language Terminology | ||||||||
10260 | // Structured block - An executable statement with a single entry at the | ||||||||
10261 | // top and a single exit at the bottom. | ||||||||
10262 | // The point of exit cannot be a branch out of the structured block. | ||||||||
10263 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
10264 | CS->getCapturedDecl()->setNothrow(); | ||||||||
10265 | } | ||||||||
10266 | |||||||||
10267 | // OpenMP [2.16, Nesting of Regions] | ||||||||
10268 | // If specified, a teams construct must be contained within a target | ||||||||
10269 | // construct. That target construct must contain no statements or directives | ||||||||
10270 | // outside of the teams construct. | ||||||||
10271 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasInnerTeamsRegion()) { | ||||||||
10272 | const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); | ||||||||
10273 | bool OMPTeamsFound = true; | ||||||||
10274 | if (const auto *CS = dyn_cast<CompoundStmt>(S)) { | ||||||||
10275 | auto I = CS->body_begin(); | ||||||||
10276 | while (I != CS->body_end()) { | ||||||||
10277 | const auto *OED = dyn_cast<OMPExecutableDirective>(*I); | ||||||||
10278 | if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || | ||||||||
10279 | OMPTeamsFound) { | ||||||||
10280 | |||||||||
10281 | OMPTeamsFound = false; | ||||||||
10282 | break; | ||||||||
10283 | } | ||||||||
10284 | ++I; | ||||||||
10285 | } | ||||||||
10286 | 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\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 10286, __PRETTY_FUNCTION__)); | ||||||||
10287 | S = *I; | ||||||||
10288 | } else { | ||||||||
10289 | const auto *OED = dyn_cast<OMPExecutableDirective>(S); | ||||||||
10290 | OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); | ||||||||
10291 | } | ||||||||
10292 | if (!OMPTeamsFound) { | ||||||||
10293 | Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); | ||||||||
10294 | Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getInnerTeamsRegionLoc(), | ||||||||
10295 | diag::note_omp_nested_teams_construct_here); | ||||||||
10296 | Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) | ||||||||
10297 | << isa<OMPExecutableDirective>(S); | ||||||||
10298 | return StmtError(); | ||||||||
10299 | } | ||||||||
10300 | } | ||||||||
10301 | |||||||||
10302 | setFunctionHasBranchProtectedScope(); | ||||||||
10303 | |||||||||
10304 | return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); | ||||||||
10305 | } | ||||||||
10306 | |||||||||
10307 | StmtResult | ||||||||
10308 | Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, | ||||||||
10309 | Stmt *AStmt, SourceLocation StartLoc, | ||||||||
10310 | SourceLocation EndLoc) { | ||||||||
10311 | if (!AStmt) | ||||||||
10312 | return StmtError(); | ||||||||
10313 | |||||||||
10314 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
10315 | // 1.2.2 OpenMP Language Terminology | ||||||||
10316 | // Structured block - An executable statement with a single entry at the | ||||||||
10317 | // top and a single exit at the bottom. | ||||||||
10318 | // The point of exit cannot be a branch out of the structured block. | ||||||||
10319 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
10320 | CS->getCapturedDecl()->setNothrow(); | ||||||||
10321 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); | ||||||||
10322 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||||
10323 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||||
10324 | // 1.2.2 OpenMP Language Terminology | ||||||||
10325 | // Structured block - An executable statement with a single entry at the | ||||||||
10326 | // top and a single exit at the bottom. | ||||||||
10327 | // The point of exit cannot be a branch out of the structured block. | ||||||||
10328 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
10329 | CS->getCapturedDecl()->setNothrow(); | ||||||||
10330 | } | ||||||||
10331 | |||||||||
10332 | setFunctionHasBranchProtectedScope(); | ||||||||
10333 | |||||||||
10334 | return OMPTargetParallelDirective::Create( | ||||||||
10335 | Context, StartLoc, EndLoc, Clauses, AStmt, | ||||||||
10336 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||||
10337 | } | ||||||||
10338 | |||||||||
10339 | StmtResult Sema::ActOnOpenMPTargetParallelForDirective( | ||||||||
10340 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||||
10341 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||||
10342 | if (!AStmt) | ||||||||
10343 | return StmtError(); | ||||||||
10344 | |||||||||
10345 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
10346 | // 1.2.2 OpenMP Language Terminology | ||||||||
10347 | // Structured block - An executable statement with a single entry at the | ||||||||
10348 | // top and a single exit at the bottom. | ||||||||
10349 | // The point of exit cannot be a branch out of the structured block. | ||||||||
10350 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
10351 | CS->getCapturedDecl()->setNothrow(); | ||||||||
10352 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); | ||||||||
10353 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||||
10354 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||||
10355 | // 1.2.2 OpenMP Language Terminology | ||||||||
10356 | // Structured block - An executable statement with a single entry at the | ||||||||
10357 | // top and a single exit at the bottom. | ||||||||
10358 | // The point of exit cannot be a branch out of the structured block. | ||||||||
10359 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
10360 | CS->getCapturedDecl()->setNothrow(); | ||||||||
10361 | } | ||||||||
10362 | |||||||||
10363 | OMPLoopDirective::HelperExprs B; | ||||||||
10364 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||||||
10365 | // define the nested loops number. | ||||||||
10366 | unsigned NestedLoopCount = | ||||||||
10367 | checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), | ||||||||
10368 | getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||||
10369 | VarsWithImplicitDSA, B); | ||||||||
10370 | if (NestedLoopCount == 0) | ||||||||
10371 | return StmtError(); | ||||||||
10372 | |||||||||
10373 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp target parallel for loop exprs were not built") ? static_cast <void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 10374, __PRETTY_FUNCTION__)) | ||||||||
10374 | "omp target parallel for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp target parallel for loop exprs were not built") ? static_cast <void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 10374, __PRETTY_FUNCTION__)); | ||||||||
10375 | |||||||||
10376 | if (!CurContext->isDependentContext()) { | ||||||||
10377 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||||
10378 | for (OMPClause *C : Clauses) { | ||||||||
10379 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||||
10380 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||||
10381 | B.NumIterations, *this, CurScope, | ||||||||
10382 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||||
10383 | return StmtError(); | ||||||||
10384 | } | ||||||||
10385 | } | ||||||||
10386 | |||||||||
10387 | setFunctionHasBranchProtectedScope(); | ||||||||
10388 | return OMPTargetParallelForDirective::Create( | ||||||||
10389 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, | ||||||||
10390 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||||
10391 | } | ||||||||
10392 | |||||||||
10393 | /// Check for existence of a map clause in the list of clauses. | ||||||||
10394 | static bool hasClauses(ArrayRef<OMPClause *> Clauses, | ||||||||
10395 | const OpenMPClauseKind K) { | ||||||||
10396 | return llvm::any_of( | ||||||||
10397 | Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); | ||||||||
10398 | } | ||||||||
10399 | |||||||||
10400 | template <typename... Params> | ||||||||
10401 | static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, | ||||||||
10402 | const Params... ClauseTypes) { | ||||||||
10403 | return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); | ||||||||
10404 | } | ||||||||
10405 | |||||||||
10406 | StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, | ||||||||
10407 | Stmt *AStmt, | ||||||||
10408 | SourceLocation StartLoc, | ||||||||
10409 | SourceLocation EndLoc) { | ||||||||
10410 | if (!AStmt) | ||||||||
10411 | return StmtError(); | ||||||||
10412 | |||||||||
10413 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 10413, __PRETTY_FUNCTION__)); | ||||||||
10414 | |||||||||
10415 | // OpenMP [2.12.2, target data Construct, Restrictions] | ||||||||
10416 | // At least one map, use_device_addr or use_device_ptr clause must appear on | ||||||||
10417 | // the directive. | ||||||||
10418 | if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) && | ||||||||
10419 | (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) { | ||||||||
10420 | StringRef Expected; | ||||||||
10421 | if (LangOpts.OpenMP < 50) | ||||||||
10422 | Expected = "'map' or 'use_device_ptr'"; | ||||||||
10423 | else | ||||||||
10424 | Expected = "'map', 'use_device_ptr', or 'use_device_addr'"; | ||||||||
10425 | Diag(StartLoc, diag::err_omp_no_clause_for_directive) | ||||||||
10426 | << Expected << getOpenMPDirectiveName(OMPD_target_data); | ||||||||
10427 | return StmtError(); | ||||||||
10428 | } | ||||||||
10429 | |||||||||
10430 | setFunctionHasBranchProtectedScope(); | ||||||||
10431 | |||||||||
10432 | return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, | ||||||||
10433 | AStmt); | ||||||||
10434 | } | ||||||||
10435 | |||||||||
10436 | StmtResult | ||||||||
10437 | Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, | ||||||||
10438 | SourceLocation StartLoc, | ||||||||
10439 | SourceLocation EndLoc, Stmt *AStmt) { | ||||||||
10440 | if (!AStmt) | ||||||||
10441 | return StmtError(); | ||||||||
10442 | |||||||||
10443 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
10444 | // 1.2.2 OpenMP Language Terminology | ||||||||
10445 | // Structured block - An executable statement with a single entry at the | ||||||||
10446 | // top and a single exit at the bottom. | ||||||||
10447 | // The point of exit cannot be a branch out of the structured block. | ||||||||
10448 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
10449 | CS->getCapturedDecl()->setNothrow(); | ||||||||
10450 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); | ||||||||
10451 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||||
10452 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||||
10453 | // 1.2.2 OpenMP Language Terminology | ||||||||
10454 | // Structured block - An executable statement with a single entry at the | ||||||||
10455 | // top and a single exit at the bottom. | ||||||||
10456 | // The point of exit cannot be a branch out of the structured block. | ||||||||
10457 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
10458 | CS->getCapturedDecl()->setNothrow(); | ||||||||
10459 | } | ||||||||
10460 | |||||||||
10461 | // OpenMP [2.10.2, Restrictions, p. 99] | ||||||||
10462 | // At least one map clause must appear on the directive. | ||||||||
10463 | if (!hasClauses(Clauses, OMPC_map)) { | ||||||||
10464 | Diag(StartLoc, diag::err_omp_no_clause_for_directive) | ||||||||
10465 | << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); | ||||||||
10466 | return StmtError(); | ||||||||
10467 | } | ||||||||
10468 | |||||||||
10469 | return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, | ||||||||
10470 | AStmt); | ||||||||
10471 | } | ||||||||
10472 | |||||||||
10473 | StmtResult | ||||||||
10474 | Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, | ||||||||
10475 | SourceLocation StartLoc, | ||||||||
10476 | SourceLocation EndLoc, Stmt *AStmt) { | ||||||||
10477 | if (!AStmt) | ||||||||
10478 | return StmtError(); | ||||||||
10479 | |||||||||
10480 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
10481 | // 1.2.2 OpenMP Language Terminology | ||||||||
10482 | // Structured block - An executable statement with a single entry at the | ||||||||
10483 | // top and a single exit at the bottom. | ||||||||
10484 | // The point of exit cannot be a branch out of the structured block. | ||||||||
10485 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
10486 | CS->getCapturedDecl()->setNothrow(); | ||||||||
10487 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); | ||||||||
10488 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||||
10489 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||||
10490 | // 1.2.2 OpenMP Language Terminology | ||||||||
10491 | // Structured block - An executable statement with a single entry at the | ||||||||
10492 | // top and a single exit at the bottom. | ||||||||
10493 | // The point of exit cannot be a branch out of the structured block. | ||||||||
10494 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
10495 | CS->getCapturedDecl()->setNothrow(); | ||||||||
10496 | } | ||||||||
10497 | |||||||||
10498 | // OpenMP [2.10.3, Restrictions, p. 102] | ||||||||
10499 | // At least one map clause must appear on the directive. | ||||||||
10500 | if (!hasClauses(Clauses, OMPC_map)) { | ||||||||
10501 | Diag(StartLoc, diag::err_omp_no_clause_for_directive) | ||||||||
10502 | << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); | ||||||||
10503 | return StmtError(); | ||||||||
10504 | } | ||||||||
10505 | |||||||||
10506 | return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, | ||||||||
10507 | AStmt); | ||||||||
10508 | } | ||||||||
10509 | |||||||||
10510 | StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, | ||||||||
10511 | SourceLocation StartLoc, | ||||||||
10512 | SourceLocation EndLoc, | ||||||||
10513 | Stmt *AStmt) { | ||||||||
10514 | if (!AStmt) | ||||||||
10515 | return StmtError(); | ||||||||
10516 | |||||||||
10517 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
10518 | // 1.2.2 OpenMP Language Terminology | ||||||||
10519 | // Structured block - An executable statement with a single entry at the | ||||||||
10520 | // top and a single exit at the bottom. | ||||||||
10521 | // The point of exit cannot be a branch out of the structured block. | ||||||||
10522 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
10523 | CS->getCapturedDecl()->setNothrow(); | ||||||||
10524 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); | ||||||||
10525 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||||
10526 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||||
10527 | // 1.2.2 OpenMP Language Terminology | ||||||||
10528 | // Structured block - An executable statement with a single entry at the | ||||||||
10529 | // top and a single exit at the bottom. | ||||||||
10530 | // The point of exit cannot be a branch out of the structured block. | ||||||||
10531 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
10532 | CS->getCapturedDecl()->setNothrow(); | ||||||||
10533 | } | ||||||||
10534 | |||||||||
10535 | if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { | ||||||||
10536 | Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); | ||||||||
10537 | return StmtError(); | ||||||||
10538 | } | ||||||||
10539 | return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, | ||||||||
10540 | AStmt); | ||||||||
10541 | } | ||||||||
10542 | |||||||||
10543 | StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, | ||||||||
10544 | Stmt *AStmt, SourceLocation StartLoc, | ||||||||
10545 | SourceLocation EndLoc) { | ||||||||
10546 | if (!AStmt) | ||||||||
10547 | return StmtError(); | ||||||||
10548 | |||||||||
10549 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
10550 | // 1.2.2 OpenMP Language Terminology | ||||||||
10551 | // Structured block - An executable statement with a single entry at the | ||||||||
10552 | // top and a single exit at the bottom. | ||||||||
10553 | // The point of exit cannot be a branch out of the structured block. | ||||||||
10554 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
10555 | CS->getCapturedDecl()->setNothrow(); | ||||||||
10556 | |||||||||
10557 | setFunctionHasBranchProtectedScope(); | ||||||||
10558 | |||||||||
10559 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentTeamsRegionLoc(StartLoc); | ||||||||
10560 | |||||||||
10561 | return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); | ||||||||
10562 | } | ||||||||
10563 | |||||||||
10564 | StmtResult | ||||||||
10565 | Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, | ||||||||
10566 | SourceLocation EndLoc, | ||||||||
10567 | OpenMPDirectiveKind CancelRegion) { | ||||||||
10568 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isParentNowaitRegion()) { | ||||||||
10569 | Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; | ||||||||
10570 | return StmtError(); | ||||||||
10571 | } | ||||||||
10572 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isParentOrderedRegion()) { | ||||||||
10573 | Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; | ||||||||
10574 | return StmtError(); | ||||||||
10575 | } | ||||||||
10576 | return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, | ||||||||
10577 | CancelRegion); | ||||||||
10578 | } | ||||||||
10579 | |||||||||
10580 | StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, | ||||||||
10581 | SourceLocation StartLoc, | ||||||||
10582 | SourceLocation EndLoc, | ||||||||
10583 | OpenMPDirectiveKind CancelRegion) { | ||||||||
10584 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isParentNowaitRegion()) { | ||||||||
10585 | Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; | ||||||||
10586 | return StmtError(); | ||||||||
10587 | } | ||||||||
10588 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isParentOrderedRegion()) { | ||||||||
10589 | Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; | ||||||||
10590 | return StmtError(); | ||||||||
10591 | } | ||||||||
10592 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentCancelRegion(/*Cancel=*/true); | ||||||||
10593 | return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, | ||||||||
10594 | CancelRegion); | ||||||||
10595 | } | ||||||||
10596 | |||||||||
10597 | static bool checkGrainsizeNumTasksClauses(Sema &S, | ||||||||
10598 | ArrayRef<OMPClause *> Clauses) { | ||||||||
10599 | const OMPClause *PrevClause = nullptr; | ||||||||
10600 | bool ErrorFound = false; | ||||||||
10601 | for (const OMPClause *C : Clauses) { | ||||||||
10602 | if (C->getClauseKind() == OMPC_grainsize || | ||||||||
10603 | C->getClauseKind() == OMPC_num_tasks) { | ||||||||
10604 | if (!PrevClause) | ||||||||
10605 | PrevClause = C; | ||||||||
10606 | else if (PrevClause->getClauseKind() != C->getClauseKind()) { | ||||||||
10607 | S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) | ||||||||
10608 | << getOpenMPClauseName(C->getClauseKind()) | ||||||||
10609 | << getOpenMPClauseName(PrevClause->getClauseKind()); | ||||||||
10610 | S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) | ||||||||
10611 | << getOpenMPClauseName(PrevClause->getClauseKind()); | ||||||||
10612 | ErrorFound = true; | ||||||||
10613 | } | ||||||||
10614 | } | ||||||||
10615 | } | ||||||||
10616 | return ErrorFound; | ||||||||
10617 | } | ||||||||
10618 | |||||||||
10619 | static bool checkReductionClauseWithNogroup(Sema &S, | ||||||||
10620 | ArrayRef<OMPClause *> Clauses) { | ||||||||
10621 | const OMPClause *ReductionClause = nullptr; | ||||||||
10622 | const OMPClause *NogroupClause = nullptr; | ||||||||
10623 | for (const OMPClause *C : Clauses) { | ||||||||
10624 | if (C->getClauseKind() == OMPC_reduction) { | ||||||||
10625 | ReductionClause = C; | ||||||||
10626 | if (NogroupClause) | ||||||||
10627 | break; | ||||||||
10628 | continue; | ||||||||
10629 | } | ||||||||
10630 | if (C->getClauseKind() == OMPC_nogroup) { | ||||||||
10631 | NogroupClause = C; | ||||||||
10632 | if (ReductionClause) | ||||||||
10633 | break; | ||||||||
10634 | continue; | ||||||||
10635 | } | ||||||||
10636 | } | ||||||||
10637 | if (ReductionClause && NogroupClause) { | ||||||||
10638 | S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) | ||||||||
10639 | << SourceRange(NogroupClause->getBeginLoc(), | ||||||||
10640 | NogroupClause->getEndLoc()); | ||||||||
10641 | return true; | ||||||||
10642 | } | ||||||||
10643 | return false; | ||||||||
10644 | } | ||||||||
10645 | |||||||||
10646 | StmtResult Sema::ActOnOpenMPTaskLoopDirective( | ||||||||
10647 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||||
10648 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||||
10649 | if (!AStmt) | ||||||||
10650 | return StmtError(); | ||||||||
10651 | |||||||||
10652 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 10652, __PRETTY_FUNCTION__)); | ||||||||
10653 | OMPLoopDirective::HelperExprs B; | ||||||||
10654 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||||||
10655 | // define the nested loops number. | ||||||||
10656 | unsigned NestedLoopCount = | ||||||||
10657 | checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), | ||||||||
10658 | /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||||
10659 | VarsWithImplicitDSA, B); | ||||||||
10660 | if (NestedLoopCount == 0) | ||||||||
10661 | return StmtError(); | ||||||||
10662 | |||||||||
10663 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 10664, __PRETTY_FUNCTION__)) | ||||||||
10664 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 10664, __PRETTY_FUNCTION__)); | ||||||||
10665 | |||||||||
10666 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] | ||||||||
10667 | // The grainsize clause and num_tasks clause are mutually exclusive and may | ||||||||
10668 | // not appear on the same taskloop directive. | ||||||||
10669 | if (checkGrainsizeNumTasksClauses(*this, Clauses)) | ||||||||
10670 | return StmtError(); | ||||||||
10671 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] | ||||||||
10672 | // If a reduction clause is present on the taskloop directive, the nogroup | ||||||||
10673 | // clause must not be specified. | ||||||||
10674 | if (checkReductionClauseWithNogroup(*this, Clauses)) | ||||||||
10675 | return StmtError(); | ||||||||
10676 | |||||||||
10677 | setFunctionHasBranchProtectedScope(); | ||||||||
10678 | return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, | ||||||||
10679 | NestedLoopCount, Clauses, AStmt, B, | ||||||||
10680 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||||
10681 | } | ||||||||
10682 | |||||||||
10683 | StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( | ||||||||
10684 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||||
10685 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||||
10686 | if (!AStmt) | ||||||||
10687 | return StmtError(); | ||||||||
10688 | |||||||||
10689 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 10689, __PRETTY_FUNCTION__)); | ||||||||
10690 | OMPLoopDirective::HelperExprs B; | ||||||||
10691 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||||||
10692 | // define the nested loops number. | ||||||||
10693 | unsigned NestedLoopCount = | ||||||||
10694 | checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), | ||||||||
10695 | /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||||
10696 | VarsWithImplicitDSA, B); | ||||||||
10697 | if (NestedLoopCount == 0) | ||||||||
10698 | return StmtError(); | ||||||||
10699 | |||||||||
10700 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 10701, __PRETTY_FUNCTION__)) | ||||||||
10701 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 10701, __PRETTY_FUNCTION__)); | ||||||||
10702 | |||||||||
10703 | if (!CurContext->isDependentContext()) { | ||||||||
10704 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||||
10705 | for (OMPClause *C : Clauses) { | ||||||||
10706 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||||
10707 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||||
10708 | B.NumIterations, *this, CurScope, | ||||||||
10709 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||||
10710 | return StmtError(); | ||||||||
10711 | } | ||||||||
10712 | } | ||||||||
10713 | |||||||||
10714 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] | ||||||||
10715 | // The grainsize clause and num_tasks clause are mutually exclusive and may | ||||||||
10716 | // not appear on the same taskloop directive. | ||||||||
10717 | if (checkGrainsizeNumTasksClauses(*this, Clauses)) | ||||||||
10718 | return StmtError(); | ||||||||
10719 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] | ||||||||
10720 | // If a reduction clause is present on the taskloop directive, the nogroup | ||||||||
10721 | // clause must not be specified. | ||||||||
10722 | if (checkReductionClauseWithNogroup(*this, Clauses)) | ||||||||
10723 | return StmtError(); | ||||||||
10724 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||||
10725 | return StmtError(); | ||||||||
10726 | |||||||||
10727 | setFunctionHasBranchProtectedScope(); | ||||||||
10728 | return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, | ||||||||
10729 | NestedLoopCount, Clauses, AStmt, B); | ||||||||
10730 | } | ||||||||
10731 | |||||||||
10732 | StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( | ||||||||
10733 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||||
10734 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||||
10735 | if (!AStmt) | ||||||||
10736 | return StmtError(); | ||||||||
10737 | |||||||||
10738 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 10738, __PRETTY_FUNCTION__)); | ||||||||
10739 | OMPLoopDirective::HelperExprs B; | ||||||||
10740 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||||||
10741 | // define the nested loops number. | ||||||||
10742 | unsigned NestedLoopCount = | ||||||||
10743 | checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), | ||||||||
10744 | /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||||
10745 | VarsWithImplicitDSA, B); | ||||||||
10746 | if (NestedLoopCount == 0) | ||||||||
10747 | return StmtError(); | ||||||||
10748 | |||||||||
10749 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 10750, __PRETTY_FUNCTION__)) | ||||||||
10750 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 10750, __PRETTY_FUNCTION__)); | ||||||||
10751 | |||||||||
10752 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] | ||||||||
10753 | // The grainsize clause and num_tasks clause are mutually exclusive and may | ||||||||
10754 | // not appear on the same taskloop directive. | ||||||||
10755 | if (checkGrainsizeNumTasksClauses(*this, Clauses)) | ||||||||
10756 | return StmtError(); | ||||||||
10757 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] | ||||||||
10758 | // If a reduction clause is present on the taskloop directive, the nogroup | ||||||||
10759 | // clause must not be specified. | ||||||||
10760 | if (checkReductionClauseWithNogroup(*this, Clauses)) | ||||||||
10761 | return StmtError(); | ||||||||
10762 | |||||||||
10763 | setFunctionHasBranchProtectedScope(); | ||||||||
10764 | return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, | ||||||||
10765 | NestedLoopCount, Clauses, AStmt, B, | ||||||||
10766 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||||
10767 | } | ||||||||
10768 | |||||||||
10769 | StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( | ||||||||
10770 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||||
10771 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||||
10772 | if (!AStmt) | ||||||||
10773 | return StmtError(); | ||||||||
10774 | |||||||||
10775 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 10775, __PRETTY_FUNCTION__)); | ||||||||
10776 | OMPLoopDirective::HelperExprs B; | ||||||||
10777 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||||||
10778 | // define the nested loops number. | ||||||||
10779 | unsigned NestedLoopCount = | ||||||||
10780 | checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), | ||||||||
10781 | /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||||
10782 | VarsWithImplicitDSA, B); | ||||||||
10783 | if (NestedLoopCount == 0) | ||||||||
10784 | return StmtError(); | ||||||||
10785 | |||||||||
10786 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 10787, __PRETTY_FUNCTION__)) | ||||||||
10787 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 10787, __PRETTY_FUNCTION__)); | ||||||||
10788 | |||||||||
10789 | if (!CurContext->isDependentContext()) { | ||||||||
10790 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||||
10791 | for (OMPClause *C : Clauses) { | ||||||||
10792 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||||
10793 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||||
10794 | B.NumIterations, *this, CurScope, | ||||||||
10795 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||||
10796 | return StmtError(); | ||||||||
10797 | } | ||||||||
10798 | } | ||||||||
10799 | |||||||||
10800 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] | ||||||||
10801 | // The grainsize clause and num_tasks clause are mutually exclusive and may | ||||||||
10802 | // not appear on the same taskloop directive. | ||||||||
10803 | if (checkGrainsizeNumTasksClauses(*this, Clauses)) | ||||||||
10804 | return StmtError(); | ||||||||
10805 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] | ||||||||
10806 | // If a reduction clause is present on the taskloop directive, the nogroup | ||||||||
10807 | // clause must not be specified. | ||||||||
10808 | if (checkReductionClauseWithNogroup(*this, Clauses)) | ||||||||
10809 | return StmtError(); | ||||||||
10810 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||||
10811 | return StmtError(); | ||||||||
10812 | |||||||||
10813 | setFunctionHasBranchProtectedScope(); | ||||||||
10814 | return OMPMasterTaskLoopSimdDirective::Create( | ||||||||
10815 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||||||
10816 | } | ||||||||
10817 | |||||||||
10818 | StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( | ||||||||
10819 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||||
10820 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||||
10821 | if (!AStmt) | ||||||||
10822 | return StmtError(); | ||||||||
10823 | |||||||||
10824 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 10824, __PRETTY_FUNCTION__)); | ||||||||
10825 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
10826 | // 1.2.2 OpenMP Language Terminology | ||||||||
10827 | // Structured block - An executable statement with a single entry at the | ||||||||
10828 | // top and a single exit at the bottom. | ||||||||
10829 | // The point of exit cannot be a branch out of the structured block. | ||||||||
10830 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
10831 | CS->getCapturedDecl()->setNothrow(); | ||||||||
10832 | for (int ThisCaptureLevel = | ||||||||
10833 | getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); | ||||||||
10834 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||||
10835 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||||
10836 | // 1.2.2 OpenMP Language Terminology | ||||||||
10837 | // Structured block - An executable statement with a single entry at the | ||||||||
10838 | // top and a single exit at the bottom. | ||||||||
10839 | // The point of exit cannot be a branch out of the structured block. | ||||||||
10840 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
10841 | CS->getCapturedDecl()->setNothrow(); | ||||||||
10842 | } | ||||||||
10843 | |||||||||
10844 | OMPLoopDirective::HelperExprs B; | ||||||||
10845 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||||||
10846 | // define the nested loops number. | ||||||||
10847 | unsigned NestedLoopCount = checkOpenMPLoop( | ||||||||
10848 | OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), | ||||||||
10849 | /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||||
10850 | VarsWithImplicitDSA, B); | ||||||||
10851 | if (NestedLoopCount == 0) | ||||||||
10852 | return StmtError(); | ||||||||
10853 | |||||||||
10854 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 10855, __PRETTY_FUNCTION__)) | ||||||||
10855 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 10855, __PRETTY_FUNCTION__)); | ||||||||
10856 | |||||||||
10857 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] | ||||||||
10858 | // The grainsize clause and num_tasks clause are mutually exclusive and may | ||||||||
10859 | // not appear on the same taskloop directive. | ||||||||
10860 | if (checkGrainsizeNumTasksClauses(*this, Clauses)) | ||||||||
10861 | return StmtError(); | ||||||||
10862 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] | ||||||||
10863 | // If a reduction clause is present on the taskloop directive, the nogroup | ||||||||
10864 | // clause must not be specified. | ||||||||
10865 | if (checkReductionClauseWithNogroup(*this, Clauses)) | ||||||||
10866 | return StmtError(); | ||||||||
10867 | |||||||||
10868 | setFunctionHasBranchProtectedScope(); | ||||||||
10869 | return OMPParallelMasterTaskLoopDirective::Create( | ||||||||
10870 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, | ||||||||
10871 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||||
10872 | } | ||||||||
10873 | |||||||||
10874 | StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( | ||||||||
10875 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||||
10876 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||||
10877 | if (!AStmt) | ||||||||
10878 | return StmtError(); | ||||||||
10879 | |||||||||
10880 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 10880, __PRETTY_FUNCTION__)); | ||||||||
10881 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
10882 | // 1.2.2 OpenMP Language Terminology | ||||||||
10883 | // Structured block - An executable statement with a single entry at the | ||||||||
10884 | // top and a single exit at the bottom. | ||||||||
10885 | // The point of exit cannot be a branch out of the structured block. | ||||||||
10886 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
10887 | CS->getCapturedDecl()->setNothrow(); | ||||||||
10888 | for (int ThisCaptureLevel = | ||||||||
10889 | getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); | ||||||||
10890 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||||
10891 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||||
10892 | // 1.2.2 OpenMP Language Terminology | ||||||||
10893 | // Structured block - An executable statement with a single entry at the | ||||||||
10894 | // top and a single exit at the bottom. | ||||||||
10895 | // The point of exit cannot be a branch out of the structured block. | ||||||||
10896 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
10897 | CS->getCapturedDecl()->setNothrow(); | ||||||||
10898 | } | ||||||||
10899 | |||||||||
10900 | OMPLoopDirective::HelperExprs B; | ||||||||
10901 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||||||
10902 | // define the nested loops number. | ||||||||
10903 | unsigned NestedLoopCount = checkOpenMPLoop( | ||||||||
10904 | OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), | ||||||||
10905 | /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||||
10906 | VarsWithImplicitDSA, B); | ||||||||
10907 | if (NestedLoopCount == 0) | ||||||||
10908 | return StmtError(); | ||||||||
10909 | |||||||||
10910 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 10911, __PRETTY_FUNCTION__)) | ||||||||
10911 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 10911, __PRETTY_FUNCTION__)); | ||||||||
10912 | |||||||||
10913 | if (!CurContext->isDependentContext()) { | ||||||||
10914 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||||
10915 | for (OMPClause *C : Clauses) { | ||||||||
10916 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||||
10917 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||||
10918 | B.NumIterations, *this, CurScope, | ||||||||
10919 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||||
10920 | return StmtError(); | ||||||||
10921 | } | ||||||||
10922 | } | ||||||||
10923 | |||||||||
10924 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] | ||||||||
10925 | // The grainsize clause and num_tasks clause are mutually exclusive and may | ||||||||
10926 | // not appear on the same taskloop directive. | ||||||||
10927 | if (checkGrainsizeNumTasksClauses(*this, Clauses)) | ||||||||
10928 | return StmtError(); | ||||||||
10929 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] | ||||||||
10930 | // If a reduction clause is present on the taskloop directive, the nogroup | ||||||||
10931 | // clause must not be specified. | ||||||||
10932 | if (checkReductionClauseWithNogroup(*this, Clauses)) | ||||||||
10933 | return StmtError(); | ||||||||
10934 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||||
10935 | return StmtError(); | ||||||||
10936 | |||||||||
10937 | setFunctionHasBranchProtectedScope(); | ||||||||
10938 | return OMPParallelMasterTaskLoopSimdDirective::Create( | ||||||||
10939 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||||||
10940 | } | ||||||||
10941 | |||||||||
10942 | StmtResult Sema::ActOnOpenMPDistributeDirective( | ||||||||
10943 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||||
10944 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||||
10945 | if (!AStmt) | ||||||||
10946 | return StmtError(); | ||||||||
10947 | |||||||||
10948 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 10948, __PRETTY_FUNCTION__)); | ||||||||
10949 | OMPLoopDirective::HelperExprs B; | ||||||||
10950 | // In presence of clause 'collapse' with number of loops, it will | ||||||||
10951 | // define the nested loops number. | ||||||||
10952 | unsigned NestedLoopCount = | ||||||||
10953 | checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), | ||||||||
10954 | nullptr /*ordered not a clause on distribute*/, AStmt, | ||||||||
10955 | *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VarsWithImplicitDSA, B); | ||||||||
10956 | if (NestedLoopCount == 0) | ||||||||
10957 | return StmtError(); | ||||||||
10958 | |||||||||
10959 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 10960, __PRETTY_FUNCTION__)) | ||||||||
10960 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 10960, __PRETTY_FUNCTION__)); | ||||||||
10961 | |||||||||
10962 | setFunctionHasBranchProtectedScope(); | ||||||||
10963 | return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, | ||||||||
10964 | NestedLoopCount, Clauses, AStmt, B); | ||||||||
10965 | } | ||||||||
10966 | |||||||||
10967 | StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( | ||||||||
10968 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||||
10969 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||||
10970 | if (!AStmt) | ||||||||
10971 | return StmtError(); | ||||||||
10972 | |||||||||
10973 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
10974 | // 1.2.2 OpenMP Language Terminology | ||||||||
10975 | // Structured block - An executable statement with a single entry at the | ||||||||
10976 | // top and a single exit at the bottom. | ||||||||
10977 | // The point of exit cannot be a branch out of the structured block. | ||||||||
10978 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
10979 | CS->getCapturedDecl()->setNothrow(); | ||||||||
10980 | for (int ThisCaptureLevel = | ||||||||
10981 | getOpenMPCaptureLevels(OMPD_distribute_parallel_for); | ||||||||
10982 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||||
10983 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||||
10984 | // 1.2.2 OpenMP Language Terminology | ||||||||
10985 | // Structured block - An executable statement with a single entry at the | ||||||||
10986 | // top and a single exit at the bottom. | ||||||||
10987 | // The point of exit cannot be a branch out of the structured block. | ||||||||
10988 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
10989 | CS->getCapturedDecl()->setNothrow(); | ||||||||
10990 | } | ||||||||
10991 | |||||||||
10992 | OMPLoopDirective::HelperExprs B; | ||||||||
10993 | // In presence of clause 'collapse' with number of loops, it will | ||||||||
10994 | // define the nested loops number. | ||||||||
10995 | unsigned NestedLoopCount = checkOpenMPLoop( | ||||||||
10996 | OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), | ||||||||
10997 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||||
10998 | VarsWithImplicitDSA, B); | ||||||||
10999 | if (NestedLoopCount == 0) | ||||||||
11000 | return StmtError(); | ||||||||
11001 | |||||||||
11002 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11003, __PRETTY_FUNCTION__)) | ||||||||
11003 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11003, __PRETTY_FUNCTION__)); | ||||||||
11004 | |||||||||
11005 | setFunctionHasBranchProtectedScope(); | ||||||||
11006 | return OMPDistributeParallelForDirective::Create( | ||||||||
11007 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, | ||||||||
11008 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||||
11009 | } | ||||||||
11010 | |||||||||
11011 | StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( | ||||||||
11012 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||||
11013 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||||
11014 | if (!AStmt) | ||||||||
11015 | return StmtError(); | ||||||||
11016 | |||||||||
11017 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
11018 | // 1.2.2 OpenMP Language Terminology | ||||||||
11019 | // Structured block - An executable statement with a single entry at the | ||||||||
11020 | // top and a single exit at the bottom. | ||||||||
11021 | // The point of exit cannot be a branch out of the structured block. | ||||||||
11022 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
11023 | CS->getCapturedDecl()->setNothrow(); | ||||||||
11024 | for (int ThisCaptureLevel = | ||||||||
11025 | getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); | ||||||||
11026 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||||
11027 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||||
11028 | // 1.2.2 OpenMP Language Terminology | ||||||||
11029 | // Structured block - An executable statement with a single entry at the | ||||||||
11030 | // top and a single exit at the bottom. | ||||||||
11031 | // The point of exit cannot be a branch out of the structured block. | ||||||||
11032 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
11033 | CS->getCapturedDecl()->setNothrow(); | ||||||||
11034 | } | ||||||||
11035 | |||||||||
11036 | OMPLoopDirective::HelperExprs B; | ||||||||
11037 | // In presence of clause 'collapse' with number of loops, it will | ||||||||
11038 | // define the nested loops number. | ||||||||
11039 | unsigned NestedLoopCount = checkOpenMPLoop( | ||||||||
11040 | OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), | ||||||||
11041 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||||
11042 | VarsWithImplicitDSA, B); | ||||||||
11043 | if (NestedLoopCount == 0) | ||||||||
11044 | return StmtError(); | ||||||||
11045 | |||||||||
11046 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11047, __PRETTY_FUNCTION__)) | ||||||||
11047 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11047, __PRETTY_FUNCTION__)); | ||||||||
11048 | |||||||||
11049 | if (!CurContext->isDependentContext()) { | ||||||||
11050 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||||
11051 | for (OMPClause *C : Clauses) { | ||||||||
11052 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||||
11053 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||||
11054 | B.NumIterations, *this, CurScope, | ||||||||
11055 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||||
11056 | return StmtError(); | ||||||||
11057 | } | ||||||||
11058 | } | ||||||||
11059 | |||||||||
11060 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||||
11061 | return StmtError(); | ||||||||
11062 | |||||||||
11063 | setFunctionHasBranchProtectedScope(); | ||||||||
11064 | return OMPDistributeParallelForSimdDirective::Create( | ||||||||
11065 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||||||
11066 | } | ||||||||
11067 | |||||||||
11068 | StmtResult Sema::ActOnOpenMPDistributeSimdDirective( | ||||||||
11069 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||||
11070 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||||
11071 | if (!AStmt) | ||||||||
11072 | return StmtError(); | ||||||||
11073 | |||||||||
11074 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
11075 | // 1.2.2 OpenMP Language Terminology | ||||||||
11076 | // Structured block - An executable statement with a single entry at the | ||||||||
11077 | // top and a single exit at the bottom. | ||||||||
11078 | // The point of exit cannot be a branch out of the structured block. | ||||||||
11079 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
11080 | CS->getCapturedDecl()->setNothrow(); | ||||||||
11081 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); | ||||||||
11082 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||||
11083 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||||
11084 | // 1.2.2 OpenMP Language Terminology | ||||||||
11085 | // Structured block - An executable statement with a single entry at the | ||||||||
11086 | // top and a single exit at the bottom. | ||||||||
11087 | // The point of exit cannot be a branch out of the structured block. | ||||||||
11088 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
11089 | CS->getCapturedDecl()->setNothrow(); | ||||||||
11090 | } | ||||||||
11091 | |||||||||
11092 | OMPLoopDirective::HelperExprs B; | ||||||||
11093 | // In presence of clause 'collapse' with number of loops, it will | ||||||||
11094 | // define the nested loops number. | ||||||||
11095 | unsigned NestedLoopCount = | ||||||||
11096 | checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), | ||||||||
11097 | nullptr /*ordered not a clause on distribute*/, CS, *this, | ||||||||
11098 | *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VarsWithImplicitDSA, B); | ||||||||
11099 | if (NestedLoopCount == 0) | ||||||||
11100 | return StmtError(); | ||||||||
11101 | |||||||||
11102 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11103, __PRETTY_FUNCTION__)) | ||||||||
11103 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11103, __PRETTY_FUNCTION__)); | ||||||||
11104 | |||||||||
11105 | if (!CurContext->isDependentContext()) { | ||||||||
11106 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||||
11107 | for (OMPClause *C : Clauses) { | ||||||||
11108 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||||
11109 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||||
11110 | B.NumIterations, *this, CurScope, | ||||||||
11111 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||||
11112 | return StmtError(); | ||||||||
11113 | } | ||||||||
11114 | } | ||||||||
11115 | |||||||||
11116 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||||
11117 | return StmtError(); | ||||||||
11118 | |||||||||
11119 | setFunctionHasBranchProtectedScope(); | ||||||||
11120 | return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, | ||||||||
11121 | NestedLoopCount, Clauses, AStmt, B); | ||||||||
11122 | } | ||||||||
11123 | |||||||||
11124 | StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( | ||||||||
11125 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||||
11126 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||||
11127 | if (!AStmt) | ||||||||
11128 | return StmtError(); | ||||||||
11129 | |||||||||
11130 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
11131 | // 1.2.2 OpenMP Language Terminology | ||||||||
11132 | // Structured block - An executable statement with a single entry at the | ||||||||
11133 | // top and a single exit at the bottom. | ||||||||
11134 | // The point of exit cannot be a branch out of the structured block. | ||||||||
11135 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
11136 | CS->getCapturedDecl()->setNothrow(); | ||||||||
11137 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); | ||||||||
11138 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||||
11139 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||||
11140 | // 1.2.2 OpenMP Language Terminology | ||||||||
11141 | // Structured block - An executable statement with a single entry at the | ||||||||
11142 | // top and a single exit at the bottom. | ||||||||
11143 | // The point of exit cannot be a branch out of the structured block. | ||||||||
11144 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
11145 | CS->getCapturedDecl()->setNothrow(); | ||||||||
11146 | } | ||||||||
11147 | |||||||||
11148 | OMPLoopDirective::HelperExprs B; | ||||||||
11149 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||||||
11150 | // define the nested loops number. | ||||||||
11151 | unsigned NestedLoopCount = checkOpenMPLoop( | ||||||||
11152 | OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), | ||||||||
11153 | getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||||
11154 | VarsWithImplicitDSA, B); | ||||||||
11155 | if (NestedLoopCount == 0) | ||||||||
11156 | return StmtError(); | ||||||||
11157 | |||||||||
11158 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp target parallel for simd loop exprs were not built") ? static_cast <void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for simd loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11159, __PRETTY_FUNCTION__)) | ||||||||
11159 | "omp target parallel for simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp target parallel for simd loop exprs were not built") ? static_cast <void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for simd loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11159, __PRETTY_FUNCTION__)); | ||||||||
11160 | |||||||||
11161 | if (!CurContext->isDependentContext()) { | ||||||||
11162 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||||
11163 | for (OMPClause *C : Clauses) { | ||||||||
11164 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||||
11165 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||||
11166 | B.NumIterations, *this, CurScope, | ||||||||
11167 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||||
11168 | return StmtError(); | ||||||||
11169 | } | ||||||||
11170 | } | ||||||||
11171 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||||
11172 | return StmtError(); | ||||||||
11173 | |||||||||
11174 | setFunctionHasBranchProtectedScope(); | ||||||||
11175 | return OMPTargetParallelForSimdDirective::Create( | ||||||||
11176 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||||||
11177 | } | ||||||||
11178 | |||||||||
11179 | StmtResult Sema::ActOnOpenMPTargetSimdDirective( | ||||||||
11180 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||||
11181 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||||
11182 | if (!AStmt) | ||||||||
11183 | return StmtError(); | ||||||||
11184 | |||||||||
11185 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
11186 | // 1.2.2 OpenMP Language Terminology | ||||||||
11187 | // Structured block - An executable statement with a single entry at the | ||||||||
11188 | // top and a single exit at the bottom. | ||||||||
11189 | // The point of exit cannot be a branch out of the structured block. | ||||||||
11190 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
11191 | CS->getCapturedDecl()->setNothrow(); | ||||||||
11192 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); | ||||||||
11193 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||||
11194 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||||
11195 | // 1.2.2 OpenMP Language Terminology | ||||||||
11196 | // Structured block - An executable statement with a single entry at the | ||||||||
11197 | // top and a single exit at the bottom. | ||||||||
11198 | // The point of exit cannot be a branch out of the structured block. | ||||||||
11199 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
11200 | CS->getCapturedDecl()->setNothrow(); | ||||||||
11201 | } | ||||||||
11202 | |||||||||
11203 | OMPLoopDirective::HelperExprs B; | ||||||||
11204 | // In presence of clause 'collapse' with number of loops, it will define the | ||||||||
11205 | // nested loops number. | ||||||||
11206 | unsigned NestedLoopCount = | ||||||||
11207 | checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), | ||||||||
11208 | getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||||
11209 | VarsWithImplicitDSA, B); | ||||||||
11210 | if (NestedLoopCount == 0) | ||||||||
11211 | return StmtError(); | ||||||||
11212 | |||||||||
11213 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp target simd loop exprs were not built") ? static_cast< void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target simd loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11214, __PRETTY_FUNCTION__)) | ||||||||
11214 | "omp target simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp target simd loop exprs were not built") ? static_cast< void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target simd loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11214, __PRETTY_FUNCTION__)); | ||||||||
11215 | |||||||||
11216 | if (!CurContext->isDependentContext()) { | ||||||||
11217 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||||
11218 | for (OMPClause *C : Clauses) { | ||||||||
11219 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||||
11220 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||||
11221 | B.NumIterations, *this, CurScope, | ||||||||
11222 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||||
11223 | return StmtError(); | ||||||||
11224 | } | ||||||||
11225 | } | ||||||||
11226 | |||||||||
11227 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||||
11228 | return StmtError(); | ||||||||
11229 | |||||||||
11230 | setFunctionHasBranchProtectedScope(); | ||||||||
11231 | return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, | ||||||||
11232 | NestedLoopCount, Clauses, AStmt, B); | ||||||||
11233 | } | ||||||||
11234 | |||||||||
11235 | StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( | ||||||||
11236 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||||
11237 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||||
11238 | if (!AStmt) | ||||||||
11239 | return StmtError(); | ||||||||
11240 | |||||||||
11241 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
11242 | // 1.2.2 OpenMP Language Terminology | ||||||||
11243 | // Structured block - An executable statement with a single entry at the | ||||||||
11244 | // top and a single exit at the bottom. | ||||||||
11245 | // The point of exit cannot be a branch out of the structured block. | ||||||||
11246 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
11247 | CS->getCapturedDecl()->setNothrow(); | ||||||||
11248 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); | ||||||||
11249 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||||
11250 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||||
11251 | // 1.2.2 OpenMP Language Terminology | ||||||||
11252 | // Structured block - An executable statement with a single entry at the | ||||||||
11253 | // top and a single exit at the bottom. | ||||||||
11254 | // The point of exit cannot be a branch out of the structured block. | ||||||||
11255 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
11256 | CS->getCapturedDecl()->setNothrow(); | ||||||||
11257 | } | ||||||||
11258 | |||||||||
11259 | OMPLoopDirective::HelperExprs B; | ||||||||
11260 | // In presence of clause 'collapse' with number of loops, it will | ||||||||
11261 | // define the nested loops number. | ||||||||
11262 | unsigned NestedLoopCount = | ||||||||
11263 | checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), | ||||||||
11264 | nullptr /*ordered not a clause on distribute*/, CS, *this, | ||||||||
11265 | *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VarsWithImplicitDSA, B); | ||||||||
11266 | if (NestedLoopCount == 0) | ||||||||
11267 | return StmtError(); | ||||||||
11268 | |||||||||
11269 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp teams distribute loop exprs were not built") ? static_cast <void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11270, __PRETTY_FUNCTION__)) | ||||||||
11270 | "omp teams distribute loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp teams distribute loop exprs were not built") ? static_cast <void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11270, __PRETTY_FUNCTION__)); | ||||||||
11271 | |||||||||
11272 | setFunctionHasBranchProtectedScope(); | ||||||||
11273 | |||||||||
11274 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentTeamsRegionLoc(StartLoc); | ||||||||
11275 | |||||||||
11276 | return OMPTeamsDistributeDirective::Create( | ||||||||
11277 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||||||
11278 | } | ||||||||
11279 | |||||||||
11280 | StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( | ||||||||
11281 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||||
11282 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||||
11283 | if (!AStmt) | ||||||||
11284 | return StmtError(); | ||||||||
11285 | |||||||||
11286 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
11287 | // 1.2.2 OpenMP Language Terminology | ||||||||
11288 | // Structured block - An executable statement with a single entry at the | ||||||||
11289 | // top and a single exit at the bottom. | ||||||||
11290 | // The point of exit cannot be a branch out of the structured block. | ||||||||
11291 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
11292 | CS->getCapturedDecl()->setNothrow(); | ||||||||
11293 | for (int ThisCaptureLevel = | ||||||||
11294 | getOpenMPCaptureLevels(OMPD_teams_distribute_simd); | ||||||||
11295 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||||
11296 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||||
11297 | // 1.2.2 OpenMP Language Terminology | ||||||||
11298 | // Structured block - An executable statement with a single entry at the | ||||||||
11299 | // top and a single exit at the bottom. | ||||||||
11300 | // The point of exit cannot be a branch out of the structured block. | ||||||||
11301 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
11302 | CS->getCapturedDecl()->setNothrow(); | ||||||||
11303 | } | ||||||||
11304 | |||||||||
11305 | OMPLoopDirective::HelperExprs B; | ||||||||
11306 | // In presence of clause 'collapse' with number of loops, it will | ||||||||
11307 | // define the nested loops number. | ||||||||
11308 | unsigned NestedLoopCount = checkOpenMPLoop( | ||||||||
11309 | OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), | ||||||||
11310 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||||
11311 | VarsWithImplicitDSA, B); | ||||||||
11312 | |||||||||
11313 | if (NestedLoopCount == 0) | ||||||||
11314 | return StmtError(); | ||||||||
11315 | |||||||||
11316 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp teams distribute simd loop exprs were not built") ? static_cast <void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute simd loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11317, __PRETTY_FUNCTION__)) | ||||||||
11317 | "omp teams distribute simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp teams distribute simd loop exprs were not built") ? static_cast <void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute simd loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11317, __PRETTY_FUNCTION__)); | ||||||||
11318 | |||||||||
11319 | if (!CurContext->isDependentContext()) { | ||||||||
11320 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||||
11321 | for (OMPClause *C : Clauses) { | ||||||||
11322 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||||
11323 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||||
11324 | B.NumIterations, *this, CurScope, | ||||||||
11325 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||||
11326 | return StmtError(); | ||||||||
11327 | } | ||||||||
11328 | } | ||||||||
11329 | |||||||||
11330 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||||
11331 | return StmtError(); | ||||||||
11332 | |||||||||
11333 | setFunctionHasBranchProtectedScope(); | ||||||||
11334 | |||||||||
11335 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentTeamsRegionLoc(StartLoc); | ||||||||
11336 | |||||||||
11337 | return OMPTeamsDistributeSimdDirective::Create( | ||||||||
11338 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||||||
11339 | } | ||||||||
11340 | |||||||||
11341 | StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( | ||||||||
11342 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||||
11343 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||||
11344 | if (!AStmt) | ||||||||
11345 | return StmtError(); | ||||||||
11346 | |||||||||
11347 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
11348 | // 1.2.2 OpenMP Language Terminology | ||||||||
11349 | // Structured block - An executable statement with a single entry at the | ||||||||
11350 | // top and a single exit at the bottom. | ||||||||
11351 | // The point of exit cannot be a branch out of the structured block. | ||||||||
11352 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
11353 | CS->getCapturedDecl()->setNothrow(); | ||||||||
11354 | |||||||||
11355 | for (int ThisCaptureLevel = | ||||||||
11356 | getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); | ||||||||
11357 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||||
11358 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||||
11359 | // 1.2.2 OpenMP Language Terminology | ||||||||
11360 | // Structured block - An executable statement with a single entry at the | ||||||||
11361 | // top and a single exit at the bottom. | ||||||||
11362 | // The point of exit cannot be a branch out of the structured block. | ||||||||
11363 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
11364 | CS->getCapturedDecl()->setNothrow(); | ||||||||
11365 | } | ||||||||
11366 | |||||||||
11367 | OMPLoopDirective::HelperExprs B; | ||||||||
11368 | // In presence of clause 'collapse' with number of loops, it will | ||||||||
11369 | // define the nested loops number. | ||||||||
11370 | unsigned NestedLoopCount = checkOpenMPLoop( | ||||||||
11371 | OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), | ||||||||
11372 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||||
11373 | VarsWithImplicitDSA, B); | ||||||||
11374 | |||||||||
11375 | if (NestedLoopCount == 0) | ||||||||
11376 | return StmtError(); | ||||||||
11377 | |||||||||
11378 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11379, __PRETTY_FUNCTION__)) | ||||||||
11379 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11379, __PRETTY_FUNCTION__)); | ||||||||
11380 | |||||||||
11381 | if (!CurContext->isDependentContext()) { | ||||||||
11382 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||||
11383 | for (OMPClause *C : Clauses) { | ||||||||
11384 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||||
11385 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||||
11386 | B.NumIterations, *this, CurScope, | ||||||||
11387 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||||
11388 | return StmtError(); | ||||||||
11389 | } | ||||||||
11390 | } | ||||||||
11391 | |||||||||
11392 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||||
11393 | return StmtError(); | ||||||||
11394 | |||||||||
11395 | setFunctionHasBranchProtectedScope(); | ||||||||
11396 | |||||||||
11397 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentTeamsRegionLoc(StartLoc); | ||||||||
11398 | |||||||||
11399 | return OMPTeamsDistributeParallelForSimdDirective::Create( | ||||||||
11400 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||||||
11401 | } | ||||||||
11402 | |||||||||
11403 | StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( | ||||||||
11404 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||||
11405 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||||
11406 | if (!AStmt) | ||||||||
11407 | return StmtError(); | ||||||||
11408 | |||||||||
11409 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
11410 | // 1.2.2 OpenMP Language Terminology | ||||||||
11411 | // Structured block - An executable statement with a single entry at the | ||||||||
11412 | // top and a single exit at the bottom. | ||||||||
11413 | // The point of exit cannot be a branch out of the structured block. | ||||||||
11414 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
11415 | CS->getCapturedDecl()->setNothrow(); | ||||||||
11416 | |||||||||
11417 | for (int ThisCaptureLevel = | ||||||||
11418 | getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); | ||||||||
11419 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||||
11420 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||||
11421 | // 1.2.2 OpenMP Language Terminology | ||||||||
11422 | // Structured block - An executable statement with a single entry at the | ||||||||
11423 | // top and a single exit at the bottom. | ||||||||
11424 | // The point of exit cannot be a branch out of the structured block. | ||||||||
11425 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
11426 | CS->getCapturedDecl()->setNothrow(); | ||||||||
11427 | } | ||||||||
11428 | |||||||||
11429 | OMPLoopDirective::HelperExprs B; | ||||||||
11430 | // In presence of clause 'collapse' with number of loops, it will | ||||||||
11431 | // define the nested loops number. | ||||||||
11432 | unsigned NestedLoopCount = checkOpenMPLoop( | ||||||||
11433 | OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), | ||||||||
11434 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||||
11435 | VarsWithImplicitDSA, B); | ||||||||
11436 | |||||||||
11437 | if (NestedLoopCount == 0) | ||||||||
11438 | return StmtError(); | ||||||||
11439 | |||||||||
11440 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11441, __PRETTY_FUNCTION__)) | ||||||||
11441 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11441, __PRETTY_FUNCTION__)); | ||||||||
11442 | |||||||||
11443 | setFunctionHasBranchProtectedScope(); | ||||||||
11444 | |||||||||
11445 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentTeamsRegionLoc(StartLoc); | ||||||||
11446 | |||||||||
11447 | return OMPTeamsDistributeParallelForDirective::Create( | ||||||||
11448 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, | ||||||||
11449 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||||
11450 | } | ||||||||
11451 | |||||||||
11452 | StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, | ||||||||
11453 | Stmt *AStmt, | ||||||||
11454 | SourceLocation StartLoc, | ||||||||
11455 | SourceLocation EndLoc) { | ||||||||
11456 | if (!AStmt) | ||||||||
11457 | return StmtError(); | ||||||||
11458 | |||||||||
11459 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
11460 | // 1.2.2 OpenMP Language Terminology | ||||||||
11461 | // Structured block - An executable statement with a single entry at the | ||||||||
11462 | // top and a single exit at the bottom. | ||||||||
11463 | // The point of exit cannot be a branch out of the structured block. | ||||||||
11464 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
11465 | CS->getCapturedDecl()->setNothrow(); | ||||||||
11466 | |||||||||
11467 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); | ||||||||
11468 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||||
11469 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||||
11470 | // 1.2.2 OpenMP Language Terminology | ||||||||
11471 | // Structured block - An executable statement with a single entry at the | ||||||||
11472 | // top and a single exit at the bottom. | ||||||||
11473 | // The point of exit cannot be a branch out of the structured block. | ||||||||
11474 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
11475 | CS->getCapturedDecl()->setNothrow(); | ||||||||
11476 | } | ||||||||
11477 | setFunctionHasBranchProtectedScope(); | ||||||||
11478 | |||||||||
11479 | return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, | ||||||||
11480 | AStmt); | ||||||||
11481 | } | ||||||||
11482 | |||||||||
11483 | StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( | ||||||||
11484 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||||
11485 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||||
11486 | if (!AStmt) | ||||||||
11487 | return StmtError(); | ||||||||
11488 | |||||||||
11489 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
11490 | // 1.2.2 OpenMP Language Terminology | ||||||||
11491 | // Structured block - An executable statement with a single entry at the | ||||||||
11492 | // top and a single exit at the bottom. | ||||||||
11493 | // The point of exit cannot be a branch out of the structured block. | ||||||||
11494 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
11495 | CS->getCapturedDecl()->setNothrow(); | ||||||||
11496 | for (int ThisCaptureLevel = | ||||||||
11497 | getOpenMPCaptureLevels(OMPD_target_teams_distribute); | ||||||||
11498 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||||
11499 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||||
11500 | // 1.2.2 OpenMP Language Terminology | ||||||||
11501 | // Structured block - An executable statement with a single entry at the | ||||||||
11502 | // top and a single exit at the bottom. | ||||||||
11503 | // The point of exit cannot be a branch out of the structured block. | ||||||||
11504 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
11505 | CS->getCapturedDecl()->setNothrow(); | ||||||||
11506 | } | ||||||||
11507 | |||||||||
11508 | OMPLoopDirective::HelperExprs B; | ||||||||
11509 | // In presence of clause 'collapse' with number of loops, it will | ||||||||
11510 | // define the nested loops number. | ||||||||
11511 | unsigned NestedLoopCount = checkOpenMPLoop( | ||||||||
11512 | OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), | ||||||||
11513 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||||
11514 | VarsWithImplicitDSA, B); | ||||||||
11515 | if (NestedLoopCount == 0) | ||||||||
11516 | return StmtError(); | ||||||||
11517 | |||||||||
11518 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp target teams distribute loop exprs were not built") ? static_cast <void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11519, __PRETTY_FUNCTION__)) | ||||||||
11519 | "omp target teams distribute loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp target teams distribute loop exprs were not built") ? static_cast <void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11519, __PRETTY_FUNCTION__)); | ||||||||
11520 | |||||||||
11521 | setFunctionHasBranchProtectedScope(); | ||||||||
11522 | return OMPTargetTeamsDistributeDirective::Create( | ||||||||
11523 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||||||
11524 | } | ||||||||
11525 | |||||||||
11526 | StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( | ||||||||
11527 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||||
11528 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||||
11529 | if (!AStmt) | ||||||||
11530 | return StmtError(); | ||||||||
11531 | |||||||||
11532 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
11533 | // 1.2.2 OpenMP Language Terminology | ||||||||
11534 | // Structured block - An executable statement with a single entry at the | ||||||||
11535 | // top and a single exit at the bottom. | ||||||||
11536 | // The point of exit cannot be a branch out of the structured block. | ||||||||
11537 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
11538 | CS->getCapturedDecl()->setNothrow(); | ||||||||
11539 | for (int ThisCaptureLevel = | ||||||||
11540 | getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); | ||||||||
11541 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||||
11542 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||||
11543 | // 1.2.2 OpenMP Language Terminology | ||||||||
11544 | // Structured block - An executable statement with a single entry at the | ||||||||
11545 | // top and a single exit at the bottom. | ||||||||
11546 | // The point of exit cannot be a branch out of the structured block. | ||||||||
11547 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
11548 | CS->getCapturedDecl()->setNothrow(); | ||||||||
11549 | } | ||||||||
11550 | |||||||||
11551 | OMPLoopDirective::HelperExprs B; | ||||||||
11552 | // In presence of clause 'collapse' with number of loops, it will | ||||||||
11553 | // define the nested loops number. | ||||||||
11554 | unsigned NestedLoopCount = checkOpenMPLoop( | ||||||||
11555 | OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), | ||||||||
11556 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||||
11557 | VarsWithImplicitDSA, B); | ||||||||
11558 | if (NestedLoopCount == 0) | ||||||||
11559 | return StmtError(); | ||||||||
11560 | |||||||||
11561 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp target teams distribute parallel for loop exprs were not built" ) ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11562, __PRETTY_FUNCTION__)) | ||||||||
11562 | "omp target teams distribute parallel for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp target teams distribute parallel for loop exprs were not built" ) ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11562, __PRETTY_FUNCTION__)); | ||||||||
11563 | |||||||||
11564 | if (!CurContext->isDependentContext()) { | ||||||||
11565 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||||
11566 | for (OMPClause *C : Clauses) { | ||||||||
11567 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||||
11568 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||||
11569 | B.NumIterations, *this, CurScope, | ||||||||
11570 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||||
11571 | return StmtError(); | ||||||||
11572 | } | ||||||||
11573 | } | ||||||||
11574 | |||||||||
11575 | setFunctionHasBranchProtectedScope(); | ||||||||
11576 | return OMPTargetTeamsDistributeParallelForDirective::Create( | ||||||||
11577 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, | ||||||||
11578 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||||
11579 | } | ||||||||
11580 | |||||||||
11581 | StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( | ||||||||
11582 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||||
11583 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||||
11584 | if (!AStmt) | ||||||||
11585 | return StmtError(); | ||||||||
11586 | |||||||||
11587 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
11588 | // 1.2.2 OpenMP Language Terminology | ||||||||
11589 | // Structured block - An executable statement with a single entry at the | ||||||||
11590 | // top and a single exit at the bottom. | ||||||||
11591 | // The point of exit cannot be a branch out of the structured block. | ||||||||
11592 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
11593 | CS->getCapturedDecl()->setNothrow(); | ||||||||
11594 | for (int ThisCaptureLevel = getOpenMPCaptureLevels( | ||||||||
11595 | OMPD_target_teams_distribute_parallel_for_simd); | ||||||||
11596 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||||
11597 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||||
11598 | // 1.2.2 OpenMP Language Terminology | ||||||||
11599 | // Structured block - An executable statement with a single entry at the | ||||||||
11600 | // top and a single exit at the bottom. | ||||||||
11601 | // The point of exit cannot be a branch out of the structured block. | ||||||||
11602 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
11603 | CS->getCapturedDecl()->setNothrow(); | ||||||||
11604 | } | ||||||||
11605 | |||||||||
11606 | OMPLoopDirective::HelperExprs B; | ||||||||
11607 | // In presence of clause 'collapse' with number of loops, it will | ||||||||
11608 | // define the nested loops number. | ||||||||
11609 | unsigned NestedLoopCount = | ||||||||
11610 | checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, | ||||||||
11611 | getCollapseNumberExpr(Clauses), | ||||||||
11612 | nullptr /*ordered not a clause on distribute*/, CS, *this, | ||||||||
11613 | *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VarsWithImplicitDSA, B); | ||||||||
11614 | if (NestedLoopCount == 0) | ||||||||
11615 | return StmtError(); | ||||||||
11616 | |||||||||
11617 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp target teams distribute parallel for simd loop exprs were not " "built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for simd loop exprs were not \" \"built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11619, __PRETTY_FUNCTION__)) | ||||||||
11618 | "omp target teams distribute parallel for simd loop exprs were not "(((CurContext->isDependentContext() || B.builtAll()) && "omp target teams distribute parallel for simd loop exprs were not " "built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for simd loop exprs were not \" \"built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11619, __PRETTY_FUNCTION__)) | ||||||||
11619 | "built")(((CurContext->isDependentContext() || B.builtAll()) && "omp target teams distribute parallel for simd loop exprs were not " "built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for simd loop exprs were not \" \"built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11619, __PRETTY_FUNCTION__)); | ||||||||
11620 | |||||||||
11621 | if (!CurContext->isDependentContext()) { | ||||||||
11622 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||||
11623 | for (OMPClause *C : Clauses) { | ||||||||
11624 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||||
11625 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||||
11626 | B.NumIterations, *this, CurScope, | ||||||||
11627 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||||
11628 | return StmtError(); | ||||||||
11629 | } | ||||||||
11630 | } | ||||||||
11631 | |||||||||
11632 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||||
11633 | return StmtError(); | ||||||||
11634 | |||||||||
11635 | setFunctionHasBranchProtectedScope(); | ||||||||
11636 | return OMPTargetTeamsDistributeParallelForSimdDirective::Create( | ||||||||
11637 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||||||
11638 | } | ||||||||
11639 | |||||||||
11640 | StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( | ||||||||
11641 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||||
11642 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||||
11643 | if (!AStmt) | ||||||||
11644 | return StmtError(); | ||||||||
11645 | |||||||||
11646 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||||
11647 | // 1.2.2 OpenMP Language Terminology | ||||||||
11648 | // Structured block - An executable statement with a single entry at the | ||||||||
11649 | // top and a single exit at the bottom. | ||||||||
11650 | // The point of exit cannot be a branch out of the structured block. | ||||||||
11651 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
11652 | CS->getCapturedDecl()->setNothrow(); | ||||||||
11653 | for (int ThisCaptureLevel = | ||||||||
11654 | getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); | ||||||||
11655 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||||
11656 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||||
11657 | // 1.2.2 OpenMP Language Terminology | ||||||||
11658 | // Structured block - An executable statement with a single entry at the | ||||||||
11659 | // top and a single exit at the bottom. | ||||||||
11660 | // The point of exit cannot be a branch out of the structured block. | ||||||||
11661 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||||
11662 | CS->getCapturedDecl()->setNothrow(); | ||||||||
11663 | } | ||||||||
11664 | |||||||||
11665 | OMPLoopDirective::HelperExprs B; | ||||||||
11666 | // In presence of clause 'collapse' with number of loops, it will | ||||||||
11667 | // define the nested loops number. | ||||||||
11668 | unsigned NestedLoopCount = checkOpenMPLoop( | ||||||||
11669 | OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), | ||||||||
11670 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||||
11671 | VarsWithImplicitDSA, B); | ||||||||
11672 | if (NestedLoopCount == 0) | ||||||||
11673 | return StmtError(); | ||||||||
11674 | |||||||||
11675 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp target teams distribute simd loop exprs were not built" ) ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute simd loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11676, __PRETTY_FUNCTION__)) | ||||||||
11676 | "omp target teams distribute simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp target teams distribute simd loop exprs were not built" ) ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute simd loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11676, __PRETTY_FUNCTION__)); | ||||||||
11677 | |||||||||
11678 | if (!CurContext->isDependentContext()) { | ||||||||
11679 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||||
11680 | for (OMPClause *C : Clauses) { | ||||||||
11681 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||||
11682 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||||
11683 | B.NumIterations, *this, CurScope, | ||||||||
11684 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||||
11685 | return StmtError(); | ||||||||
11686 | } | ||||||||
11687 | } | ||||||||
11688 | |||||||||
11689 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||||
11690 | return StmtError(); | ||||||||
11691 | |||||||||
11692 | setFunctionHasBranchProtectedScope(); | ||||||||
11693 | return OMPTargetTeamsDistributeSimdDirective::Create( | ||||||||
11694 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||||||
11695 | } | ||||||||
11696 | |||||||||
11697 | OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, | ||||||||
11698 | SourceLocation StartLoc, | ||||||||
11699 | SourceLocation LParenLoc, | ||||||||
11700 | SourceLocation EndLoc) { | ||||||||
11701 | OMPClause *Res = nullptr; | ||||||||
11702 | switch (Kind) { | ||||||||
11703 | case OMPC_final: | ||||||||
11704 | Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||||
11705 | break; | ||||||||
11706 | case OMPC_num_threads: | ||||||||
11707 | Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||||
11708 | break; | ||||||||
11709 | case OMPC_safelen: | ||||||||
11710 | Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||||
11711 | break; | ||||||||
11712 | case OMPC_simdlen: | ||||||||
11713 | Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||||
11714 | break; | ||||||||
11715 | case OMPC_allocator: | ||||||||
11716 | Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||||
11717 | break; | ||||||||
11718 | case OMPC_collapse: | ||||||||
11719 | Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||||
11720 | break; | ||||||||
11721 | case OMPC_ordered: | ||||||||
11722 | Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); | ||||||||
11723 | break; | ||||||||
11724 | case OMPC_num_teams: | ||||||||
11725 | Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||||
11726 | break; | ||||||||
11727 | case OMPC_thread_limit: | ||||||||
11728 | Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||||
11729 | break; | ||||||||
11730 | case OMPC_priority: | ||||||||
11731 | Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||||
11732 | break; | ||||||||
11733 | case OMPC_grainsize: | ||||||||
11734 | Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||||
11735 | break; | ||||||||
11736 | case OMPC_num_tasks: | ||||||||
11737 | Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||||
11738 | break; | ||||||||
11739 | case OMPC_hint: | ||||||||
11740 | Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||||
11741 | break; | ||||||||
11742 | case OMPC_depobj: | ||||||||
11743 | Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||||
11744 | break; | ||||||||
11745 | case OMPC_detach: | ||||||||
11746 | Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||||
11747 | break; | ||||||||
11748 | case OMPC_device: | ||||||||
11749 | case OMPC_if: | ||||||||
11750 | case OMPC_default: | ||||||||
11751 | case OMPC_proc_bind: | ||||||||
11752 | case OMPC_schedule: | ||||||||
11753 | case OMPC_private: | ||||||||
11754 | case OMPC_firstprivate: | ||||||||
11755 | case OMPC_lastprivate: | ||||||||
11756 | case OMPC_shared: | ||||||||
11757 | case OMPC_reduction: | ||||||||
11758 | case OMPC_task_reduction: | ||||||||
11759 | case OMPC_in_reduction: | ||||||||
11760 | case OMPC_linear: | ||||||||
11761 | case OMPC_aligned: | ||||||||
11762 | case OMPC_copyin: | ||||||||
11763 | case OMPC_copyprivate: | ||||||||
11764 | case OMPC_nowait: | ||||||||
11765 | case OMPC_untied: | ||||||||
11766 | case OMPC_mergeable: | ||||||||
11767 | case OMPC_threadprivate: | ||||||||
11768 | case OMPC_allocate: | ||||||||
11769 | case OMPC_flush: | ||||||||
11770 | case OMPC_read: | ||||||||
11771 | case OMPC_write: | ||||||||
11772 | case OMPC_update: | ||||||||
11773 | case OMPC_capture: | ||||||||
11774 | case OMPC_seq_cst: | ||||||||
11775 | case OMPC_acq_rel: | ||||||||
11776 | case OMPC_acquire: | ||||||||
11777 | case OMPC_release: | ||||||||
11778 | case OMPC_relaxed: | ||||||||
11779 | case OMPC_depend: | ||||||||
11780 | case OMPC_threads: | ||||||||
11781 | case OMPC_simd: | ||||||||
11782 | case OMPC_map: | ||||||||
11783 | case OMPC_nogroup: | ||||||||
11784 | case OMPC_dist_schedule: | ||||||||
11785 | case OMPC_defaultmap: | ||||||||
11786 | case OMPC_unknown: | ||||||||
11787 | case OMPC_uniform: | ||||||||
11788 | case OMPC_to: | ||||||||
11789 | case OMPC_from: | ||||||||
11790 | case OMPC_use_device_ptr: | ||||||||
11791 | case OMPC_use_device_addr: | ||||||||
11792 | case OMPC_is_device_ptr: | ||||||||
11793 | case OMPC_unified_address: | ||||||||
11794 | case OMPC_unified_shared_memory: | ||||||||
11795 | case OMPC_reverse_offload: | ||||||||
11796 | case OMPC_dynamic_allocators: | ||||||||
11797 | case OMPC_atomic_default_mem_order: | ||||||||
11798 | case OMPC_device_type: | ||||||||
11799 | case OMPC_match: | ||||||||
11800 | case OMPC_nontemporal: | ||||||||
11801 | case OMPC_order: | ||||||||
11802 | case OMPC_destroy: | ||||||||
11803 | case OMPC_inclusive: | ||||||||
11804 | case OMPC_exclusive: | ||||||||
11805 | case OMPC_uses_allocators: | ||||||||
11806 | case OMPC_affinity: | ||||||||
11807 | default: | ||||||||
11808 | llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11808); | ||||||||
11809 | } | ||||||||
11810 | return Res; | ||||||||
11811 | } | ||||||||
11812 | |||||||||
11813 | // An OpenMP directive such as 'target parallel' has two captured regions: | ||||||||
11814 | // for the 'target' and 'parallel' respectively. This function returns | ||||||||
11815 | // the region in which to capture expressions associated with a clause. | ||||||||
11816 | // A return value of OMPD_unknown signifies that the expression should not | ||||||||
11817 | // be captured. | ||||||||
11818 | static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( | ||||||||
11819 | OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, | ||||||||
11820 | OpenMPDirectiveKind NameModifier = OMPD_unknown) { | ||||||||
11821 | OpenMPDirectiveKind CaptureRegion = OMPD_unknown; | ||||||||
11822 | switch (CKind) { | ||||||||
11823 | case OMPC_if: | ||||||||
11824 | switch (DKind) { | ||||||||
11825 | case OMPD_target_parallel_for_simd: | ||||||||
11826 | if (OpenMPVersion >= 50 && | ||||||||
11827 | (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { | ||||||||
11828 | CaptureRegion = OMPD_parallel; | ||||||||
11829 | break; | ||||||||
11830 | } | ||||||||
11831 | LLVM_FALLTHROUGH[[gnu::fallthrough]]; | ||||||||
11832 | case OMPD_target_parallel: | ||||||||
11833 | case OMPD_target_parallel_for: | ||||||||
11834 | // If this clause applies to the nested 'parallel' region, capture within | ||||||||
11835 | // the 'target' region, otherwise do not capture. | ||||||||
11836 | if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) | ||||||||
11837 | CaptureRegion = OMPD_target; | ||||||||
11838 | break; | ||||||||
11839 | case OMPD_target_teams_distribute_parallel_for_simd: | ||||||||
11840 | if (OpenMPVersion >= 50 && | ||||||||
11841 | (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { | ||||||||
11842 | CaptureRegion = OMPD_parallel; | ||||||||
11843 | break; | ||||||||
11844 | } | ||||||||
11845 | LLVM_FALLTHROUGH[[gnu::fallthrough]]; | ||||||||
11846 | case OMPD_target_teams_distribute_parallel_for: | ||||||||
11847 | // If this clause applies to the nested 'parallel' region, capture within | ||||||||
11848 | // the 'teams' region, otherwise do not capture. | ||||||||
11849 | if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) | ||||||||
11850 | CaptureRegion = OMPD_teams; | ||||||||
11851 | break; | ||||||||
11852 | case OMPD_teams_distribute_parallel_for_simd: | ||||||||
11853 | if (OpenMPVersion >= 50 && | ||||||||
11854 | (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { | ||||||||
11855 | CaptureRegion = OMPD_parallel; | ||||||||
11856 | break; | ||||||||
11857 | } | ||||||||
11858 | LLVM_FALLTHROUGH[[gnu::fallthrough]]; | ||||||||
11859 | case OMPD_teams_distribute_parallel_for: | ||||||||
11860 | CaptureRegion = OMPD_teams; | ||||||||
11861 | break; | ||||||||
11862 | case OMPD_target_update: | ||||||||
11863 | case OMPD_target_enter_data: | ||||||||
11864 | case OMPD_target_exit_data: | ||||||||
11865 | CaptureRegion = OMPD_task; | ||||||||
11866 | break; | ||||||||
11867 | case OMPD_parallel_master_taskloop: | ||||||||
11868 | if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) | ||||||||
11869 | CaptureRegion = OMPD_parallel; | ||||||||
11870 | break; | ||||||||
11871 | case OMPD_parallel_master_taskloop_simd: | ||||||||
11872 | if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || | ||||||||
11873 | NameModifier == OMPD_taskloop) { | ||||||||
11874 | CaptureRegion = OMPD_parallel; | ||||||||
11875 | break; | ||||||||
11876 | } | ||||||||
11877 | if (OpenMPVersion <= 45) | ||||||||
11878 | break; | ||||||||
11879 | if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) | ||||||||
11880 | CaptureRegion = OMPD_taskloop; | ||||||||
11881 | break; | ||||||||
11882 | case OMPD_parallel_for_simd: | ||||||||
11883 | if (OpenMPVersion <= 45) | ||||||||
11884 | break; | ||||||||
11885 | if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) | ||||||||
11886 | CaptureRegion = OMPD_parallel; | ||||||||
11887 | break; | ||||||||
11888 | case OMPD_taskloop_simd: | ||||||||
11889 | case OMPD_master_taskloop_simd: | ||||||||
11890 | if (OpenMPVersion <= 45) | ||||||||
11891 | break; | ||||||||
11892 | if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) | ||||||||
11893 | CaptureRegion = OMPD_taskloop; | ||||||||
11894 | break; | ||||||||
11895 | case OMPD_distribute_parallel_for_simd: | ||||||||
11896 | if (OpenMPVersion <= 45) | ||||||||
11897 | break; | ||||||||
11898 | if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) | ||||||||
11899 | CaptureRegion = OMPD_parallel; | ||||||||
11900 | break; | ||||||||
11901 | case OMPD_target_simd: | ||||||||
11902 | if (OpenMPVersion >= 50 && | ||||||||
11903 | (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) | ||||||||
11904 | CaptureRegion = OMPD_target; | ||||||||
11905 | break; | ||||||||
11906 | case OMPD_teams_distribute_simd: | ||||||||
11907 | case OMPD_target_teams_distribute_simd: | ||||||||
11908 | if (OpenMPVersion >= 50 && | ||||||||
11909 | (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) | ||||||||
11910 | CaptureRegion = OMPD_teams; | ||||||||
11911 | break; | ||||||||
11912 | case OMPD_cancel: | ||||||||
11913 | case OMPD_parallel: | ||||||||
11914 | case OMPD_parallel_master: | ||||||||
11915 | case OMPD_parallel_sections: | ||||||||
11916 | case OMPD_parallel_for: | ||||||||
11917 | case OMPD_target: | ||||||||
11918 | case OMPD_target_teams: | ||||||||
11919 | case OMPD_target_teams_distribute: | ||||||||
11920 | case OMPD_distribute_parallel_for: | ||||||||
11921 | case OMPD_task: | ||||||||
11922 | case OMPD_taskloop: | ||||||||
11923 | case OMPD_master_taskloop: | ||||||||
11924 | case OMPD_target_data: | ||||||||
11925 | case OMPD_simd: | ||||||||
11926 | case OMPD_for_simd: | ||||||||
11927 | case OMPD_distribute_simd: | ||||||||
11928 | // Do not capture if-clause expressions. | ||||||||
11929 | break; | ||||||||
11930 | case OMPD_threadprivate: | ||||||||
11931 | case OMPD_allocate: | ||||||||
11932 | case OMPD_taskyield: | ||||||||
11933 | case OMPD_barrier: | ||||||||
11934 | case OMPD_taskwait: | ||||||||
11935 | case OMPD_cancellation_point: | ||||||||
11936 | case OMPD_flush: | ||||||||
11937 | case OMPD_depobj: | ||||||||
11938 | case OMPD_scan: | ||||||||
11939 | case OMPD_declare_reduction: | ||||||||
11940 | case OMPD_declare_mapper: | ||||||||
11941 | case OMPD_declare_simd: | ||||||||
11942 | case OMPD_declare_variant: | ||||||||
11943 | case OMPD_begin_declare_variant: | ||||||||
11944 | case OMPD_end_declare_variant: | ||||||||
11945 | case OMPD_declare_target: | ||||||||
11946 | case OMPD_end_declare_target: | ||||||||
11947 | case OMPD_teams: | ||||||||
11948 | case OMPD_for: | ||||||||
11949 | case OMPD_sections: | ||||||||
11950 | case OMPD_section: | ||||||||
11951 | case OMPD_single: | ||||||||
11952 | case OMPD_master: | ||||||||
11953 | case OMPD_critical: | ||||||||
11954 | case OMPD_taskgroup: | ||||||||
11955 | case OMPD_distribute: | ||||||||
11956 | case OMPD_ordered: | ||||||||
11957 | case OMPD_atomic: | ||||||||
11958 | case OMPD_teams_distribute: | ||||||||
11959 | case OMPD_requires: | ||||||||
11960 | llvm_unreachable("Unexpected OpenMP directive with if-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with if-clause" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11960); | ||||||||
11961 | case OMPD_unknown: | ||||||||
11962 | default: | ||||||||
11963 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 11963); | ||||||||
11964 | } | ||||||||
11965 | break; | ||||||||
11966 | case OMPC_num_threads: | ||||||||
11967 | switch (DKind) { | ||||||||
11968 | case OMPD_target_parallel: | ||||||||
11969 | case OMPD_target_parallel_for: | ||||||||
11970 | case OMPD_target_parallel_for_simd: | ||||||||
11971 | CaptureRegion = OMPD_target; | ||||||||
11972 | break; | ||||||||
11973 | case OMPD_teams_distribute_parallel_for: | ||||||||
11974 | case OMPD_teams_distribute_parallel_for_simd: | ||||||||
11975 | case OMPD_target_teams_distribute_parallel_for: | ||||||||
11976 | case OMPD_target_teams_distribute_parallel_for_simd: | ||||||||
11977 | CaptureRegion = OMPD_teams; | ||||||||
11978 | break; | ||||||||
11979 | case OMPD_parallel: | ||||||||
11980 | case OMPD_parallel_master: | ||||||||
11981 | case OMPD_parallel_sections: | ||||||||
11982 | case OMPD_parallel_for: | ||||||||
11983 | case OMPD_parallel_for_simd: | ||||||||
11984 | case OMPD_distribute_parallel_for: | ||||||||
11985 | case OMPD_distribute_parallel_for_simd: | ||||||||
11986 | case OMPD_parallel_master_taskloop: | ||||||||
11987 | case OMPD_parallel_master_taskloop_simd: | ||||||||
11988 | // Do not capture num_threads-clause expressions. | ||||||||
11989 | break; | ||||||||
11990 | case OMPD_target_data: | ||||||||
11991 | case OMPD_target_enter_data: | ||||||||
11992 | case OMPD_target_exit_data: | ||||||||
11993 | case OMPD_target_update: | ||||||||
11994 | case OMPD_target: | ||||||||
11995 | case OMPD_target_simd: | ||||||||
11996 | case OMPD_target_teams: | ||||||||
11997 | case OMPD_target_teams_distribute: | ||||||||
11998 | case OMPD_target_teams_distribute_simd: | ||||||||
11999 | case OMPD_cancel: | ||||||||
12000 | case OMPD_task: | ||||||||
12001 | case OMPD_taskloop: | ||||||||
12002 | case OMPD_taskloop_simd: | ||||||||
12003 | case OMPD_master_taskloop: | ||||||||
12004 | case OMPD_master_taskloop_simd: | ||||||||
12005 | case OMPD_threadprivate: | ||||||||
12006 | case OMPD_allocate: | ||||||||
12007 | case OMPD_taskyield: | ||||||||
12008 | case OMPD_barrier: | ||||||||
12009 | case OMPD_taskwait: | ||||||||
12010 | case OMPD_cancellation_point: | ||||||||
12011 | case OMPD_flush: | ||||||||
12012 | case OMPD_depobj: | ||||||||
12013 | case OMPD_scan: | ||||||||
12014 | case OMPD_declare_reduction: | ||||||||
12015 | case OMPD_declare_mapper: | ||||||||
12016 | case OMPD_declare_simd: | ||||||||
12017 | case OMPD_declare_variant: | ||||||||
12018 | case OMPD_begin_declare_variant: | ||||||||
12019 | case OMPD_end_declare_variant: | ||||||||
12020 | case OMPD_declare_target: | ||||||||
12021 | case OMPD_end_declare_target: | ||||||||
12022 | case OMPD_teams: | ||||||||
12023 | case OMPD_simd: | ||||||||
12024 | case OMPD_for: | ||||||||
12025 | case OMPD_for_simd: | ||||||||
12026 | case OMPD_sections: | ||||||||
12027 | case OMPD_section: | ||||||||
12028 | case OMPD_single: | ||||||||
12029 | case OMPD_master: | ||||||||
12030 | case OMPD_critical: | ||||||||
12031 | case OMPD_taskgroup: | ||||||||
12032 | case OMPD_distribute: | ||||||||
12033 | case OMPD_ordered: | ||||||||
12034 | case OMPD_atomic: | ||||||||
12035 | case OMPD_distribute_simd: | ||||||||
12036 | case OMPD_teams_distribute: | ||||||||
12037 | case OMPD_teams_distribute_simd: | ||||||||
12038 | case OMPD_requires: | ||||||||
12039 | llvm_unreachable("Unexpected OpenMP directive with num_threads-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with num_threads-clause" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 12039); | ||||||||
12040 | case OMPD_unknown: | ||||||||
12041 | default: | ||||||||
12042 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 12042); | ||||||||
12043 | } | ||||||||
12044 | break; | ||||||||
12045 | case OMPC_num_teams: | ||||||||
12046 | switch (DKind) { | ||||||||
12047 | case OMPD_target_teams: | ||||||||
12048 | case OMPD_target_teams_distribute: | ||||||||
12049 | case OMPD_target_teams_distribute_simd: | ||||||||
12050 | case OMPD_target_teams_distribute_parallel_for: | ||||||||
12051 | case OMPD_target_teams_distribute_parallel_for_simd: | ||||||||
12052 | CaptureRegion = OMPD_target; | ||||||||
12053 | break; | ||||||||
12054 | case OMPD_teams_distribute_parallel_for: | ||||||||
12055 | case OMPD_teams_distribute_parallel_for_simd: | ||||||||
12056 | case OMPD_teams: | ||||||||
12057 | case OMPD_teams_distribute: | ||||||||
12058 | case OMPD_teams_distribute_simd: | ||||||||
12059 | // Do not capture num_teams-clause expressions. | ||||||||
12060 | break; | ||||||||
12061 | case OMPD_distribute_parallel_for: | ||||||||
12062 | case OMPD_distribute_parallel_for_simd: | ||||||||
12063 | case OMPD_task: | ||||||||
12064 | case OMPD_taskloop: | ||||||||
12065 | case OMPD_taskloop_simd: | ||||||||
12066 | case OMPD_master_taskloop: | ||||||||
12067 | case OMPD_master_taskloop_simd: | ||||||||
12068 | case OMPD_parallel_master_taskloop: | ||||||||
12069 | case OMPD_parallel_master_taskloop_simd: | ||||||||
12070 | case OMPD_target_data: | ||||||||
12071 | case OMPD_target_enter_data: | ||||||||
12072 | case OMPD_target_exit_data: | ||||||||
12073 | case OMPD_target_update: | ||||||||
12074 | case OMPD_cancel: | ||||||||
12075 | case OMPD_parallel: | ||||||||
12076 | case OMPD_parallel_master: | ||||||||
12077 | case OMPD_parallel_sections: | ||||||||
12078 | case OMPD_parallel_for: | ||||||||
12079 | case OMPD_parallel_for_simd: | ||||||||
12080 | case OMPD_target: | ||||||||
12081 | case OMPD_target_simd: | ||||||||
12082 | case OMPD_target_parallel: | ||||||||
12083 | case OMPD_target_parallel_for: | ||||||||
12084 | case OMPD_target_parallel_for_simd: | ||||||||
12085 | case OMPD_threadprivate: | ||||||||
12086 | case OMPD_allocate: | ||||||||
12087 | case OMPD_taskyield: | ||||||||
12088 | case OMPD_barrier: | ||||||||
12089 | case OMPD_taskwait: | ||||||||
12090 | case OMPD_cancellation_point: | ||||||||
12091 | case OMPD_flush: | ||||||||
12092 | case OMPD_depobj: | ||||||||
12093 | case OMPD_scan: | ||||||||
12094 | case OMPD_declare_reduction: | ||||||||
12095 | case OMPD_declare_mapper: | ||||||||
12096 | case OMPD_declare_simd: | ||||||||
12097 | case OMPD_declare_variant: | ||||||||
12098 | case OMPD_begin_declare_variant: | ||||||||
12099 | case OMPD_end_declare_variant: | ||||||||
12100 | case OMPD_declare_target: | ||||||||
12101 | case OMPD_end_declare_target: | ||||||||
12102 | case OMPD_simd: | ||||||||
12103 | case OMPD_for: | ||||||||
12104 | case OMPD_for_simd: | ||||||||
12105 | case OMPD_sections: | ||||||||
12106 | case OMPD_section: | ||||||||
12107 | case OMPD_single: | ||||||||
12108 | case OMPD_master: | ||||||||
12109 | case OMPD_critical: | ||||||||
12110 | case OMPD_taskgroup: | ||||||||
12111 | case OMPD_distribute: | ||||||||
12112 | case OMPD_ordered: | ||||||||
12113 | case OMPD_atomic: | ||||||||
12114 | case OMPD_distribute_simd: | ||||||||
12115 | case OMPD_requires: | ||||||||
12116 | llvm_unreachable("Unexpected OpenMP directive with num_teams-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with num_teams-clause" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 12116); | ||||||||
12117 | case OMPD_unknown: | ||||||||
12118 | default: | ||||||||
12119 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 12119); | ||||||||
12120 | } | ||||||||
12121 | break; | ||||||||
12122 | case OMPC_thread_limit: | ||||||||
12123 | switch (DKind) { | ||||||||
12124 | case OMPD_target_teams: | ||||||||
12125 | case OMPD_target_teams_distribute: | ||||||||
12126 | case OMPD_target_teams_distribute_simd: | ||||||||
12127 | case OMPD_target_teams_distribute_parallel_for: | ||||||||
12128 | case OMPD_target_teams_distribute_parallel_for_simd: | ||||||||
12129 | CaptureRegion = OMPD_target; | ||||||||
12130 | break; | ||||||||
12131 | case OMPD_teams_distribute_parallel_for: | ||||||||
12132 | case OMPD_teams_distribute_parallel_for_simd: | ||||||||
12133 | case OMPD_teams: | ||||||||
12134 | case OMPD_teams_distribute: | ||||||||
12135 | case OMPD_teams_distribute_simd: | ||||||||
12136 | // Do not capture thread_limit-clause expressions. | ||||||||
12137 | break; | ||||||||
12138 | case OMPD_distribute_parallel_for: | ||||||||
12139 | case OMPD_distribute_parallel_for_simd: | ||||||||
12140 | case OMPD_task: | ||||||||
12141 | case OMPD_taskloop: | ||||||||
12142 | case OMPD_taskloop_simd: | ||||||||
12143 | case OMPD_master_taskloop: | ||||||||
12144 | case OMPD_master_taskloop_simd: | ||||||||
12145 | case OMPD_parallel_master_taskloop: | ||||||||
12146 | case OMPD_parallel_master_taskloop_simd: | ||||||||
12147 | case OMPD_target_data: | ||||||||
12148 | case OMPD_target_enter_data: | ||||||||
12149 | case OMPD_target_exit_data: | ||||||||
12150 | case OMPD_target_update: | ||||||||
12151 | case OMPD_cancel: | ||||||||
12152 | case OMPD_parallel: | ||||||||
12153 | case OMPD_parallel_master: | ||||||||
12154 | case OMPD_parallel_sections: | ||||||||
12155 | case OMPD_parallel_for: | ||||||||
12156 | case OMPD_parallel_for_simd: | ||||||||
12157 | case OMPD_target: | ||||||||
12158 | case OMPD_target_simd: | ||||||||
12159 | case OMPD_target_parallel: | ||||||||
12160 | case OMPD_target_parallel_for: | ||||||||
12161 | case OMPD_target_parallel_for_simd: | ||||||||
12162 | case OMPD_threadprivate: | ||||||||
12163 | case OMPD_allocate: | ||||||||
12164 | case OMPD_taskyield: | ||||||||
12165 | case OMPD_barrier: | ||||||||
12166 | case OMPD_taskwait: | ||||||||
12167 | case OMPD_cancellation_point: | ||||||||
12168 | case OMPD_flush: | ||||||||
12169 | case OMPD_depobj: | ||||||||
12170 | case OMPD_scan: | ||||||||
12171 | case OMPD_declare_reduction: | ||||||||
12172 | case OMPD_declare_mapper: | ||||||||
12173 | case OMPD_declare_simd: | ||||||||
12174 | case OMPD_declare_variant: | ||||||||
12175 | case OMPD_begin_declare_variant: | ||||||||
12176 | case OMPD_end_declare_variant: | ||||||||
12177 | case OMPD_declare_target: | ||||||||
12178 | case OMPD_end_declare_target: | ||||||||
12179 | case OMPD_simd: | ||||||||
12180 | case OMPD_for: | ||||||||
12181 | case OMPD_for_simd: | ||||||||
12182 | case OMPD_sections: | ||||||||
12183 | case OMPD_section: | ||||||||
12184 | case OMPD_single: | ||||||||
12185 | case OMPD_master: | ||||||||
12186 | case OMPD_critical: | ||||||||
12187 | case OMPD_taskgroup: | ||||||||
12188 | case OMPD_distribute: | ||||||||
12189 | case OMPD_ordered: | ||||||||
12190 | case OMPD_atomic: | ||||||||
12191 | case OMPD_distribute_simd: | ||||||||
12192 | case OMPD_requires: | ||||||||
12193 | llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with thread_limit-clause" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 12193); | ||||||||
12194 | case OMPD_unknown: | ||||||||
12195 | default: | ||||||||
12196 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 12196); | ||||||||
12197 | } | ||||||||
12198 | break; | ||||||||
12199 | case OMPC_schedule: | ||||||||
12200 | switch (DKind) { | ||||||||
12201 | case OMPD_parallel_for: | ||||||||
12202 | case OMPD_parallel_for_simd: | ||||||||
12203 | case OMPD_distribute_parallel_for: | ||||||||
12204 | case OMPD_distribute_parallel_for_simd: | ||||||||
12205 | case OMPD_teams_distribute_parallel_for: | ||||||||
12206 | case OMPD_teams_distribute_parallel_for_simd: | ||||||||
12207 | case OMPD_target_parallel_for: | ||||||||
12208 | case OMPD_target_parallel_for_simd: | ||||||||
12209 | case OMPD_target_teams_distribute_parallel_for: | ||||||||
12210 | case OMPD_target_teams_distribute_parallel_for_simd: | ||||||||
12211 | CaptureRegion = OMPD_parallel; | ||||||||
12212 | break; | ||||||||
12213 | case OMPD_for: | ||||||||
12214 | case OMPD_for_simd: | ||||||||
12215 | // Do not capture schedule-clause expressions. | ||||||||
12216 | break; | ||||||||
12217 | case OMPD_task: | ||||||||
12218 | case OMPD_taskloop: | ||||||||
12219 | case OMPD_taskloop_simd: | ||||||||
12220 | case OMPD_master_taskloop: | ||||||||
12221 | case OMPD_master_taskloop_simd: | ||||||||
12222 | case OMPD_parallel_master_taskloop: | ||||||||
12223 | case OMPD_parallel_master_taskloop_simd: | ||||||||
12224 | case OMPD_target_data: | ||||||||
12225 | case OMPD_target_enter_data: | ||||||||
12226 | case OMPD_target_exit_data: | ||||||||
12227 | case OMPD_target_update: | ||||||||
12228 | case OMPD_teams: | ||||||||
12229 | case OMPD_teams_distribute: | ||||||||
12230 | case OMPD_teams_distribute_simd: | ||||||||
12231 | case OMPD_target_teams_distribute: | ||||||||
12232 | case OMPD_target_teams_distribute_simd: | ||||||||
12233 | case OMPD_target: | ||||||||
12234 | case OMPD_target_simd: | ||||||||
12235 | case OMPD_target_parallel: | ||||||||
12236 | case OMPD_cancel: | ||||||||
12237 | case OMPD_parallel: | ||||||||
12238 | case OMPD_parallel_master: | ||||||||
12239 | case OMPD_parallel_sections: | ||||||||
12240 | case OMPD_threadprivate: | ||||||||
12241 | case OMPD_allocate: | ||||||||
12242 | case OMPD_taskyield: | ||||||||
12243 | case OMPD_barrier: | ||||||||
12244 | case OMPD_taskwait: | ||||||||
12245 | case OMPD_cancellation_point: | ||||||||
12246 | case OMPD_flush: | ||||||||
12247 | case OMPD_depobj: | ||||||||
12248 | case OMPD_scan: | ||||||||
12249 | case OMPD_declare_reduction: | ||||||||
12250 | case OMPD_declare_mapper: | ||||||||
12251 | case OMPD_declare_simd: | ||||||||
12252 | case OMPD_declare_variant: | ||||||||
12253 | case OMPD_begin_declare_variant: | ||||||||
12254 | case OMPD_end_declare_variant: | ||||||||
12255 | case OMPD_declare_target: | ||||||||
12256 | case OMPD_end_declare_target: | ||||||||
12257 | case OMPD_simd: | ||||||||
12258 | case OMPD_sections: | ||||||||
12259 | case OMPD_section: | ||||||||
12260 | case OMPD_single: | ||||||||
12261 | case OMPD_master: | ||||||||
12262 | case OMPD_critical: | ||||||||
12263 | case OMPD_taskgroup: | ||||||||
12264 | case OMPD_distribute: | ||||||||
12265 | case OMPD_ordered: | ||||||||
12266 | case OMPD_atomic: | ||||||||
12267 | case OMPD_distribute_simd: | ||||||||
12268 | case OMPD_target_teams: | ||||||||
12269 | case OMPD_requires: | ||||||||
12270 | llvm_unreachable("Unexpected OpenMP directive with schedule clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with schedule clause" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 12270); | ||||||||
12271 | case OMPD_unknown: | ||||||||
12272 | default: | ||||||||
12273 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 12273); | ||||||||
12274 | } | ||||||||
12275 | break; | ||||||||
12276 | case OMPC_dist_schedule: | ||||||||
12277 | switch (DKind) { | ||||||||
12278 | case OMPD_teams_distribute_parallel_for: | ||||||||
12279 | case OMPD_teams_distribute_parallel_for_simd: | ||||||||
12280 | case OMPD_teams_distribute: | ||||||||
12281 | case OMPD_teams_distribute_simd: | ||||||||
12282 | case OMPD_target_teams_distribute_parallel_for: | ||||||||
12283 | case OMPD_target_teams_distribute_parallel_for_simd: | ||||||||
12284 | case OMPD_target_teams_distribute: | ||||||||
12285 | case OMPD_target_teams_distribute_simd: | ||||||||
12286 | CaptureRegion = OMPD_teams; | ||||||||
12287 | break; | ||||||||
12288 | case OMPD_distribute_parallel_for: | ||||||||
12289 | case OMPD_distribute_parallel_for_simd: | ||||||||
12290 | case OMPD_distribute: | ||||||||
12291 | case OMPD_distribute_simd: | ||||||||
12292 | // Do not capture thread_limit-clause expressions. | ||||||||
12293 | break; | ||||||||
12294 | case OMPD_parallel_for: | ||||||||
12295 | case OMPD_parallel_for_simd: | ||||||||
12296 | case OMPD_target_parallel_for_simd: | ||||||||
12297 | case OMPD_target_parallel_for: | ||||||||
12298 | case OMPD_task: | ||||||||
12299 | case OMPD_taskloop: | ||||||||
12300 | case OMPD_taskloop_simd: | ||||||||
12301 | case OMPD_master_taskloop: | ||||||||
12302 | case OMPD_master_taskloop_simd: | ||||||||
12303 | case OMPD_parallel_master_taskloop: | ||||||||
12304 | case OMPD_parallel_master_taskloop_simd: | ||||||||
12305 | case OMPD_target_data: | ||||||||
12306 | case OMPD_target_enter_data: | ||||||||
12307 | case OMPD_target_exit_data: | ||||||||
12308 | case OMPD_target_update: | ||||||||
12309 | case OMPD_teams: | ||||||||
12310 | case OMPD_target: | ||||||||
12311 | case OMPD_target_simd: | ||||||||
12312 | case OMPD_target_parallel: | ||||||||
12313 | case OMPD_cancel: | ||||||||
12314 | case OMPD_parallel: | ||||||||
12315 | case OMPD_parallel_master: | ||||||||
12316 | case OMPD_parallel_sections: | ||||||||
12317 | case OMPD_threadprivate: | ||||||||
12318 | case OMPD_allocate: | ||||||||
12319 | case OMPD_taskyield: | ||||||||
12320 | case OMPD_barrier: | ||||||||
12321 | case OMPD_taskwait: | ||||||||
12322 | case OMPD_cancellation_point: | ||||||||
12323 | case OMPD_flush: | ||||||||
12324 | case OMPD_depobj: | ||||||||
12325 | case OMPD_scan: | ||||||||
12326 | case OMPD_declare_reduction: | ||||||||
12327 | case OMPD_declare_mapper: | ||||||||
12328 | case OMPD_declare_simd: | ||||||||
12329 | case OMPD_declare_variant: | ||||||||
12330 | case OMPD_begin_declare_variant: | ||||||||
12331 | case OMPD_end_declare_variant: | ||||||||
12332 | case OMPD_declare_target: | ||||||||
12333 | case OMPD_end_declare_target: | ||||||||
12334 | case OMPD_simd: | ||||||||
12335 | case OMPD_for: | ||||||||
12336 | case OMPD_for_simd: | ||||||||
12337 | case OMPD_sections: | ||||||||
12338 | case OMPD_section: | ||||||||
12339 | case OMPD_single: | ||||||||
12340 | case OMPD_master: | ||||||||
12341 | case OMPD_critical: | ||||||||
12342 | case OMPD_taskgroup: | ||||||||
12343 | case OMPD_ordered: | ||||||||
12344 | case OMPD_atomic: | ||||||||
12345 | case OMPD_target_teams: | ||||||||
12346 | case OMPD_requires: | ||||||||
12347 | llvm_unreachable("Unexpected OpenMP directive with schedule clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with schedule clause" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 12347); | ||||||||
12348 | case OMPD_unknown: | ||||||||
12349 | default: | ||||||||
12350 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 12350); | ||||||||
12351 | } | ||||||||
12352 | break; | ||||||||
12353 | case OMPC_device: | ||||||||
12354 | switch (DKind) { | ||||||||
12355 | case OMPD_target_update: | ||||||||
12356 | case OMPD_target_enter_data: | ||||||||
12357 | case OMPD_target_exit_data: | ||||||||
12358 | case OMPD_target: | ||||||||
12359 | case OMPD_target_simd: | ||||||||
12360 | case OMPD_target_teams: | ||||||||
12361 | case OMPD_target_parallel: | ||||||||
12362 | case OMPD_target_teams_distribute: | ||||||||
12363 | case OMPD_target_teams_distribute_simd: | ||||||||
12364 | case OMPD_target_parallel_for: | ||||||||
12365 | case OMPD_target_parallel_for_simd: | ||||||||
12366 | case OMPD_target_teams_distribute_parallel_for: | ||||||||
12367 | case OMPD_target_teams_distribute_parallel_for_simd: | ||||||||
12368 | CaptureRegion = OMPD_task; | ||||||||
12369 | break; | ||||||||
12370 | case OMPD_target_data: | ||||||||
12371 | // Do not capture device-clause expressions. | ||||||||
12372 | break; | ||||||||
12373 | case OMPD_teams_distribute_parallel_for: | ||||||||
12374 | case OMPD_teams_distribute_parallel_for_simd: | ||||||||
12375 | case OMPD_teams: | ||||||||
12376 | case OMPD_teams_distribute: | ||||||||
12377 | case OMPD_teams_distribute_simd: | ||||||||
12378 | case OMPD_distribute_parallel_for: | ||||||||
12379 | case OMPD_distribute_parallel_for_simd: | ||||||||
12380 | case OMPD_task: | ||||||||
12381 | case OMPD_taskloop: | ||||||||
12382 | case OMPD_taskloop_simd: | ||||||||
12383 | case OMPD_master_taskloop: | ||||||||
12384 | case OMPD_master_taskloop_simd: | ||||||||
12385 | case OMPD_parallel_master_taskloop: | ||||||||
12386 | case OMPD_parallel_master_taskloop_simd: | ||||||||
12387 | case OMPD_cancel: | ||||||||
12388 | case OMPD_parallel: | ||||||||
12389 | case OMPD_parallel_master: | ||||||||
12390 | case OMPD_parallel_sections: | ||||||||
12391 | case OMPD_parallel_for: | ||||||||
12392 | case OMPD_parallel_for_simd: | ||||||||
12393 | case OMPD_threadprivate: | ||||||||
12394 | case OMPD_allocate: | ||||||||
12395 | case OMPD_taskyield: | ||||||||
12396 | case OMPD_barrier: | ||||||||
12397 | case OMPD_taskwait: | ||||||||
12398 | case OMPD_cancellation_point: | ||||||||
12399 | case OMPD_flush: | ||||||||
12400 | case OMPD_depobj: | ||||||||
12401 | case OMPD_scan: | ||||||||
12402 | case OMPD_declare_reduction: | ||||||||
12403 | case OMPD_declare_mapper: | ||||||||
12404 | case OMPD_declare_simd: | ||||||||
12405 | case OMPD_declare_variant: | ||||||||
12406 | case OMPD_begin_declare_variant: | ||||||||
12407 | case OMPD_end_declare_variant: | ||||||||
12408 | case OMPD_declare_target: | ||||||||
12409 | case OMPD_end_declare_target: | ||||||||
12410 | case OMPD_simd: | ||||||||
12411 | case OMPD_for: | ||||||||
12412 | case OMPD_for_simd: | ||||||||
12413 | case OMPD_sections: | ||||||||
12414 | case OMPD_section: | ||||||||
12415 | case OMPD_single: | ||||||||
12416 | case OMPD_master: | ||||||||
12417 | case OMPD_critical: | ||||||||
12418 | case OMPD_taskgroup: | ||||||||
12419 | case OMPD_distribute: | ||||||||
12420 | case OMPD_ordered: | ||||||||
12421 | case OMPD_atomic: | ||||||||
12422 | case OMPD_distribute_simd: | ||||||||
12423 | case OMPD_requires: | ||||||||
12424 | llvm_unreachable("Unexpected OpenMP directive with num_teams-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with num_teams-clause" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 12424); | ||||||||
12425 | case OMPD_unknown: | ||||||||
12426 | default: | ||||||||
12427 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 12427); | ||||||||
12428 | } | ||||||||
12429 | break; | ||||||||
12430 | case OMPC_grainsize: | ||||||||
12431 | case OMPC_num_tasks: | ||||||||
12432 | case OMPC_final: | ||||||||
12433 | case OMPC_priority: | ||||||||
12434 | switch (DKind) { | ||||||||
12435 | case OMPD_task: | ||||||||
12436 | case OMPD_taskloop: | ||||||||
12437 | case OMPD_taskloop_simd: | ||||||||
12438 | case OMPD_master_taskloop: | ||||||||
12439 | case OMPD_master_taskloop_simd: | ||||||||
12440 | break; | ||||||||
12441 | case OMPD_parallel_master_taskloop: | ||||||||
12442 | case OMPD_parallel_master_taskloop_simd: | ||||||||
12443 | CaptureRegion = OMPD_parallel; | ||||||||
12444 | break; | ||||||||
12445 | case OMPD_target_update: | ||||||||
12446 | case OMPD_target_enter_data: | ||||||||
12447 | case OMPD_target_exit_data: | ||||||||
12448 | case OMPD_target: | ||||||||
12449 | case OMPD_target_simd: | ||||||||
12450 | case OMPD_target_teams: | ||||||||
12451 | case OMPD_target_parallel: | ||||||||
12452 | case OMPD_target_teams_distribute: | ||||||||
12453 | case OMPD_target_teams_distribute_simd: | ||||||||
12454 | case OMPD_target_parallel_for: | ||||||||
12455 | case OMPD_target_parallel_for_simd: | ||||||||
12456 | case OMPD_target_teams_distribute_parallel_for: | ||||||||
12457 | case OMPD_target_teams_distribute_parallel_for_simd: | ||||||||
12458 | case OMPD_target_data: | ||||||||
12459 | case OMPD_teams_distribute_parallel_for: | ||||||||
12460 | case OMPD_teams_distribute_parallel_for_simd: | ||||||||
12461 | case OMPD_teams: | ||||||||
12462 | case OMPD_teams_distribute: | ||||||||
12463 | case OMPD_teams_distribute_simd: | ||||||||
12464 | case OMPD_distribute_parallel_for: | ||||||||
12465 | case OMPD_distribute_parallel_for_simd: | ||||||||
12466 | case OMPD_cancel: | ||||||||
12467 | case OMPD_parallel: | ||||||||
12468 | case OMPD_parallel_master: | ||||||||
12469 | case OMPD_parallel_sections: | ||||||||
12470 | case OMPD_parallel_for: | ||||||||
12471 | case OMPD_parallel_for_simd: | ||||||||
12472 | case OMPD_threadprivate: | ||||||||
12473 | case OMPD_allocate: | ||||||||
12474 | case OMPD_taskyield: | ||||||||
12475 | case OMPD_barrier: | ||||||||
12476 | case OMPD_taskwait: | ||||||||
12477 | case OMPD_cancellation_point: | ||||||||
12478 | case OMPD_flush: | ||||||||
12479 | case OMPD_depobj: | ||||||||
12480 | case OMPD_scan: | ||||||||
12481 | case OMPD_declare_reduction: | ||||||||
12482 | case OMPD_declare_mapper: | ||||||||
12483 | case OMPD_declare_simd: | ||||||||
12484 | case OMPD_declare_variant: | ||||||||
12485 | case OMPD_begin_declare_variant: | ||||||||
12486 | case OMPD_end_declare_variant: | ||||||||
12487 | case OMPD_declare_target: | ||||||||
12488 | case OMPD_end_declare_target: | ||||||||
12489 | case OMPD_simd: | ||||||||
12490 | case OMPD_for: | ||||||||
12491 | case OMPD_for_simd: | ||||||||
12492 | case OMPD_sections: | ||||||||
12493 | case OMPD_section: | ||||||||
12494 | case OMPD_single: | ||||||||
12495 | case OMPD_master: | ||||||||
12496 | case OMPD_critical: | ||||||||
12497 | case OMPD_taskgroup: | ||||||||
12498 | case OMPD_distribute: | ||||||||
12499 | case OMPD_ordered: | ||||||||
12500 | case OMPD_atomic: | ||||||||
12501 | case OMPD_distribute_simd: | ||||||||
12502 | case OMPD_requires: | ||||||||
12503 | llvm_unreachable("Unexpected OpenMP directive with grainsize-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with grainsize-clause" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 12503); | ||||||||
12504 | case OMPD_unknown: | ||||||||
12505 | default: | ||||||||
12506 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 12506); | ||||||||
12507 | } | ||||||||
12508 | break; | ||||||||
12509 | case OMPC_firstprivate: | ||||||||
12510 | case OMPC_lastprivate: | ||||||||
12511 | case OMPC_reduction: | ||||||||
12512 | case OMPC_task_reduction: | ||||||||
12513 | case OMPC_in_reduction: | ||||||||
12514 | case OMPC_linear: | ||||||||
12515 | case OMPC_default: | ||||||||
12516 | case OMPC_proc_bind: | ||||||||
12517 | case OMPC_safelen: | ||||||||
12518 | case OMPC_simdlen: | ||||||||
12519 | case OMPC_allocator: | ||||||||
12520 | case OMPC_collapse: | ||||||||
12521 | case OMPC_private: | ||||||||
12522 | case OMPC_shared: | ||||||||
12523 | case OMPC_aligned: | ||||||||
12524 | case OMPC_copyin: | ||||||||
12525 | case OMPC_copyprivate: | ||||||||
12526 | case OMPC_ordered: | ||||||||
12527 | case OMPC_nowait: | ||||||||
12528 | case OMPC_untied: | ||||||||
12529 | case OMPC_mergeable: | ||||||||
12530 | case OMPC_threadprivate: | ||||||||
12531 | case OMPC_allocate: | ||||||||
12532 | case OMPC_flush: | ||||||||
12533 | case OMPC_depobj: | ||||||||
12534 | case OMPC_read: | ||||||||
12535 | case OMPC_write: | ||||||||
12536 | case OMPC_update: | ||||||||
12537 | case OMPC_capture: | ||||||||
12538 | case OMPC_seq_cst: | ||||||||
12539 | case OMPC_acq_rel: | ||||||||
12540 | case OMPC_acquire: | ||||||||
12541 | case OMPC_release: | ||||||||
12542 | case OMPC_relaxed: | ||||||||
12543 | case OMPC_depend: | ||||||||
12544 | case OMPC_threads: | ||||||||
12545 | case OMPC_simd: | ||||||||
12546 | case OMPC_map: | ||||||||
12547 | case OMPC_nogroup: | ||||||||
12548 | case OMPC_hint: | ||||||||
12549 | case OMPC_defaultmap: | ||||||||
12550 | case OMPC_unknown: | ||||||||
12551 | case OMPC_uniform: | ||||||||
12552 | case OMPC_to: | ||||||||
12553 | case OMPC_from: | ||||||||
12554 | case OMPC_use_device_ptr: | ||||||||
12555 | case OMPC_use_device_addr: | ||||||||
12556 | case OMPC_is_device_ptr: | ||||||||
12557 | case OMPC_unified_address: | ||||||||
12558 | case OMPC_unified_shared_memory: | ||||||||
12559 | case OMPC_reverse_offload: | ||||||||
12560 | case OMPC_dynamic_allocators: | ||||||||
12561 | case OMPC_atomic_default_mem_order: | ||||||||
12562 | case OMPC_device_type: | ||||||||
12563 | case OMPC_match: | ||||||||
12564 | case OMPC_nontemporal: | ||||||||
12565 | case OMPC_order: | ||||||||
12566 | case OMPC_destroy: | ||||||||
12567 | case OMPC_detach: | ||||||||
12568 | case OMPC_inclusive: | ||||||||
12569 | case OMPC_exclusive: | ||||||||
12570 | case OMPC_uses_allocators: | ||||||||
12571 | case OMPC_affinity: | ||||||||
12572 | default: | ||||||||
12573 | llvm_unreachable("Unexpected OpenMP clause.")::llvm::llvm_unreachable_internal("Unexpected OpenMP clause." , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 12573); | ||||||||
12574 | } | ||||||||
12575 | return CaptureRegion; | ||||||||
12576 | } | ||||||||
12577 | |||||||||
12578 | OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, | ||||||||
12579 | Expr *Condition, SourceLocation StartLoc, | ||||||||
12580 | SourceLocation LParenLoc, | ||||||||
12581 | SourceLocation NameModifierLoc, | ||||||||
12582 | SourceLocation ColonLoc, | ||||||||
12583 | SourceLocation EndLoc) { | ||||||||
12584 | Expr *ValExpr = Condition; | ||||||||
12585 | Stmt *HelperValStmt = nullptr; | ||||||||
12586 | OpenMPDirectiveKind CaptureRegion = OMPD_unknown; | ||||||||
12587 | if (!Condition->isValueDependent() && !Condition->isTypeDependent() && | ||||||||
12588 | !Condition->isInstantiationDependent() && | ||||||||
12589 | !Condition->containsUnexpandedParameterPack()) { | ||||||||
12590 | ExprResult Val = CheckBooleanCondition(StartLoc, Condition); | ||||||||
12591 | if (Val.isInvalid()) | ||||||||
12592 | return nullptr; | ||||||||
12593 | |||||||||
12594 | ValExpr = Val.get(); | ||||||||
12595 | |||||||||
12596 | OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); | ||||||||
12597 | CaptureRegion = getOpenMPCaptureRegionForClause( | ||||||||
12598 | DKind, OMPC_if, LangOpts.OpenMP, NameModifier); | ||||||||
12599 | if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { | ||||||||
12600 | ValExpr = MakeFullExpr(ValExpr).get(); | ||||||||
12601 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; | ||||||||
12602 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); | ||||||||
12603 | HelperValStmt = buildPreInits(Context, Captures); | ||||||||
12604 | } | ||||||||
12605 | } | ||||||||
12606 | |||||||||
12607 | return new (Context) | ||||||||
12608 | OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, | ||||||||
12609 | LParenLoc, NameModifierLoc, ColonLoc, EndLoc); | ||||||||
12610 | } | ||||||||
12611 | |||||||||
12612 | OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, | ||||||||
12613 | SourceLocation StartLoc, | ||||||||
12614 | SourceLocation LParenLoc, | ||||||||
12615 | SourceLocation EndLoc) { | ||||||||
12616 | Expr *ValExpr = Condition; | ||||||||
12617 | Stmt *HelperValStmt = nullptr; | ||||||||
12618 | OpenMPDirectiveKind CaptureRegion = OMPD_unknown; | ||||||||
12619 | if (!Condition->isValueDependent() && !Condition->isTypeDependent() && | ||||||||
12620 | !Condition->isInstantiationDependent() && | ||||||||
12621 | !Condition->containsUnexpandedParameterPack()) { | ||||||||
12622 | ExprResult Val = CheckBooleanCondition(StartLoc, Condition); | ||||||||
12623 | if (Val.isInvalid()) | ||||||||
12624 | return nullptr; | ||||||||
12625 | |||||||||
12626 | ValExpr = MakeFullExpr(Val.get()).get(); | ||||||||
12627 | |||||||||
12628 | OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); | ||||||||
12629 | CaptureRegion = | ||||||||
12630 | getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); | ||||||||
12631 | if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { | ||||||||
12632 | ValExpr = MakeFullExpr(ValExpr).get(); | ||||||||
12633 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; | ||||||||
12634 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); | ||||||||
12635 | HelperValStmt = buildPreInits(Context, Captures); | ||||||||
12636 | } | ||||||||
12637 | } | ||||||||
12638 | |||||||||
12639 | return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, | ||||||||
12640 | StartLoc, LParenLoc, EndLoc); | ||||||||
12641 | } | ||||||||
12642 | |||||||||
12643 | ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, | ||||||||
12644 | Expr *Op) { | ||||||||
12645 | if (!Op) | ||||||||
12646 | return ExprError(); | ||||||||
12647 | |||||||||
12648 | class IntConvertDiagnoser : public ICEConvertDiagnoser { | ||||||||
12649 | public: | ||||||||
12650 | IntConvertDiagnoser() | ||||||||
12651 | : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} | ||||||||
12652 | SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, | ||||||||
12653 | QualType T) override { | ||||||||
12654 | return S.Diag(Loc, diag::err_omp_not_integral) << T; | ||||||||
12655 | } | ||||||||
12656 | SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, | ||||||||
12657 | QualType T) override { | ||||||||
12658 | return S.Diag(Loc, diag::err_omp_incomplete_type) << T; | ||||||||
12659 | } | ||||||||
12660 | SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, | ||||||||
12661 | QualType T, | ||||||||
12662 | QualType ConvTy) override { | ||||||||
12663 | return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; | ||||||||
12664 | } | ||||||||
12665 | SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, | ||||||||
12666 | QualType ConvTy) override { | ||||||||
12667 | return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) | ||||||||
12668 | << ConvTy->isEnumeralType() << ConvTy; | ||||||||
12669 | } | ||||||||
12670 | SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, | ||||||||
12671 | QualType T) override { | ||||||||
12672 | return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; | ||||||||
12673 | } | ||||||||
12674 | SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, | ||||||||
12675 | QualType ConvTy) override { | ||||||||
12676 | return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) | ||||||||
12677 | << ConvTy->isEnumeralType() << ConvTy; | ||||||||
12678 | } | ||||||||
12679 | SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, | ||||||||
12680 | QualType) override { | ||||||||
12681 | llvm_unreachable("conversion functions are permitted")::llvm::llvm_unreachable_internal("conversion functions are permitted" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 12681); | ||||||||
12682 | } | ||||||||
12683 | } ConvertDiagnoser; | ||||||||
12684 | return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); | ||||||||
12685 | } | ||||||||
12686 | |||||||||
12687 | static bool | ||||||||
12688 | isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, | ||||||||
12689 | bool StrictlyPositive, bool BuildCapture = false, | ||||||||
12690 | OpenMPDirectiveKind DKind = OMPD_unknown, | ||||||||
12691 | OpenMPDirectiveKind *CaptureRegion = nullptr, | ||||||||
12692 | Stmt **HelperValStmt = nullptr) { | ||||||||
12693 | if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && | ||||||||
12694 | !ValExpr->isInstantiationDependent()) { | ||||||||
12695 | SourceLocation Loc = ValExpr->getExprLoc(); | ||||||||
12696 | ExprResult Value = | ||||||||
12697 | SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); | ||||||||
12698 | if (Value.isInvalid()) | ||||||||
12699 | return false; | ||||||||
12700 | |||||||||
12701 | ValExpr = Value.get(); | ||||||||
12702 | // The expression must evaluate to a non-negative integer value. | ||||||||
12703 | if (Optional<llvm::APSInt> Result = | ||||||||
12704 | ValExpr->getIntegerConstantExpr(SemaRef.Context)) { | ||||||||
12705 | if (Result->isSigned() && | ||||||||
12706 | !((!StrictlyPositive && Result->isNonNegative()) || | ||||||||
12707 | (StrictlyPositive && Result->isStrictlyPositive()))) { | ||||||||
12708 | SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) | ||||||||
12709 | << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) | ||||||||
12710 | << ValExpr->getSourceRange(); | ||||||||
12711 | return false; | ||||||||
12712 | } | ||||||||
12713 | } | ||||||||
12714 | if (!BuildCapture) | ||||||||
12715 | return true; | ||||||||
12716 | *CaptureRegion = | ||||||||
12717 | getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); | ||||||||
12718 | if (*CaptureRegion != OMPD_unknown && | ||||||||
12719 | !SemaRef.CurContext->isDependentContext()) { | ||||||||
12720 | ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); | ||||||||
12721 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; | ||||||||
12722 | ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); | ||||||||
12723 | *HelperValStmt = buildPreInits(SemaRef.Context, Captures); | ||||||||
12724 | } | ||||||||
12725 | } | ||||||||
12726 | return true; | ||||||||
12727 | } | ||||||||
12728 | |||||||||
12729 | OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, | ||||||||
12730 | SourceLocation StartLoc, | ||||||||
12731 | SourceLocation LParenLoc, | ||||||||
12732 | SourceLocation EndLoc) { | ||||||||
12733 | Expr *ValExpr = NumThreads; | ||||||||
12734 | Stmt *HelperValStmt = nullptr; | ||||||||
12735 | |||||||||
12736 | // OpenMP [2.5, Restrictions] | ||||||||
12737 | // The num_threads expression must evaluate to a positive integer value. | ||||||||
12738 | if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, | ||||||||
12739 | /*StrictlyPositive=*/true)) | ||||||||
12740 | return nullptr; | ||||||||
12741 | |||||||||
12742 | OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); | ||||||||
12743 | OpenMPDirectiveKind CaptureRegion = | ||||||||
12744 | getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); | ||||||||
12745 | if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { | ||||||||
12746 | ValExpr = MakeFullExpr(ValExpr).get(); | ||||||||
12747 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; | ||||||||
12748 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); | ||||||||
12749 | HelperValStmt = buildPreInits(Context, Captures); | ||||||||
12750 | } | ||||||||
12751 | |||||||||
12752 | return new (Context) OMPNumThreadsClause( | ||||||||
12753 | ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); | ||||||||
12754 | } | ||||||||
12755 | |||||||||
12756 | ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, | ||||||||
12757 | OpenMPClauseKind CKind, | ||||||||
12758 | bool StrictlyPositive) { | ||||||||
12759 | if (!E) | ||||||||
12760 | return ExprError(); | ||||||||
12761 | if (E->isValueDependent() || E->isTypeDependent() || | ||||||||
12762 | E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) | ||||||||
12763 | return E; | ||||||||
12764 | llvm::APSInt Result; | ||||||||
12765 | ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); | ||||||||
12766 | if (ICE.isInvalid()) | ||||||||
12767 | return ExprError(); | ||||||||
12768 | if ((StrictlyPositive && !Result.isStrictlyPositive()) || | ||||||||
12769 | (!StrictlyPositive && !Result.isNonNegative())) { | ||||||||
12770 | Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) | ||||||||
12771 | << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) | ||||||||
12772 | << E->getSourceRange(); | ||||||||
12773 | return ExprError(); | ||||||||
12774 | } | ||||||||
12775 | if (CKind == OMPC_aligned && !Result.isPowerOf2()) { | ||||||||
12776 | Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) | ||||||||
12777 | << E->getSourceRange(); | ||||||||
12778 | return ExprError(); | ||||||||
12779 | } | ||||||||
12780 | if (CKind == OMPC_collapse && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getAssociatedLoops() == 1) | ||||||||
12781 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setAssociatedLoops(Result.getExtValue()); | ||||||||
12782 | else if (CKind == OMPC_ordered) | ||||||||
12783 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setAssociatedLoops(Result.getExtValue()); | ||||||||
12784 | return ICE; | ||||||||
12785 | } | ||||||||
12786 | |||||||||
12787 | OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, | ||||||||
12788 | SourceLocation LParenLoc, | ||||||||
12789 | SourceLocation EndLoc) { | ||||||||
12790 | // OpenMP [2.8.1, simd construct, Description] | ||||||||
12791 | // The parameter of the safelen clause must be a constant | ||||||||
12792 | // positive integer expression. | ||||||||
12793 | ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); | ||||||||
12794 | if (Safelen.isInvalid()) | ||||||||
12795 | return nullptr; | ||||||||
12796 | return new (Context) | ||||||||
12797 | OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); | ||||||||
12798 | } | ||||||||
12799 | |||||||||
12800 | OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, | ||||||||
12801 | SourceLocation LParenLoc, | ||||||||
12802 | SourceLocation EndLoc) { | ||||||||
12803 | // OpenMP [2.8.1, simd construct, Description] | ||||||||
12804 | // The parameter of the simdlen clause must be a constant | ||||||||
12805 | // positive integer expression. | ||||||||
12806 | ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); | ||||||||
12807 | if (Simdlen.isInvalid()) | ||||||||
12808 | return nullptr; | ||||||||
12809 | return new (Context) | ||||||||
12810 | OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); | ||||||||
12811 | } | ||||||||
12812 | |||||||||
12813 | /// Tries to find omp_allocator_handle_t type. | ||||||||
12814 | static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, | ||||||||
12815 | DSAStackTy *Stack) { | ||||||||
12816 | QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); | ||||||||
12817 | if (!OMPAllocatorHandleT.isNull()) | ||||||||
12818 | return true; | ||||||||
12819 | // Build the predefined allocator expressions. | ||||||||
12820 | bool ErrorFound = false; | ||||||||
12821 | for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { | ||||||||
12822 | auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); | ||||||||
12823 | StringRef Allocator = | ||||||||
12824 | OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); | ||||||||
12825 | DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); | ||||||||
12826 | auto *VD = dyn_cast_or_null<ValueDecl>( | ||||||||
12827 | S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); | ||||||||
12828 | if (!VD) { | ||||||||
12829 | ErrorFound = true; | ||||||||
12830 | break; | ||||||||
12831 | } | ||||||||
12832 | QualType AllocatorType = | ||||||||
12833 | VD->getType().getNonLValueExprType(S.getASTContext()); | ||||||||
12834 | ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); | ||||||||
12835 | if (!Res.isUsable()) { | ||||||||
12836 | ErrorFound = true; | ||||||||
12837 | break; | ||||||||
12838 | } | ||||||||
12839 | if (OMPAllocatorHandleT.isNull()) | ||||||||
12840 | OMPAllocatorHandleT = AllocatorType; | ||||||||
12841 | if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { | ||||||||
12842 | ErrorFound = true; | ||||||||
12843 | break; | ||||||||
12844 | } | ||||||||
12845 | Stack->setAllocator(AllocatorKind, Res.get()); | ||||||||
12846 | } | ||||||||
12847 | if (ErrorFound) { | ||||||||
12848 | S.Diag(Loc, diag::err_omp_implied_type_not_found) | ||||||||
12849 | << "omp_allocator_handle_t"; | ||||||||
12850 | return false; | ||||||||
12851 | } | ||||||||
12852 | OMPAllocatorHandleT.addConst(); | ||||||||
12853 | Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); | ||||||||
12854 | return true; | ||||||||
12855 | } | ||||||||
12856 | |||||||||
12857 | OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, | ||||||||
12858 | SourceLocation LParenLoc, | ||||||||
12859 | SourceLocation EndLoc) { | ||||||||
12860 | // OpenMP [2.11.3, allocate Directive, Description] | ||||||||
12861 | // allocator is an expression of omp_allocator_handle_t type. | ||||||||
12862 | if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||||
12863 | return nullptr; | ||||||||
12864 | |||||||||
12865 | ExprResult Allocator = DefaultLvalueConversion(A); | ||||||||
12866 | if (Allocator.isInvalid()) | ||||||||
12867 | return nullptr; | ||||||||
12868 | Allocator = PerformImplicitConversion(Allocator.get(), | ||||||||
12869 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPAllocatorHandleT(), | ||||||||
12870 | Sema::AA_Initializing, | ||||||||
12871 | /*AllowExplicit=*/true); | ||||||||
12872 | if (Allocator.isInvalid()) | ||||||||
12873 | return nullptr; | ||||||||
12874 | return new (Context) | ||||||||
12875 | OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); | ||||||||
12876 | } | ||||||||
12877 | |||||||||
12878 | OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, | ||||||||
12879 | SourceLocation StartLoc, | ||||||||
12880 | SourceLocation LParenLoc, | ||||||||
12881 | SourceLocation EndLoc) { | ||||||||
12882 | // OpenMP [2.7.1, loop construct, Description] | ||||||||
12883 | // OpenMP [2.8.1, simd construct, Description] | ||||||||
12884 | // OpenMP [2.9.6, distribute construct, Description] | ||||||||
12885 | // The parameter of the collapse clause must be a constant | ||||||||
12886 | // positive integer expression. | ||||||||
12887 | ExprResult NumForLoopsResult = | ||||||||
12888 | VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); | ||||||||
12889 | if (NumForLoopsResult.isInvalid()) | ||||||||
12890 | return nullptr; | ||||||||
12891 | return new (Context) | ||||||||
12892 | OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); | ||||||||
12893 | } | ||||||||
12894 | |||||||||
12895 | OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, | ||||||||
12896 | SourceLocation EndLoc, | ||||||||
12897 | SourceLocation LParenLoc, | ||||||||
12898 | Expr *NumForLoops) { | ||||||||
12899 | // OpenMP [2.7.1, loop construct, Description] | ||||||||
12900 | // OpenMP [2.8.1, simd construct, Description] | ||||||||
12901 | // OpenMP [2.9.6, distribute construct, Description] | ||||||||
12902 | // The parameter of the ordered clause must be a constant | ||||||||
12903 | // positive integer expression if any. | ||||||||
12904 | if (NumForLoops && LParenLoc.isValid()) { | ||||||||
12905 | ExprResult NumForLoopsResult = | ||||||||
12906 | VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); | ||||||||
12907 | if (NumForLoopsResult.isInvalid()) | ||||||||
12908 | return nullptr; | ||||||||
12909 | NumForLoops = NumForLoopsResult.get(); | ||||||||
12910 | } else { | ||||||||
12911 | NumForLoops = nullptr; | ||||||||
12912 | } | ||||||||
12913 | auto *Clause = OMPOrderedClause::Create( | ||||||||
12914 | Context, NumForLoops, NumForLoops ? DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getAssociatedLoops() : 0, | ||||||||
12915 | StartLoc, LParenLoc, EndLoc); | ||||||||
12916 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); | ||||||||
12917 | return Clause; | ||||||||
12918 | } | ||||||||
12919 | |||||||||
12920 | OMPClause *Sema::ActOnOpenMPSimpleClause( | ||||||||
12921 | OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, | ||||||||
12922 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { | ||||||||
12923 | OMPClause *Res = nullptr; | ||||||||
12924 | switch (Kind) { | ||||||||
12925 | case OMPC_default: | ||||||||
12926 | Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument), | ||||||||
12927 | ArgumentLoc, StartLoc, LParenLoc, EndLoc); | ||||||||
12928 | break; | ||||||||
12929 | case OMPC_proc_bind: | ||||||||
12930 | Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), | ||||||||
12931 | ArgumentLoc, StartLoc, LParenLoc, EndLoc); | ||||||||
12932 | break; | ||||||||
12933 | case OMPC_atomic_default_mem_order: | ||||||||
12934 | Res = ActOnOpenMPAtomicDefaultMemOrderClause( | ||||||||
12935 | static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), | ||||||||
12936 | ArgumentLoc, StartLoc, LParenLoc, EndLoc); | ||||||||
12937 | break; | ||||||||
12938 | case OMPC_order: | ||||||||
12939 | Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), | ||||||||
12940 | ArgumentLoc, StartLoc, LParenLoc, EndLoc); | ||||||||
12941 | break; | ||||||||
12942 | case OMPC_update: | ||||||||
12943 | Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument), | ||||||||
12944 | ArgumentLoc, StartLoc, LParenLoc, EndLoc); | ||||||||
12945 | break; | ||||||||
12946 | case OMPC_if: | ||||||||
12947 | case OMPC_final: | ||||||||
12948 | case OMPC_num_threads: | ||||||||
12949 | case OMPC_safelen: | ||||||||
12950 | case OMPC_simdlen: | ||||||||
12951 | case OMPC_allocator: | ||||||||
12952 | case OMPC_collapse: | ||||||||
12953 | case OMPC_schedule: | ||||||||
12954 | case OMPC_private: | ||||||||
12955 | case OMPC_firstprivate: | ||||||||
12956 | case OMPC_lastprivate: | ||||||||
12957 | case OMPC_shared: | ||||||||
12958 | case OMPC_reduction: | ||||||||
12959 | case OMPC_task_reduction: | ||||||||
12960 | case OMPC_in_reduction: | ||||||||
12961 | case OMPC_linear: | ||||||||
12962 | case OMPC_aligned: | ||||||||
12963 | case OMPC_copyin: | ||||||||
12964 | case OMPC_copyprivate: | ||||||||
12965 | case OMPC_ordered: | ||||||||
12966 | case OMPC_nowait: | ||||||||
12967 | case OMPC_untied: | ||||||||
12968 | case OMPC_mergeable: | ||||||||
12969 | case OMPC_threadprivate: | ||||||||
12970 | case OMPC_allocate: | ||||||||
12971 | case OMPC_flush: | ||||||||
12972 | case OMPC_depobj: | ||||||||
12973 | case OMPC_read: | ||||||||
12974 | case OMPC_write: | ||||||||
12975 | case OMPC_capture: | ||||||||
12976 | case OMPC_seq_cst: | ||||||||
12977 | case OMPC_acq_rel: | ||||||||
12978 | case OMPC_acquire: | ||||||||
12979 | case OMPC_release: | ||||||||
12980 | case OMPC_relaxed: | ||||||||
12981 | case OMPC_depend: | ||||||||
12982 | case OMPC_device: | ||||||||
12983 | case OMPC_threads: | ||||||||
12984 | case OMPC_simd: | ||||||||
12985 | case OMPC_map: | ||||||||
12986 | case OMPC_num_teams: | ||||||||
12987 | case OMPC_thread_limit: | ||||||||
12988 | case OMPC_priority: | ||||||||
12989 | case OMPC_grainsize: | ||||||||
12990 | case OMPC_nogroup: | ||||||||
12991 | case OMPC_num_tasks: | ||||||||
12992 | case OMPC_hint: | ||||||||
12993 | case OMPC_dist_schedule: | ||||||||
12994 | case OMPC_defaultmap: | ||||||||
12995 | case OMPC_unknown: | ||||||||
12996 | case OMPC_uniform: | ||||||||
12997 | case OMPC_to: | ||||||||
12998 | case OMPC_from: | ||||||||
12999 | case OMPC_use_device_ptr: | ||||||||
13000 | case OMPC_use_device_addr: | ||||||||
13001 | case OMPC_is_device_ptr: | ||||||||
13002 | case OMPC_unified_address: | ||||||||
13003 | case OMPC_unified_shared_memory: | ||||||||
13004 | case OMPC_reverse_offload: | ||||||||
13005 | case OMPC_dynamic_allocators: | ||||||||
13006 | case OMPC_device_type: | ||||||||
13007 | case OMPC_match: | ||||||||
13008 | case OMPC_nontemporal: | ||||||||
13009 | case OMPC_destroy: | ||||||||
13010 | case OMPC_detach: | ||||||||
13011 | case OMPC_inclusive: | ||||||||
13012 | case OMPC_exclusive: | ||||||||
13013 | case OMPC_uses_allocators: | ||||||||
13014 | case OMPC_affinity: | ||||||||
13015 | default: | ||||||||
13016 | llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 13016); | ||||||||
13017 | } | ||||||||
13018 | return Res; | ||||||||
13019 | } | ||||||||
13020 | |||||||||
13021 | static std::string | ||||||||
13022 | getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, | ||||||||
13023 | ArrayRef<unsigned> Exclude = llvm::None) { | ||||||||
13024 | SmallString<256> Buffer; | ||||||||
13025 | llvm::raw_svector_ostream Out(Buffer); | ||||||||
13026 | unsigned Skipped = Exclude.size(); | ||||||||
13027 | auto S = Exclude.begin(), E = Exclude.end(); | ||||||||
13028 | for (unsigned I = First; I < Last; ++I) { | ||||||||
13029 | if (std::find(S, E, I) != E) { | ||||||||
13030 | --Skipped; | ||||||||
13031 | continue; | ||||||||
13032 | } | ||||||||
13033 | Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; | ||||||||
13034 | if (I + Skipped + 2 == Last) | ||||||||
13035 | Out << " or "; | ||||||||
13036 | else if (I + Skipped + 1 != Last) | ||||||||
13037 | Out << ", "; | ||||||||
13038 | } | ||||||||
13039 | return std::string(Out.str()); | ||||||||
13040 | } | ||||||||
13041 | |||||||||
13042 | OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, | ||||||||
13043 | SourceLocation KindKwLoc, | ||||||||
13044 | SourceLocation StartLoc, | ||||||||
13045 | SourceLocation LParenLoc, | ||||||||
13046 | SourceLocation EndLoc) { | ||||||||
13047 | if (Kind == OMP_DEFAULT_unknown) { | ||||||||
13048 | Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) | ||||||||
13049 | << getListOfPossibleValues(OMPC_default, /*First=*/0, | ||||||||
13050 | /*Last=*/unsigned(OMP_DEFAULT_unknown)) | ||||||||
13051 | << getOpenMPClauseName(OMPC_default); | ||||||||
13052 | return nullptr; | ||||||||
13053 | } | ||||||||
13054 | |||||||||
13055 | switch (Kind) { | ||||||||
13056 | case OMP_DEFAULT_none: | ||||||||
13057 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setDefaultDSANone(KindKwLoc); | ||||||||
13058 | break; | ||||||||
13059 | case OMP_DEFAULT_shared: | ||||||||
13060 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setDefaultDSAShared(KindKwLoc); | ||||||||
13061 | break; | ||||||||
13062 | case OMP_DEFAULT_firstprivate: | ||||||||
13063 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setDefaultDSAFirstPrivate(KindKwLoc); | ||||||||
13064 | break; | ||||||||
13065 | default: | ||||||||
13066 | llvm_unreachable("DSA unexpected in OpenMP default clause")::llvm::llvm_unreachable_internal("DSA unexpected in OpenMP default clause" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 13066); | ||||||||
13067 | } | ||||||||
13068 | |||||||||
13069 | return new (Context) | ||||||||
13070 | OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); | ||||||||
13071 | } | ||||||||
13072 | |||||||||
13073 | OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, | ||||||||
13074 | SourceLocation KindKwLoc, | ||||||||
13075 | SourceLocation StartLoc, | ||||||||
13076 | SourceLocation LParenLoc, | ||||||||
13077 | SourceLocation EndLoc) { | ||||||||
13078 | if (Kind == OMP_PROC_BIND_unknown) { | ||||||||
13079 | Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) | ||||||||
13080 | << getListOfPossibleValues(OMPC_proc_bind, | ||||||||
13081 | /*First=*/unsigned(OMP_PROC_BIND_master), | ||||||||
13082 | /*Last=*/5) | ||||||||
13083 | << getOpenMPClauseName(OMPC_proc_bind); | ||||||||
13084 | return nullptr; | ||||||||
13085 | } | ||||||||
13086 | return new (Context) | ||||||||
13087 | OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); | ||||||||
13088 | } | ||||||||
13089 | |||||||||
13090 | OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( | ||||||||
13091 | OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, | ||||||||
13092 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { | ||||||||
13093 | if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { | ||||||||
13094 | Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) | ||||||||
13095 | << getListOfPossibleValues( | ||||||||
13096 | OMPC_atomic_default_mem_order, /*First=*/0, | ||||||||
13097 | /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) | ||||||||
13098 | << getOpenMPClauseName(OMPC_atomic_default_mem_order); | ||||||||
13099 | return nullptr; | ||||||||
13100 | } | ||||||||
13101 | return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, | ||||||||
13102 | LParenLoc, EndLoc); | ||||||||
13103 | } | ||||||||
13104 | |||||||||
13105 | OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, | ||||||||
13106 | SourceLocation KindKwLoc, | ||||||||
13107 | SourceLocation StartLoc, | ||||||||
13108 | SourceLocation LParenLoc, | ||||||||
13109 | SourceLocation EndLoc) { | ||||||||
13110 | if (Kind == OMPC_ORDER_unknown) { | ||||||||
13111 | static_assert(OMPC_ORDER_unknown > 0, | ||||||||
13112 | "OMPC_ORDER_unknown not greater than 0"); | ||||||||
13113 | Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) | ||||||||
13114 | << getListOfPossibleValues(OMPC_order, /*First=*/0, | ||||||||
13115 | /*Last=*/OMPC_ORDER_unknown) | ||||||||
13116 | << getOpenMPClauseName(OMPC_order); | ||||||||
13117 | return nullptr; | ||||||||
13118 | } | ||||||||
13119 | return new (Context) | ||||||||
13120 | OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); | ||||||||
13121 | } | ||||||||
13122 | |||||||||
13123 | OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, | ||||||||
13124 | SourceLocation KindKwLoc, | ||||||||
13125 | SourceLocation StartLoc, | ||||||||
13126 | SourceLocation LParenLoc, | ||||||||
13127 | SourceLocation EndLoc) { | ||||||||
13128 | if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source || | ||||||||
13129 | Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) { | ||||||||
13130 | unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink, | ||||||||
13131 | OMPC_DEPEND_depobj}; | ||||||||
13132 | Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) | ||||||||
13133 | << getListOfPossibleValues(OMPC_depend, /*First=*/0, | ||||||||
13134 | /*Last=*/OMPC_DEPEND_unknown, Except) | ||||||||
13135 | << getOpenMPClauseName(OMPC_update); | ||||||||
13136 | return nullptr; | ||||||||
13137 | } | ||||||||
13138 | return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind, | ||||||||
13139 | EndLoc); | ||||||||
13140 | } | ||||||||
13141 | |||||||||
13142 | OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( | ||||||||
13143 | OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, | ||||||||
13144 | SourceLocation StartLoc, SourceLocation LParenLoc, | ||||||||
13145 | ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, | ||||||||
13146 | SourceLocation EndLoc) { | ||||||||
13147 | OMPClause *Res = nullptr; | ||||||||
13148 | switch (Kind) { | ||||||||
13149 | case OMPC_schedule: | ||||||||
13150 | enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; | ||||||||
13151 | assert(Argument.size() == NumberOfElements &&((Argument.size() == NumberOfElements && ArgumentLoc. size() == NumberOfElements) ? static_cast<void> (0) : __assert_fail ("Argument.size() == NumberOfElements && ArgumentLoc.size() == NumberOfElements" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 13152, __PRETTY_FUNCTION__)) | ||||||||
13152 | ArgumentLoc.size() == NumberOfElements)((Argument.size() == NumberOfElements && ArgumentLoc. size() == NumberOfElements) ? static_cast<void> (0) : __assert_fail ("Argument.size() == NumberOfElements && ArgumentLoc.size() == NumberOfElements" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 13152, __PRETTY_FUNCTION__)); | ||||||||
13153 | Res = ActOnOpenMPScheduleClause( | ||||||||
13154 | static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), | ||||||||
13155 | static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), | ||||||||
13156 | static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, | ||||||||
13157 | StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], | ||||||||
13158 | ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); | ||||||||
13159 | break; | ||||||||
13160 | case OMPC_if: | ||||||||
13161 | assert(Argument.size() == 1 && ArgumentLoc.size() == 1)((Argument.size() == 1 && ArgumentLoc.size() == 1) ? static_cast <void> (0) : __assert_fail ("Argument.size() == 1 && ArgumentLoc.size() == 1" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 13161, __PRETTY_FUNCTION__)); | ||||||||
13162 | Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), | ||||||||
13163 | Expr, StartLoc, LParenLoc, ArgumentLoc.back(), | ||||||||
13164 | DelimLoc, EndLoc); | ||||||||
13165 | break; | ||||||||
13166 | case OMPC_dist_schedule: | ||||||||
13167 | Res = ActOnOpenMPDistScheduleClause( | ||||||||
13168 | static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, | ||||||||
13169 | StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); | ||||||||
13170 | break; | ||||||||
13171 | case OMPC_defaultmap: | ||||||||
13172 | enum { Modifier, DefaultmapKind }; | ||||||||
13173 | Res = ActOnOpenMPDefaultmapClause( | ||||||||
13174 | static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), | ||||||||
13175 | static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), | ||||||||
13176 | StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], | ||||||||
13177 | EndLoc); | ||||||||
13178 | break; | ||||||||
13179 | case OMPC_device: | ||||||||
13180 | assert(Argument.size() == 1 && ArgumentLoc.size() == 1)((Argument.size() == 1 && ArgumentLoc.size() == 1) ? static_cast <void> (0) : __assert_fail ("Argument.size() == 1 && ArgumentLoc.size() == 1" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 13180, __PRETTY_FUNCTION__)); | ||||||||
13181 | Res = ActOnOpenMPDeviceClause( | ||||||||
13182 | static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr, | ||||||||
13183 | StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); | ||||||||
13184 | break; | ||||||||
13185 | case OMPC_final: | ||||||||
13186 | case OMPC_num_threads: | ||||||||
13187 | case OMPC_safelen: | ||||||||
13188 | case OMPC_simdlen: | ||||||||
13189 | case OMPC_allocator: | ||||||||
13190 | case OMPC_collapse: | ||||||||
13191 | case OMPC_default: | ||||||||
13192 | case OMPC_proc_bind: | ||||||||
13193 | case OMPC_private: | ||||||||
13194 | case OMPC_firstprivate: | ||||||||
13195 | case OMPC_lastprivate: | ||||||||
13196 | case OMPC_shared: | ||||||||
13197 | case OMPC_reduction: | ||||||||
13198 | case OMPC_task_reduction: | ||||||||
13199 | case OMPC_in_reduction: | ||||||||
13200 | case OMPC_linear: | ||||||||
13201 | case OMPC_aligned: | ||||||||
13202 | case OMPC_copyin: | ||||||||
13203 | case OMPC_copyprivate: | ||||||||
13204 | case OMPC_ordered: | ||||||||
13205 | case OMPC_nowait: | ||||||||
13206 | case OMPC_untied: | ||||||||
13207 | case OMPC_mergeable: | ||||||||
13208 | case OMPC_threadprivate: | ||||||||
13209 | case OMPC_allocate: | ||||||||
13210 | case OMPC_flush: | ||||||||
13211 | case OMPC_depobj: | ||||||||
13212 | case OMPC_read: | ||||||||
13213 | case OMPC_write: | ||||||||
13214 | case OMPC_update: | ||||||||
13215 | case OMPC_capture: | ||||||||
13216 | case OMPC_seq_cst: | ||||||||
13217 | case OMPC_acq_rel: | ||||||||
13218 | case OMPC_acquire: | ||||||||
13219 | case OMPC_release: | ||||||||
13220 | case OMPC_relaxed: | ||||||||
13221 | case OMPC_depend: | ||||||||
13222 | case OMPC_threads: | ||||||||
13223 | case OMPC_simd: | ||||||||
13224 | case OMPC_map: | ||||||||
13225 | case OMPC_num_teams: | ||||||||
13226 | case OMPC_thread_limit: | ||||||||
13227 | case OMPC_priority: | ||||||||
13228 | case OMPC_grainsize: | ||||||||
13229 | case OMPC_nogroup: | ||||||||
13230 | case OMPC_num_tasks: | ||||||||
13231 | case OMPC_hint: | ||||||||
13232 | case OMPC_unknown: | ||||||||
13233 | case OMPC_uniform: | ||||||||
13234 | case OMPC_to: | ||||||||
13235 | case OMPC_from: | ||||||||
13236 | case OMPC_use_device_ptr: | ||||||||
13237 | case OMPC_use_device_addr: | ||||||||
13238 | case OMPC_is_device_ptr: | ||||||||
13239 | case OMPC_unified_address: | ||||||||
13240 | case OMPC_unified_shared_memory: | ||||||||
13241 | case OMPC_reverse_offload: | ||||||||
13242 | case OMPC_dynamic_allocators: | ||||||||
13243 | case OMPC_atomic_default_mem_order: | ||||||||
13244 | case OMPC_device_type: | ||||||||
13245 | case OMPC_match: | ||||||||
13246 | case OMPC_nontemporal: | ||||||||
13247 | case OMPC_order: | ||||||||
13248 | case OMPC_destroy: | ||||||||
13249 | case OMPC_detach: | ||||||||
13250 | case OMPC_inclusive: | ||||||||
13251 | case OMPC_exclusive: | ||||||||
13252 | case OMPC_uses_allocators: | ||||||||
13253 | case OMPC_affinity: | ||||||||
13254 | default: | ||||||||
13255 | llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 13255); | ||||||||
13256 | } | ||||||||
13257 | return Res; | ||||||||
13258 | } | ||||||||
13259 | |||||||||
13260 | static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, | ||||||||
13261 | OpenMPScheduleClauseModifier M2, | ||||||||
13262 | SourceLocation M1Loc, SourceLocation M2Loc) { | ||||||||
13263 | if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { | ||||||||
13264 | SmallVector<unsigned, 2> Excluded; | ||||||||
13265 | if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) | ||||||||
13266 | Excluded.push_back(M2); | ||||||||
13267 | if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) | ||||||||
13268 | Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); | ||||||||
13269 | if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) | ||||||||
13270 | Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); | ||||||||
13271 | S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) | ||||||||
13272 | << getListOfPossibleValues(OMPC_schedule, | ||||||||
13273 | /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, | ||||||||
13274 | /*Last=*/OMPC_SCHEDULE_MODIFIER_last, | ||||||||
13275 | Excluded) | ||||||||
13276 | << getOpenMPClauseName(OMPC_schedule); | ||||||||
13277 | return true; | ||||||||
13278 | } | ||||||||
13279 | return false; | ||||||||
13280 | } | ||||||||
13281 | |||||||||
13282 | OMPClause *Sema::ActOnOpenMPScheduleClause( | ||||||||
13283 | OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, | ||||||||
13284 | OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, | ||||||||
13285 | SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, | ||||||||
13286 | SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { | ||||||||
13287 | if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || | ||||||||
13288 | checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) | ||||||||
13289 | return nullptr; | ||||||||
13290 | // OpenMP, 2.7.1, Loop Construct, Restrictions | ||||||||
13291 | // Either the monotonic modifier or the nonmonotonic modifier can be specified | ||||||||
13292 | // but not both. | ||||||||
13293 | if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || | ||||||||
13294 | (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && | ||||||||
13295 | M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || | ||||||||
13296 | (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && | ||||||||
13297 | M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { | ||||||||
13298 | Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) | ||||||||
13299 | << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) | ||||||||
13300 | << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); | ||||||||
13301 | return nullptr; | ||||||||
13302 | } | ||||||||
13303 | if (Kind == OMPC_SCHEDULE_unknown) { | ||||||||
13304 | std::string Values; | ||||||||
13305 | if (M1Loc.isInvalid() && M2Loc.isInvalid()) { | ||||||||
13306 | unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; | ||||||||
13307 | Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, | ||||||||
13308 | /*Last=*/OMPC_SCHEDULE_MODIFIER_last, | ||||||||
13309 | Exclude); | ||||||||
13310 | } else { | ||||||||
13311 | Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, | ||||||||
13312 | /*Last=*/OMPC_SCHEDULE_unknown); | ||||||||
13313 | } | ||||||||
13314 | Diag(KindLoc, diag::err_omp_unexpected_clause_value) | ||||||||
13315 | << Values << getOpenMPClauseName(OMPC_schedule); | ||||||||
13316 | return nullptr; | ||||||||
13317 | } | ||||||||
13318 | // OpenMP, 2.7.1, Loop Construct, Restrictions | ||||||||
13319 | // The nonmonotonic modifier can only be specified with schedule(dynamic) or | ||||||||
13320 | // schedule(guided). | ||||||||
13321 | // OpenMP 5.0 does not have this restriction. | ||||||||
13322 | if (LangOpts.OpenMP < 50 && | ||||||||
13323 | (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || | ||||||||
13324 | M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && | ||||||||
13325 | Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { | ||||||||
13326 | Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, | ||||||||
13327 | diag::err_omp_schedule_nonmonotonic_static); | ||||||||
13328 | return nullptr; | ||||||||
13329 | } | ||||||||
13330 | Expr *ValExpr = ChunkSize; | ||||||||
13331 | Stmt *HelperValStmt = nullptr; | ||||||||
13332 | if (ChunkSize) { | ||||||||
13333 | if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && | ||||||||
13334 | !ChunkSize->isInstantiationDependent() && | ||||||||
13335 | !ChunkSize->containsUnexpandedParameterPack()) { | ||||||||
13336 | SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); | ||||||||
13337 | ExprResult Val = | ||||||||
13338 | PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); | ||||||||
13339 | if (Val.isInvalid()) | ||||||||
13340 | return nullptr; | ||||||||
13341 | |||||||||
13342 | ValExpr = Val.get(); | ||||||||
13343 | |||||||||
13344 | // OpenMP [2.7.1, Restrictions] | ||||||||
13345 | // chunk_size must be a loop invariant integer expression with a positive | ||||||||
13346 | // value. | ||||||||
13347 | if (Optional<llvm::APSInt> Result = | ||||||||
13348 | ValExpr->getIntegerConstantExpr(Context)) { | ||||||||
13349 | if (Result->isSigned() && !Result->isStrictlyPositive()) { | ||||||||
13350 | Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) | ||||||||
13351 | << "schedule" << 1 << ChunkSize->getSourceRange(); | ||||||||
13352 | return nullptr; | ||||||||
13353 | } | ||||||||
13354 | } else if (getOpenMPCaptureRegionForClause( | ||||||||
13355 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(), OMPC_schedule, | ||||||||
13356 | LangOpts.OpenMP) != OMPD_unknown && | ||||||||
13357 | !CurContext->isDependentContext()) { | ||||||||
13358 | ValExpr = MakeFullExpr(ValExpr).get(); | ||||||||
13359 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; | ||||||||
13360 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); | ||||||||
13361 | HelperValStmt = buildPreInits(Context, Captures); | ||||||||
13362 | } | ||||||||
13363 | } | ||||||||
13364 | } | ||||||||
13365 | |||||||||
13366 | return new (Context) | ||||||||
13367 | OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, | ||||||||
13368 | ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); | ||||||||
13369 | } | ||||||||
13370 | |||||||||
13371 | OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, | ||||||||
13372 | SourceLocation StartLoc, | ||||||||
13373 | SourceLocation EndLoc) { | ||||||||
13374 | OMPClause *Res = nullptr; | ||||||||
13375 | switch (Kind) { | ||||||||
13376 | case OMPC_ordered: | ||||||||
13377 | Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); | ||||||||
13378 | break; | ||||||||
13379 | case OMPC_nowait: | ||||||||
13380 | Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); | ||||||||
13381 | break; | ||||||||
13382 | case OMPC_untied: | ||||||||
13383 | Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); | ||||||||
13384 | break; | ||||||||
13385 | case OMPC_mergeable: | ||||||||
13386 | Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); | ||||||||
13387 | break; | ||||||||
13388 | case OMPC_read: | ||||||||
13389 | Res = ActOnOpenMPReadClause(StartLoc, EndLoc); | ||||||||
13390 | break; | ||||||||
13391 | case OMPC_write: | ||||||||
13392 | Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); | ||||||||
13393 | break; | ||||||||
13394 | case OMPC_update: | ||||||||
13395 | Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); | ||||||||
13396 | break; | ||||||||
13397 | case OMPC_capture: | ||||||||
13398 | Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); | ||||||||
13399 | break; | ||||||||
13400 | case OMPC_seq_cst: | ||||||||
13401 | Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); | ||||||||
13402 | break; | ||||||||
13403 | case OMPC_acq_rel: | ||||||||
13404 | Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); | ||||||||
13405 | break; | ||||||||
13406 | case OMPC_acquire: | ||||||||
13407 | Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); | ||||||||
13408 | break; | ||||||||
13409 | case OMPC_release: | ||||||||
13410 | Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); | ||||||||
13411 | break; | ||||||||
13412 | case OMPC_relaxed: | ||||||||
13413 | Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); | ||||||||
13414 | break; | ||||||||
13415 | case OMPC_threads: | ||||||||
13416 | Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); | ||||||||
13417 | break; | ||||||||
13418 | case OMPC_simd: | ||||||||
13419 | Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); | ||||||||
13420 | break; | ||||||||
13421 | case OMPC_nogroup: | ||||||||
13422 | Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); | ||||||||
13423 | break; | ||||||||
13424 | case OMPC_unified_address: | ||||||||
13425 | Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); | ||||||||
13426 | break; | ||||||||
13427 | case OMPC_unified_shared_memory: | ||||||||
13428 | Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); | ||||||||
13429 | break; | ||||||||
13430 | case OMPC_reverse_offload: | ||||||||
13431 | Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); | ||||||||
13432 | break; | ||||||||
13433 | case OMPC_dynamic_allocators: | ||||||||
13434 | Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); | ||||||||
13435 | break; | ||||||||
13436 | case OMPC_destroy: | ||||||||
13437 | Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc); | ||||||||
13438 | break; | ||||||||
13439 | case OMPC_if: | ||||||||
13440 | case OMPC_final: | ||||||||
13441 | case OMPC_num_threads: | ||||||||
13442 | case OMPC_safelen: | ||||||||
13443 | case OMPC_simdlen: | ||||||||
13444 | case OMPC_allocator: | ||||||||
13445 | case OMPC_collapse: | ||||||||
13446 | case OMPC_schedule: | ||||||||
13447 | case OMPC_private: | ||||||||
13448 | case OMPC_firstprivate: | ||||||||
13449 | case OMPC_lastprivate: | ||||||||
13450 | case OMPC_shared: | ||||||||
13451 | case OMPC_reduction: | ||||||||
13452 | case OMPC_task_reduction: | ||||||||
13453 | case OMPC_in_reduction: | ||||||||
13454 | case OMPC_linear: | ||||||||
13455 | case OMPC_aligned: | ||||||||
13456 | case OMPC_copyin: | ||||||||
13457 | case OMPC_copyprivate: | ||||||||
13458 | case OMPC_default: | ||||||||
13459 | case OMPC_proc_bind: | ||||||||
13460 | case OMPC_threadprivate: | ||||||||
13461 | case OMPC_allocate: | ||||||||
13462 | case OMPC_flush: | ||||||||
13463 | case OMPC_depobj: | ||||||||
13464 | case OMPC_depend: | ||||||||
13465 | case OMPC_device: | ||||||||
13466 | case OMPC_map: | ||||||||
13467 | case OMPC_num_teams: | ||||||||
13468 | case OMPC_thread_limit: | ||||||||
13469 | case OMPC_priority: | ||||||||
13470 | case OMPC_grainsize: | ||||||||
13471 | case OMPC_num_tasks: | ||||||||
13472 | case OMPC_hint: | ||||||||
13473 | case OMPC_dist_schedule: | ||||||||
13474 | case OMPC_defaultmap: | ||||||||
13475 | case OMPC_unknown: | ||||||||
13476 | case OMPC_uniform: | ||||||||
13477 | case OMPC_to: | ||||||||
13478 | case OMPC_from: | ||||||||
13479 | case OMPC_use_device_ptr: | ||||||||
13480 | case OMPC_use_device_addr: | ||||||||
13481 | case OMPC_is_device_ptr: | ||||||||
13482 | case OMPC_atomic_default_mem_order: | ||||||||
13483 | case OMPC_device_type: | ||||||||
13484 | case OMPC_match: | ||||||||
13485 | case OMPC_nontemporal: | ||||||||
13486 | case OMPC_order: | ||||||||
13487 | case OMPC_detach: | ||||||||
13488 | case OMPC_inclusive: | ||||||||
13489 | case OMPC_exclusive: | ||||||||
13490 | case OMPC_uses_allocators: | ||||||||
13491 | case OMPC_affinity: | ||||||||
13492 | default: | ||||||||
13493 | llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 13493); | ||||||||
13494 | } | ||||||||
13495 | return Res; | ||||||||
13496 | } | ||||||||
13497 | |||||||||
13498 | OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, | ||||||||
13499 | SourceLocation EndLoc) { | ||||||||
13500 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setNowaitRegion(); | ||||||||
13501 | return new (Context) OMPNowaitClause(StartLoc, EndLoc); | ||||||||
13502 | } | ||||||||
13503 | |||||||||
13504 | OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, | ||||||||
13505 | SourceLocation EndLoc) { | ||||||||
13506 | return new (Context) OMPUntiedClause(StartLoc, EndLoc); | ||||||||
13507 | } | ||||||||
13508 | |||||||||
13509 | OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, | ||||||||
13510 | SourceLocation EndLoc) { | ||||||||
13511 | return new (Context) OMPMergeableClause(StartLoc, EndLoc); | ||||||||
13512 | } | ||||||||
13513 | |||||||||
13514 | OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, | ||||||||
13515 | SourceLocation EndLoc) { | ||||||||
13516 | return new (Context) OMPReadClause(StartLoc, EndLoc); | ||||||||
13517 | } | ||||||||
13518 | |||||||||
13519 | OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, | ||||||||
13520 | SourceLocation EndLoc) { | ||||||||
13521 | return new (Context) OMPWriteClause(StartLoc, EndLoc); | ||||||||
13522 | } | ||||||||
13523 | |||||||||
13524 | OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, | ||||||||
13525 | SourceLocation EndLoc) { | ||||||||
13526 | return OMPUpdateClause::Create(Context, StartLoc, EndLoc); | ||||||||
13527 | } | ||||||||
13528 | |||||||||
13529 | OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, | ||||||||
13530 | SourceLocation EndLoc) { | ||||||||
13531 | return new (Context) OMPCaptureClause(StartLoc, EndLoc); | ||||||||
13532 | } | ||||||||
13533 | |||||||||
13534 | OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, | ||||||||
13535 | SourceLocation EndLoc) { | ||||||||
13536 | return new (Context) OMPSeqCstClause(StartLoc, EndLoc); | ||||||||
13537 | } | ||||||||
13538 | |||||||||
13539 | OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, | ||||||||
13540 | SourceLocation EndLoc) { | ||||||||
13541 | return new (Context) OMPAcqRelClause(StartLoc, EndLoc); | ||||||||
13542 | } | ||||||||
13543 | |||||||||
13544 | OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, | ||||||||
13545 | SourceLocation EndLoc) { | ||||||||
13546 | return new (Context) OMPAcquireClause(StartLoc, EndLoc); | ||||||||
13547 | } | ||||||||
13548 | |||||||||
13549 | OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, | ||||||||
13550 | SourceLocation EndLoc) { | ||||||||
13551 | return new (Context) OMPReleaseClause(StartLoc, EndLoc); | ||||||||
13552 | } | ||||||||
13553 | |||||||||
13554 | OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, | ||||||||
13555 | SourceLocation EndLoc) { | ||||||||
13556 | return new (Context) OMPRelaxedClause(StartLoc, EndLoc); | ||||||||
13557 | } | ||||||||
13558 | |||||||||
13559 | OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, | ||||||||
13560 | SourceLocation EndLoc) { | ||||||||
13561 | return new (Context) OMPThreadsClause(StartLoc, EndLoc); | ||||||||
13562 | } | ||||||||
13563 | |||||||||
13564 | OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, | ||||||||
13565 | SourceLocation EndLoc) { | ||||||||
13566 | return new (Context) OMPSIMDClause(StartLoc, EndLoc); | ||||||||
13567 | } | ||||||||
13568 | |||||||||
13569 | OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, | ||||||||
13570 | SourceLocation EndLoc) { | ||||||||
13571 | return new (Context) OMPNogroupClause(StartLoc, EndLoc); | ||||||||
13572 | } | ||||||||
13573 | |||||||||
13574 | OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, | ||||||||
13575 | SourceLocation EndLoc) { | ||||||||
13576 | return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); | ||||||||
13577 | } | ||||||||
13578 | |||||||||
13579 | OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, | ||||||||
13580 | SourceLocation EndLoc) { | ||||||||
13581 | return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); | ||||||||
13582 | } | ||||||||
13583 | |||||||||
13584 | OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, | ||||||||
13585 | SourceLocation EndLoc) { | ||||||||
13586 | return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); | ||||||||
13587 | } | ||||||||
13588 | |||||||||
13589 | OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, | ||||||||
13590 | SourceLocation EndLoc) { | ||||||||
13591 | return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); | ||||||||
13592 | } | ||||||||
13593 | |||||||||
13594 | OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc, | ||||||||
13595 | SourceLocation EndLoc) { | ||||||||
13596 | return new (Context) OMPDestroyClause(StartLoc, EndLoc); | ||||||||
13597 | } | ||||||||
13598 | |||||||||
13599 | OMPClause *Sema::ActOnOpenMPVarListClause( | ||||||||
13600 | OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr, | ||||||||
13601 | const OMPVarListLocTy &Locs, SourceLocation ColonLoc, | ||||||||
13602 | CXXScopeSpec &ReductionOrMapperIdScopeSpec, | ||||||||
13603 | DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, | ||||||||
13604 | ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, | ||||||||
13605 | ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, | ||||||||
13606 | SourceLocation ExtraModifierLoc, | ||||||||
13607 | ArrayRef<OpenMPMotionModifierKind> MotionModifiers, | ||||||||
13608 | ArrayRef<SourceLocation> MotionModifiersLoc) { | ||||||||
13609 | SourceLocation StartLoc = Locs.StartLoc; | ||||||||
13610 | SourceLocation LParenLoc = Locs.LParenLoc; | ||||||||
13611 | SourceLocation EndLoc = Locs.EndLoc; | ||||||||
13612 | OMPClause *Res = nullptr; | ||||||||
13613 | switch (Kind) { | ||||||||
13614 | case OMPC_private: | ||||||||
13615 | Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||||||
13616 | break; | ||||||||
13617 | case OMPC_firstprivate: | ||||||||
13618 | Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||||||
13619 | break; | ||||||||
13620 | case OMPC_lastprivate: | ||||||||
13621 | assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&((0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && "Unexpected lastprivate modifier.") ? static_cast <void> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && \"Unexpected lastprivate modifier.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 13622, __PRETTY_FUNCTION__)) | ||||||||
13622 | "Unexpected lastprivate modifier.")((0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && "Unexpected lastprivate modifier.") ? static_cast <void> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && \"Unexpected lastprivate modifier.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 13622, __PRETTY_FUNCTION__)); | ||||||||
13623 | Res = ActOnOpenMPLastprivateClause( | ||||||||
13624 | VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), | ||||||||
13625 | ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); | ||||||||
13626 | break; | ||||||||
13627 | case OMPC_shared: | ||||||||
13628 | Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||||||
13629 | break; | ||||||||
13630 | case OMPC_reduction: | ||||||||
13631 | assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&((0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && "Unexpected lastprivate modifier.") ? static_cast <void> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && \"Unexpected lastprivate modifier.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 13632, __PRETTY_FUNCTION__)) | ||||||||
13632 | "Unexpected lastprivate modifier.")((0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && "Unexpected lastprivate modifier.") ? static_cast <void> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && \"Unexpected lastprivate modifier.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 13632, __PRETTY_FUNCTION__)); | ||||||||
13633 | Res = ActOnOpenMPReductionClause( | ||||||||
13634 | VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier), | ||||||||
13635 | StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc, | ||||||||
13636 | ReductionOrMapperIdScopeSpec, ReductionOrMapperId); | ||||||||
13637 | break; | ||||||||
13638 | case OMPC_task_reduction: | ||||||||
13639 | Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, | ||||||||
13640 | EndLoc, ReductionOrMapperIdScopeSpec, | ||||||||
13641 | ReductionOrMapperId); | ||||||||
13642 | break; | ||||||||
13643 | case OMPC_in_reduction: | ||||||||
13644 | Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, | ||||||||
13645 | EndLoc, ReductionOrMapperIdScopeSpec, | ||||||||
13646 | ReductionOrMapperId); | ||||||||
13647 | break; | ||||||||
13648 | case OMPC_linear: | ||||||||
13649 | assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&((0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && "Unexpected linear modifier.") ? static_cast<void > (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && \"Unexpected linear modifier.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 13650, __PRETTY_FUNCTION__)) | ||||||||
13650 | "Unexpected linear modifier.")((0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && "Unexpected linear modifier.") ? static_cast<void > (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && \"Unexpected linear modifier.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 13650, __PRETTY_FUNCTION__)); | ||||||||
13651 | Res = ActOnOpenMPLinearClause( | ||||||||
13652 | VarList, DepModOrTailExpr, StartLoc, LParenLoc, | ||||||||
13653 | static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc, | ||||||||
13654 | ColonLoc, EndLoc); | ||||||||
13655 | break; | ||||||||
13656 | case OMPC_aligned: | ||||||||
13657 | Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc, | ||||||||
13658 | LParenLoc, ColonLoc, EndLoc); | ||||||||
13659 | break; | ||||||||
13660 | case OMPC_copyin: | ||||||||
13661 | Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||||||
13662 | break; | ||||||||
13663 | case OMPC_copyprivate: | ||||||||
13664 | Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||||||
13665 | break; | ||||||||
13666 | case OMPC_flush: | ||||||||
13667 | Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||||||
13668 | break; | ||||||||
13669 | case OMPC_depend: | ||||||||
13670 | assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&((0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && "Unexpected depend modifier.") ? static_cast<void > (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && \"Unexpected depend modifier.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 13671, __PRETTY_FUNCTION__)) | ||||||||
13671 | "Unexpected depend modifier.")((0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && "Unexpected depend modifier.") ? static_cast<void > (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && \"Unexpected depend modifier.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 13671, __PRETTY_FUNCTION__)); | ||||||||
13672 | Res = ActOnOpenMPDependClause( | ||||||||
13673 | DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier), | ||||||||
13674 | ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); | ||||||||
13675 | break; | ||||||||
13676 | case OMPC_map: | ||||||||
13677 | assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&((0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && "Unexpected map modifier.") ? static_cast<void > (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && \"Unexpected map modifier.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 13678, __PRETTY_FUNCTION__)) | ||||||||
13678 | "Unexpected map modifier.")((0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && "Unexpected map modifier.") ? static_cast<void > (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && \"Unexpected map modifier.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 13678, __PRETTY_FUNCTION__)); | ||||||||
13679 | Res = ActOnOpenMPMapClause( | ||||||||
13680 | MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec, | ||||||||
13681 | ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier), | ||||||||
13682 | IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs); | ||||||||
13683 | break; | ||||||||
13684 | case OMPC_to: | ||||||||
13685 | Res = ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc, | ||||||||
13686 | ReductionOrMapperIdScopeSpec, ReductionOrMapperId, | ||||||||
13687 | ColonLoc, VarList, Locs); | ||||||||
13688 | break; | ||||||||
13689 | case OMPC_from: | ||||||||
13690 | Res = ActOnOpenMPFromClause(MotionModifiers, MotionModifiersLoc, | ||||||||
13691 | ReductionOrMapperIdScopeSpec, | ||||||||
13692 | ReductionOrMapperId, ColonLoc, VarList, Locs); | ||||||||
13693 | break; | ||||||||
13694 | case OMPC_use_device_ptr: | ||||||||
13695 | Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); | ||||||||
13696 | break; | ||||||||
13697 | case OMPC_use_device_addr: | ||||||||
13698 | Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs); | ||||||||
13699 | break; | ||||||||
13700 | case OMPC_is_device_ptr: | ||||||||
13701 | Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); | ||||||||
13702 | break; | ||||||||
13703 | case OMPC_allocate: | ||||||||
13704 | Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc, | ||||||||
13705 | LParenLoc, ColonLoc, EndLoc); | ||||||||
13706 | break; | ||||||||
13707 | case OMPC_nontemporal: | ||||||||
13708 | Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||||||
13709 | break; | ||||||||
13710 | case OMPC_inclusive: | ||||||||
13711 | Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||||||
13712 | break; | ||||||||
13713 | case OMPC_exclusive: | ||||||||
13714 | Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||||||
13715 | break; | ||||||||
13716 | case OMPC_affinity: | ||||||||
13717 | Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc, | ||||||||
13718 | DepModOrTailExpr, VarList); | ||||||||
13719 | break; | ||||||||
13720 | case OMPC_if: | ||||||||
13721 | case OMPC_depobj: | ||||||||
13722 | case OMPC_final: | ||||||||
13723 | case OMPC_num_threads: | ||||||||
13724 | case OMPC_safelen: | ||||||||
13725 | case OMPC_simdlen: | ||||||||
13726 | case OMPC_allocator: | ||||||||
13727 | case OMPC_collapse: | ||||||||
13728 | case OMPC_default: | ||||||||
13729 | case OMPC_proc_bind: | ||||||||
13730 | case OMPC_schedule: | ||||||||
13731 | case OMPC_ordered: | ||||||||
13732 | case OMPC_nowait: | ||||||||
13733 | case OMPC_untied: | ||||||||
13734 | case OMPC_mergeable: | ||||||||
13735 | case OMPC_threadprivate: | ||||||||
13736 | case OMPC_read: | ||||||||
13737 | case OMPC_write: | ||||||||
13738 | case OMPC_update: | ||||||||
13739 | case OMPC_capture: | ||||||||
13740 | case OMPC_seq_cst: | ||||||||
13741 | case OMPC_acq_rel: | ||||||||
13742 | case OMPC_acquire: | ||||||||
13743 | case OMPC_release: | ||||||||
13744 | case OMPC_relaxed: | ||||||||
13745 | case OMPC_device: | ||||||||
13746 | case OMPC_threads: | ||||||||
13747 | case OMPC_simd: | ||||||||
13748 | case OMPC_num_teams: | ||||||||
13749 | case OMPC_thread_limit: | ||||||||
13750 | case OMPC_priority: | ||||||||
13751 | case OMPC_grainsize: | ||||||||
13752 | case OMPC_nogroup: | ||||||||
13753 | case OMPC_num_tasks: | ||||||||
13754 | case OMPC_hint: | ||||||||
13755 | case OMPC_dist_schedule: | ||||||||
13756 | case OMPC_defaultmap: | ||||||||
13757 | case OMPC_unknown: | ||||||||
13758 | case OMPC_uniform: | ||||||||
13759 | case OMPC_unified_address: | ||||||||
13760 | case OMPC_unified_shared_memory: | ||||||||
13761 | case OMPC_reverse_offload: | ||||||||
13762 | case OMPC_dynamic_allocators: | ||||||||
13763 | case OMPC_atomic_default_mem_order: | ||||||||
13764 | case OMPC_device_type: | ||||||||
13765 | case OMPC_match: | ||||||||
13766 | case OMPC_order: | ||||||||
13767 | case OMPC_destroy: | ||||||||
13768 | case OMPC_detach: | ||||||||
13769 | case OMPC_uses_allocators: | ||||||||
13770 | default: | ||||||||
13771 | llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 13771); | ||||||||
13772 | } | ||||||||
13773 | return Res; | ||||||||
13774 | } | ||||||||
13775 | |||||||||
13776 | ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, | ||||||||
13777 | ExprObjectKind OK, SourceLocation Loc) { | ||||||||
13778 | ExprResult Res = BuildDeclRefExpr( | ||||||||
13779 | Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); | ||||||||
13780 | if (!Res.isUsable()) | ||||||||
13781 | return ExprError(); | ||||||||
13782 | if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { | ||||||||
13783 | Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); | ||||||||
13784 | if (!Res.isUsable()) | ||||||||
13785 | return ExprError(); | ||||||||
13786 | } | ||||||||
13787 | if (VK != VK_LValue && Res.get()->isGLValue()) { | ||||||||
13788 | Res = DefaultLvalueConversion(Res.get()); | ||||||||
13789 | if (!Res.isUsable()) | ||||||||
13790 | return ExprError(); | ||||||||
13791 | } | ||||||||
13792 | return Res; | ||||||||
13793 | } | ||||||||
13794 | |||||||||
13795 | OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, | ||||||||
13796 | SourceLocation StartLoc, | ||||||||
13797 | SourceLocation LParenLoc, | ||||||||
13798 | SourceLocation EndLoc) { | ||||||||
13799 | SmallVector<Expr *, 8> Vars; | ||||||||
13800 | SmallVector<Expr *, 8> PrivateCopies; | ||||||||
13801 | for (Expr *RefExpr : VarList) { | ||||||||
13802 | 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.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 13802, __PRETTY_FUNCTION__)); | ||||||||
13803 | SourceLocation ELoc; | ||||||||
13804 | SourceRange ERange; | ||||||||
13805 | Expr *SimpleRefExpr = RefExpr; | ||||||||
13806 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||||||
13807 | if (Res.second) { | ||||||||
13808 | // It will be analyzed later. | ||||||||
13809 | Vars.push_back(RefExpr); | ||||||||
13810 | PrivateCopies.push_back(nullptr); | ||||||||
13811 | } | ||||||||
13812 | ValueDecl *D = Res.first; | ||||||||
13813 | if (!D) | ||||||||
13814 | continue; | ||||||||
13815 | |||||||||
13816 | QualType Type = D->getType(); | ||||||||
13817 | auto *VD = dyn_cast<VarDecl>(D); | ||||||||
13818 | |||||||||
13819 | // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] | ||||||||
13820 | // A variable that appears in a private clause must not have an incomplete | ||||||||
13821 | // type or a reference type. | ||||||||
13822 | if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) | ||||||||
13823 | continue; | ||||||||
13824 | Type = Type.getNonReferenceType(); | ||||||||
13825 | |||||||||
13826 | // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] | ||||||||
13827 | // A variable that is privatized must not have a const-qualified type | ||||||||
13828 | // unless it is of class type with a mutable member. This restriction does | ||||||||
13829 | // not apply to the firstprivate clause. | ||||||||
13830 | // | ||||||||
13831 | // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] | ||||||||
13832 | // A variable that appears in a private clause must not have a | ||||||||
13833 | // const-qualified type unless it is of class type with a mutable member. | ||||||||
13834 | if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) | ||||||||
13835 | continue; | ||||||||
13836 | |||||||||
13837 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||||
13838 | // in a Construct] | ||||||||
13839 | // Variables with the predetermined data-sharing attributes may not be | ||||||||
13840 | // listed in data-sharing attributes clauses, except for the cases | ||||||||
13841 | // listed below. For these exceptions only, listing a predetermined | ||||||||
13842 | // variable in a data-sharing attribute clause is allowed and overrides | ||||||||
13843 | // the variable's predetermined data-sharing attributes. | ||||||||
13844 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); | ||||||||
13845 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { | ||||||||
13846 | Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) | ||||||||
13847 | << getOpenMPClauseName(OMPC_private); | ||||||||
13848 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||||
13849 | continue; | ||||||||
13850 | } | ||||||||
13851 | |||||||||
13852 | OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); | ||||||||
13853 | // Variably modified types are not supported for tasks. | ||||||||
13854 | if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && | ||||||||
13855 | isOpenMPTaskingDirective(CurrDir)) { | ||||||||
13856 | Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) | ||||||||
13857 | << getOpenMPClauseName(OMPC_private) << Type | ||||||||
13858 | << getOpenMPDirectiveName(CurrDir); | ||||||||
13859 | bool IsDecl = | ||||||||
13860 | !VD || | ||||||||
13861 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||||||
13862 | Diag(D->getLocation(), | ||||||||
13863 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||||
13864 | << D; | ||||||||
13865 | continue; | ||||||||
13866 | } | ||||||||
13867 | |||||||||
13868 | // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] | ||||||||
13869 | // A list item cannot appear in both a map clause and a data-sharing | ||||||||
13870 | // attribute clause on the same construct | ||||||||
13871 | // | ||||||||
13872 | // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] | ||||||||
13873 | // A list item cannot appear in both a map clause and a data-sharing | ||||||||
13874 | // attribute clause on the same construct unless the construct is a | ||||||||
13875 | // combined construct. | ||||||||
13876 | if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || | ||||||||
13877 | CurrDir == OMPD_target) { | ||||||||
13878 | OpenMPClauseKind ConflictKind; | ||||||||
13879 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->checkMappableExprComponentListsForDecl( | ||||||||
13880 | VD, /*CurrentRegionOnly=*/true, | ||||||||
13881 | [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, | ||||||||
13882 | OpenMPClauseKind WhereFoundClauseKind) -> bool { | ||||||||
13883 | ConflictKind = WhereFoundClauseKind; | ||||||||
13884 | return true; | ||||||||
13885 | })) { | ||||||||
13886 | Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) | ||||||||
13887 | << getOpenMPClauseName(OMPC_private) | ||||||||
13888 | << getOpenMPClauseName(ConflictKind) | ||||||||
13889 | << getOpenMPDirectiveName(CurrDir); | ||||||||
13890 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||||
13891 | continue; | ||||||||
13892 | } | ||||||||
13893 | } | ||||||||
13894 | |||||||||
13895 | // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] | ||||||||
13896 | // A variable of class type (or array thereof) that appears in a private | ||||||||
13897 | // clause requires an accessible, unambiguous default constructor for the | ||||||||
13898 | // class type. | ||||||||
13899 | // Generate helper private variable and initialize it with the default | ||||||||
13900 | // value. The address of the original variable is replaced by the address of | ||||||||
13901 | // the new private variable in CodeGen. This new variable is not added to | ||||||||
13902 | // IdResolver, so the code in the OpenMP region uses original variable for | ||||||||
13903 | // proper diagnostics. | ||||||||
13904 | Type = Type.getUnqualifiedType(); | ||||||||
13905 | VarDecl *VDPrivate = | ||||||||
13906 | buildVarDecl(*this, ELoc, Type, D->getName(), | ||||||||
13907 | D->hasAttrs() ? &D->getAttrs() : nullptr, | ||||||||
13908 | VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); | ||||||||
13909 | ActOnUninitializedDecl(VDPrivate); | ||||||||
13910 | if (VDPrivate->isInvalidDecl()) | ||||||||
13911 | continue; | ||||||||
13912 | DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( | ||||||||
13913 | *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); | ||||||||
13914 | |||||||||
13915 | DeclRefExpr *Ref = nullptr; | ||||||||
13916 | if (!VD && !CurContext->isDependentContext()) | ||||||||
13917 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); | ||||||||
13918 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); | ||||||||
13919 | Vars.push_back((VD || CurContext->isDependentContext()) | ||||||||
13920 | ? RefExpr->IgnoreParens() | ||||||||
13921 | : Ref); | ||||||||
13922 | PrivateCopies.push_back(VDPrivateRefExpr); | ||||||||
13923 | } | ||||||||
13924 | |||||||||
13925 | if (Vars.empty()) | ||||||||
13926 | return nullptr; | ||||||||
13927 | |||||||||
13928 | return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, | ||||||||
13929 | PrivateCopies); | ||||||||
13930 | } | ||||||||
13931 | |||||||||
13932 | namespace { | ||||||||
13933 | class DiagsUninitializedSeveretyRAII { | ||||||||
13934 | private: | ||||||||
13935 | DiagnosticsEngine &Diags; | ||||||||
13936 | SourceLocation SavedLoc; | ||||||||
13937 | bool IsIgnored = false; | ||||||||
13938 | |||||||||
13939 | public: | ||||||||
13940 | DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, | ||||||||
13941 | bool IsIgnored) | ||||||||
13942 | : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { | ||||||||
13943 | if (!IsIgnored) { | ||||||||
13944 | Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, | ||||||||
13945 | /*Map*/ diag::Severity::Ignored, Loc); | ||||||||
13946 | } | ||||||||
13947 | } | ||||||||
13948 | ~DiagsUninitializedSeveretyRAII() { | ||||||||
13949 | if (!IsIgnored) | ||||||||
13950 | Diags.popMappings(SavedLoc); | ||||||||
13951 | } | ||||||||
13952 | }; | ||||||||
13953 | } | ||||||||
13954 | |||||||||
13955 | OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, | ||||||||
13956 | SourceLocation StartLoc, | ||||||||
13957 | SourceLocation LParenLoc, | ||||||||
13958 | SourceLocation EndLoc) { | ||||||||
13959 | SmallVector<Expr *, 8> Vars; | ||||||||
13960 | SmallVector<Expr *, 8> PrivateCopies; | ||||||||
13961 | SmallVector<Expr *, 8> Inits; | ||||||||
13962 | SmallVector<Decl *, 4> ExprCaptures; | ||||||||
13963 | bool IsImplicitClause = | ||||||||
13964 | StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); | ||||||||
13965 | SourceLocation ImplicitClauseLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(); | ||||||||
13966 | |||||||||
13967 | for (Expr *RefExpr : VarList) { | ||||||||
13968 | 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.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 13968, __PRETTY_FUNCTION__)); | ||||||||
13969 | SourceLocation ELoc; | ||||||||
13970 | SourceRange ERange; | ||||||||
13971 | Expr *SimpleRefExpr = RefExpr; | ||||||||
13972 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||||||
13973 | if (Res.second) { | ||||||||
13974 | // It will be analyzed later. | ||||||||
13975 | Vars.push_back(RefExpr); | ||||||||
13976 | PrivateCopies.push_back(nullptr); | ||||||||
13977 | Inits.push_back(nullptr); | ||||||||
13978 | } | ||||||||
13979 | ValueDecl *D = Res.first; | ||||||||
13980 | if (!D) | ||||||||
13981 | continue; | ||||||||
13982 | |||||||||
13983 | ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; | ||||||||
13984 | QualType Type = D->getType(); | ||||||||
13985 | auto *VD = dyn_cast<VarDecl>(D); | ||||||||
13986 | |||||||||
13987 | // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] | ||||||||
13988 | // A variable that appears in a private clause must not have an incomplete | ||||||||
13989 | // type or a reference type. | ||||||||
13990 | if (RequireCompleteType(ELoc, Type, | ||||||||
13991 | diag::err_omp_firstprivate_incomplete_type)) | ||||||||
13992 | continue; | ||||||||
13993 | Type = Type.getNonReferenceType(); | ||||||||
13994 | |||||||||
13995 | // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] | ||||||||
13996 | // A variable of class type (or array thereof) that appears in a private | ||||||||
13997 | // clause requires an accessible, unambiguous copy constructor for the | ||||||||
13998 | // class type. | ||||||||
13999 | QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); | ||||||||
14000 | |||||||||
14001 | // If an implicit firstprivate variable found it was checked already. | ||||||||
14002 | DSAStackTy::DSAVarData TopDVar; | ||||||||
14003 | if (!IsImplicitClause) { | ||||||||
14004 | DSAStackTy::DSAVarData DVar = | ||||||||
14005 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); | ||||||||
14006 | TopDVar = DVar; | ||||||||
14007 | OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); | ||||||||
14008 | bool IsConstant = ElemType.isConstant(Context); | ||||||||
14009 | // OpenMP [2.4.13, Data-sharing Attribute Clauses] | ||||||||
14010 | // A list item that specifies a given variable may not appear in more | ||||||||
14011 | // than one clause on the same directive, except that a variable may be | ||||||||
14012 | // specified in both firstprivate and lastprivate clauses. | ||||||||
14013 | // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] | ||||||||
14014 | // A list item may appear in a firstprivate or lastprivate clause but not | ||||||||
14015 | // both. | ||||||||
14016 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && | ||||||||
14017 | (isOpenMPDistributeDirective(CurrDir) || | ||||||||
14018 | DVar.CKind != OMPC_lastprivate) && | ||||||||
14019 | DVar.RefExpr) { | ||||||||
14020 | Diag(ELoc, diag::err_omp_wrong_dsa) | ||||||||
14021 | << getOpenMPClauseName(DVar.CKind) | ||||||||
14022 | << getOpenMPClauseName(OMPC_firstprivate); | ||||||||
14023 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||||
14024 | continue; | ||||||||
14025 | } | ||||||||
14026 | |||||||||
14027 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||||
14028 | // in a Construct] | ||||||||
14029 | // Variables with the predetermined data-sharing attributes may not be | ||||||||
14030 | // listed in data-sharing attributes clauses, except for the cases | ||||||||
14031 | // listed below. For these exceptions only, listing a predetermined | ||||||||
14032 | // variable in a data-sharing attribute clause is allowed and overrides | ||||||||
14033 | // the variable's predetermined data-sharing attributes. | ||||||||
14034 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||||
14035 | // in a Construct, C/C++, p.2] | ||||||||
14036 | // Variables with const-qualified type having no mutable member may be | ||||||||
14037 | // listed in a firstprivate clause, even if they are static data members. | ||||||||
14038 | if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && | ||||||||
14039 | DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { | ||||||||
14040 | Diag(ELoc, diag::err_omp_wrong_dsa) | ||||||||
14041 | << getOpenMPClauseName(DVar.CKind) | ||||||||
14042 | << getOpenMPClauseName(OMPC_firstprivate); | ||||||||
14043 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||||
14044 | continue; | ||||||||
14045 | } | ||||||||
14046 | |||||||||
14047 | // OpenMP [2.9.3.4, Restrictions, p.2] | ||||||||
14048 | // A list item that is private within a parallel region must not appear | ||||||||
14049 | // in a firstprivate clause on a worksharing construct if any of the | ||||||||
14050 | // worksharing regions arising from the worksharing construct ever bind | ||||||||
14051 | // to any of the parallel regions arising from the parallel construct. | ||||||||
14052 | // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] | ||||||||
14053 | // A list item that is private within a teams region must not appear in a | ||||||||
14054 | // firstprivate clause on a distribute construct if any of the distribute | ||||||||
14055 | // regions arising from the distribute construct ever bind to any of the | ||||||||
14056 | // teams regions arising from the teams construct. | ||||||||
14057 | // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] | ||||||||
14058 | // A list item that appears in a reduction clause of a teams construct | ||||||||
14059 | // must not appear in a firstprivate clause on a distribute construct if | ||||||||
14060 | // any of the distribute regions arising from the distribute construct | ||||||||
14061 | // ever bind to any of the teams regions arising from the teams construct. | ||||||||
14062 | if ((isOpenMPWorksharingDirective(CurrDir) || | ||||||||
14063 | isOpenMPDistributeDirective(CurrDir)) && | ||||||||
14064 | !isOpenMPParallelDirective(CurrDir) && | ||||||||
14065 | !isOpenMPTeamsDirective(CurrDir)) { | ||||||||
14066 | DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getImplicitDSA(D, true); | ||||||||
14067 | if (DVar.CKind != OMPC_shared && | ||||||||
14068 | (isOpenMPParallelDirective(DVar.DKind) || | ||||||||
14069 | isOpenMPTeamsDirective(DVar.DKind) || | ||||||||
14070 | DVar.DKind == OMPD_unknown)) { | ||||||||
14071 | Diag(ELoc, diag::err_omp_required_access) | ||||||||
14072 | << getOpenMPClauseName(OMPC_firstprivate) | ||||||||
14073 | << getOpenMPClauseName(OMPC_shared); | ||||||||
14074 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||||
14075 | continue; | ||||||||
14076 | } | ||||||||
14077 | } | ||||||||
14078 | // OpenMP [2.9.3.4, Restrictions, p.3] | ||||||||
14079 | // A list item that appears in a reduction clause of a parallel construct | ||||||||
14080 | // must not appear in a firstprivate clause on a worksharing or task | ||||||||
14081 | // construct if any of the worksharing or task regions arising from the | ||||||||
14082 | // worksharing or task construct ever bind to any of the parallel regions | ||||||||
14083 | // arising from the parallel construct. | ||||||||
14084 | // OpenMP [2.9.3.4, Restrictions, p.4] | ||||||||
14085 | // A list item that appears in a reduction clause in worksharing | ||||||||
14086 | // construct must not appear in a firstprivate clause in a task construct | ||||||||
14087 | // encountered during execution of any of the worksharing regions arising | ||||||||
14088 | // from the worksharing construct. | ||||||||
14089 | if (isOpenMPTaskingDirective(CurrDir)) { | ||||||||
14090 | DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasInnermostDSA( | ||||||||
14091 | D, | ||||||||
14092 | [](OpenMPClauseKind C, bool AppliedToPointee) { | ||||||||
14093 | return C == OMPC_reduction && !AppliedToPointee; | ||||||||
14094 | }, | ||||||||
14095 | [](OpenMPDirectiveKind K) { | ||||||||
14096 | return isOpenMPParallelDirective(K) || | ||||||||
14097 | isOpenMPWorksharingDirective(K) || | ||||||||
14098 | isOpenMPTeamsDirective(K); | ||||||||
14099 | }, | ||||||||
14100 | /*FromParent=*/true); | ||||||||
14101 | if (DVar.CKind == OMPC_reduction && | ||||||||
14102 | (isOpenMPParallelDirective(DVar.DKind) || | ||||||||
14103 | isOpenMPWorksharingDirective(DVar.DKind) || | ||||||||
14104 | isOpenMPTeamsDirective(DVar.DKind))) { | ||||||||
14105 | Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) | ||||||||
14106 | << getOpenMPDirectiveName(DVar.DKind); | ||||||||
14107 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||||
14108 | continue; | ||||||||
14109 | } | ||||||||
14110 | } | ||||||||
14111 | |||||||||
14112 | // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] | ||||||||
14113 | // A list item cannot appear in both a map clause and a data-sharing | ||||||||
14114 | // attribute clause on the same construct | ||||||||
14115 | // | ||||||||
14116 | // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] | ||||||||
14117 | // A list item cannot appear in both a map clause and a data-sharing | ||||||||
14118 | // attribute clause on the same construct unless the construct is a | ||||||||
14119 | // combined construct. | ||||||||
14120 | if ((LangOpts.OpenMP <= 45 && | ||||||||
14121 | isOpenMPTargetExecutionDirective(CurrDir)) || | ||||||||
14122 | CurrDir == OMPD_target) { | ||||||||
14123 | OpenMPClauseKind ConflictKind; | ||||||||
14124 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->checkMappableExprComponentListsForDecl( | ||||||||
14125 | VD, /*CurrentRegionOnly=*/true, | ||||||||
14126 | [&ConflictKind]( | ||||||||
14127 | OMPClauseMappableExprCommon::MappableExprComponentListRef, | ||||||||
14128 | OpenMPClauseKind WhereFoundClauseKind) { | ||||||||
14129 | ConflictKind = WhereFoundClauseKind; | ||||||||
14130 | return true; | ||||||||
14131 | })) { | ||||||||
14132 | Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) | ||||||||
14133 | << getOpenMPClauseName(OMPC_firstprivate) | ||||||||
14134 | << getOpenMPClauseName(ConflictKind) | ||||||||
14135 | << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()); | ||||||||
14136 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||||
14137 | continue; | ||||||||
14138 | } | ||||||||
14139 | } | ||||||||
14140 | } | ||||||||
14141 | |||||||||
14142 | // Variably modified types are not supported for tasks. | ||||||||
14143 | if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && | ||||||||
14144 | isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective())) { | ||||||||
14145 | Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) | ||||||||
14146 | << getOpenMPClauseName(OMPC_firstprivate) << Type | ||||||||
14147 | << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()); | ||||||||
14148 | bool IsDecl = | ||||||||
14149 | !VD || | ||||||||
14150 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||||||
14151 | Diag(D->getLocation(), | ||||||||
14152 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||||
14153 | << D; | ||||||||
14154 | continue; | ||||||||
14155 | } | ||||||||
14156 | |||||||||
14157 | Type = Type.getUnqualifiedType(); | ||||||||
14158 | VarDecl *VDPrivate = | ||||||||
14159 | buildVarDecl(*this, ELoc, Type, D->getName(), | ||||||||
14160 | D->hasAttrs() ? &D->getAttrs() : nullptr, | ||||||||
14161 | VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); | ||||||||
14162 | // Generate helper private variable and initialize it with the value of the | ||||||||
14163 | // original variable. The address of the original variable is replaced by | ||||||||
14164 | // the address of the new private variable in the CodeGen. This new variable | ||||||||
14165 | // is not added to IdResolver, so the code in the OpenMP region uses | ||||||||
14166 | // original variable for proper diagnostics and variable capturing. | ||||||||
14167 | Expr *VDInitRefExpr = nullptr; | ||||||||
14168 | // For arrays generate initializer for single element and replace it by the | ||||||||
14169 | // original array element in CodeGen. | ||||||||
14170 | if (Type->isArrayType()) { | ||||||||
14171 | VarDecl *VDInit = | ||||||||
14172 | buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); | ||||||||
14173 | VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); | ||||||||
14174 | Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); | ||||||||
14175 | ElemType = ElemType.getUnqualifiedType(); | ||||||||
14176 | VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, | ||||||||
14177 | ".firstprivate.temp"); | ||||||||
14178 | InitializedEntity Entity = | ||||||||
14179 | InitializedEntity::InitializeVariable(VDInitTemp); | ||||||||
14180 | InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); | ||||||||
14181 | |||||||||
14182 | InitializationSequence InitSeq(*this, Entity, Kind, Init); | ||||||||
14183 | ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); | ||||||||
14184 | if (Result.isInvalid()) | ||||||||
14185 | VDPrivate->setInvalidDecl(); | ||||||||
14186 | else | ||||||||
14187 | VDPrivate->setInit(Result.getAs<Expr>()); | ||||||||
14188 | // Remove temp variable declaration. | ||||||||
14189 | Context.Deallocate(VDInitTemp); | ||||||||
14190 | } else { | ||||||||
14191 | VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, | ||||||||
14192 | ".firstprivate.temp"); | ||||||||
14193 | VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), | ||||||||
14194 | RefExpr->getExprLoc()); | ||||||||
14195 | AddInitializerToDecl(VDPrivate, | ||||||||
14196 | DefaultLvalueConversion(VDInitRefExpr).get(), | ||||||||
14197 | /*DirectInit=*/false); | ||||||||
14198 | } | ||||||||
14199 | if (VDPrivate->isInvalidDecl()) { | ||||||||
14200 | if (IsImplicitClause) { | ||||||||
14201 | Diag(RefExpr->getExprLoc(), | ||||||||
14202 | diag::note_omp_task_predetermined_firstprivate_here); | ||||||||
14203 | } | ||||||||
14204 | continue; | ||||||||
14205 | } | ||||||||
14206 | CurContext->addDecl(VDPrivate); | ||||||||
14207 | DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( | ||||||||
14208 | *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), | ||||||||
14209 | RefExpr->getExprLoc()); | ||||||||
14210 | DeclRefExpr *Ref = nullptr; | ||||||||
14211 | if (!VD && !CurContext->isDependentContext()) { | ||||||||
14212 | if (TopDVar.CKind == OMPC_lastprivate) { | ||||||||
14213 | Ref = TopDVar.PrivateCopy; | ||||||||
14214 | } else { | ||||||||
14215 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); | ||||||||
14216 | if (!isOpenMPCapturedDecl(D)) | ||||||||
14217 | ExprCaptures.push_back(Ref->getDecl()); | ||||||||
14218 | } | ||||||||
14219 | } | ||||||||
14220 | if (!IsImplicitClause) | ||||||||
14221 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); | ||||||||
14222 | Vars.push_back((VD || CurContext->isDependentContext()) | ||||||||
14223 | ? RefExpr->IgnoreParens() | ||||||||
14224 | : Ref); | ||||||||
14225 | PrivateCopies.push_back(VDPrivateRefExpr); | ||||||||
14226 | Inits.push_back(VDInitRefExpr); | ||||||||
14227 | } | ||||||||
14228 | |||||||||
14229 | if (Vars.empty()) | ||||||||
14230 | return nullptr; | ||||||||
14231 | |||||||||
14232 | return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, | ||||||||
14233 | Vars, PrivateCopies, Inits, | ||||||||
14234 | buildPreInits(Context, ExprCaptures)); | ||||||||
14235 | } | ||||||||
14236 | |||||||||
14237 | OMPClause *Sema::ActOnOpenMPLastprivateClause( | ||||||||
14238 | ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, | ||||||||
14239 | SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, | ||||||||
14240 | SourceLocation LParenLoc, SourceLocation EndLoc) { | ||||||||
14241 | if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { | ||||||||
14242 | assert(ColonLoc.isValid() && "Colon location must be valid.")((ColonLoc.isValid() && "Colon location must be valid." ) ? static_cast<void> (0) : __assert_fail ("ColonLoc.isValid() && \"Colon location must be valid.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 14242, __PRETTY_FUNCTION__)); | ||||||||
14243 | Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) | ||||||||
14244 | << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, | ||||||||
14245 | /*Last=*/OMPC_LASTPRIVATE_unknown) | ||||||||
14246 | << getOpenMPClauseName(OMPC_lastprivate); | ||||||||
14247 | return nullptr; | ||||||||
14248 | } | ||||||||
14249 | |||||||||
14250 | SmallVector<Expr *, 8> Vars; | ||||||||
14251 | SmallVector<Expr *, 8> SrcExprs; | ||||||||
14252 | SmallVector<Expr *, 8> DstExprs; | ||||||||
14253 | SmallVector<Expr *, 8> AssignmentOps; | ||||||||
14254 | SmallVector<Decl *, 4> ExprCaptures; | ||||||||
14255 | SmallVector<Expr *, 4> ExprPostUpdates; | ||||||||
14256 | for (Expr *RefExpr : VarList) { | ||||||||
14257 | 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.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 14257, __PRETTY_FUNCTION__)); | ||||||||
14258 | SourceLocation ELoc; | ||||||||
14259 | SourceRange ERange; | ||||||||
14260 | Expr *SimpleRefExpr = RefExpr; | ||||||||
14261 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||||||
14262 | if (Res.second) { | ||||||||
14263 | // It will be analyzed later. | ||||||||
14264 | Vars.push_back(RefExpr); | ||||||||
14265 | SrcExprs.push_back(nullptr); | ||||||||
14266 | DstExprs.push_back(nullptr); | ||||||||
14267 | AssignmentOps.push_back(nullptr); | ||||||||
14268 | } | ||||||||
14269 | ValueDecl *D = Res.first; | ||||||||
14270 | if (!D) | ||||||||
14271 | continue; | ||||||||
14272 | |||||||||
14273 | QualType Type = D->getType(); | ||||||||
14274 | auto *VD = dyn_cast<VarDecl>(D); | ||||||||
14275 | |||||||||
14276 | // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] | ||||||||
14277 | // A variable that appears in a lastprivate clause must not have an | ||||||||
14278 | // incomplete type or a reference type. | ||||||||
14279 | if (RequireCompleteType(ELoc, Type, | ||||||||
14280 | diag::err_omp_lastprivate_incomplete_type)) | ||||||||
14281 | continue; | ||||||||
14282 | Type = Type.getNonReferenceType(); | ||||||||
14283 | |||||||||
14284 | // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] | ||||||||
14285 | // A variable that is privatized must not have a const-qualified type | ||||||||
14286 | // unless it is of class type with a mutable member. This restriction does | ||||||||
14287 | // not apply to the firstprivate clause. | ||||||||
14288 | // | ||||||||
14289 | // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] | ||||||||
14290 | // A variable that appears in a lastprivate clause must not have a | ||||||||
14291 | // const-qualified type unless it is of class type with a mutable member. | ||||||||
14292 | if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) | ||||||||
14293 | continue; | ||||||||
14294 | |||||||||
14295 | // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] | ||||||||
14296 | // A list item that appears in a lastprivate clause with the conditional | ||||||||
14297 | // modifier must be a scalar variable. | ||||||||
14298 | if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { | ||||||||
14299 | Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); | ||||||||
14300 | bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == | ||||||||
14301 | VarDecl::DeclarationOnly; | ||||||||
14302 | Diag(D->getLocation(), | ||||||||
14303 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||||
14304 | << D; | ||||||||
14305 | continue; | ||||||||
14306 | } | ||||||||
14307 | |||||||||
14308 | OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); | ||||||||
14309 | // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||||
14310 | // in a Construct] | ||||||||
14311 | // Variables with the predetermined data-sharing attributes may not be | ||||||||
14312 | // listed in data-sharing attributes clauses, except for the cases | ||||||||
14313 | // listed below. | ||||||||
14314 | // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] | ||||||||
14315 | // A list item may appear in a firstprivate or lastprivate clause but not | ||||||||
14316 | // both. | ||||||||
14317 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); | ||||||||
14318 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && | ||||||||
14319 | (isOpenMPDistributeDirective(CurrDir) || | ||||||||
14320 | DVar.CKind != OMPC_firstprivate) && | ||||||||
14321 | (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { | ||||||||
14322 | Diag(ELoc, diag::err_omp_wrong_dsa) | ||||||||
14323 | << getOpenMPClauseName(DVar.CKind) | ||||||||
14324 | << getOpenMPClauseName(OMPC_lastprivate); | ||||||||
14325 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||||
14326 | continue; | ||||||||
14327 | } | ||||||||
14328 | |||||||||
14329 | // OpenMP [2.14.3.5, Restrictions, p.2] | ||||||||
14330 | // A list item that is private within a parallel region, or that appears in | ||||||||
14331 | // the reduction clause of a parallel construct, must not appear in a | ||||||||
14332 | // lastprivate clause on a worksharing construct if any of the corresponding | ||||||||
14333 | // worksharing regions ever binds to any of the corresponding parallel | ||||||||
14334 | // regions. | ||||||||
14335 | DSAStackTy::DSAVarData TopDVar = DVar; | ||||||||
14336 | if (isOpenMPWorksharingDirective(CurrDir) && | ||||||||
14337 | !isOpenMPParallelDirective(CurrDir) && | ||||||||
14338 | !isOpenMPTeamsDirective(CurrDir)) { | ||||||||
14339 | DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getImplicitDSA(D, true); | ||||||||
14340 | if (DVar.CKind != OMPC_shared) { | ||||||||
14341 | Diag(ELoc, diag::err_omp_required_access) | ||||||||
14342 | << getOpenMPClauseName(OMPC_lastprivate) | ||||||||
14343 | << getOpenMPClauseName(OMPC_shared); | ||||||||
14344 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||||
14345 | continue; | ||||||||
14346 | } | ||||||||
14347 | } | ||||||||
14348 | |||||||||
14349 | // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] | ||||||||
14350 | // A variable of class type (or array thereof) that appears in a | ||||||||
14351 | // lastprivate clause requires an accessible, unambiguous default | ||||||||
14352 | // constructor for the class type, unless the list item is also specified | ||||||||
14353 | // in a firstprivate clause. | ||||||||
14354 | // A variable of class type (or array thereof) that appears in a | ||||||||
14355 | // lastprivate clause requires an accessible, unambiguous copy assignment | ||||||||
14356 | // operator for the class type. | ||||||||
14357 | Type = Context.getBaseElementType(Type).getNonReferenceType(); | ||||||||
14358 | VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), | ||||||||
14359 | Type.getUnqualifiedType(), ".lastprivate.src", | ||||||||
14360 | D->hasAttrs() ? &D->getAttrs() : nullptr); | ||||||||
14361 | DeclRefExpr *PseudoSrcExpr = | ||||||||
14362 | buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); | ||||||||
14363 | VarDecl *DstVD = | ||||||||
14364 | buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", | ||||||||
14365 | D->hasAttrs() ? &D->getAttrs() : nullptr); | ||||||||
14366 | DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); | ||||||||
14367 | // For arrays generate assignment operation for single element and replace | ||||||||
14368 | // it by the original array element in CodeGen. | ||||||||
14369 | ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, | ||||||||
14370 | PseudoDstExpr, PseudoSrcExpr); | ||||||||
14371 | if (AssignmentOp.isInvalid()) | ||||||||
14372 | continue; | ||||||||
14373 | AssignmentOp = | ||||||||
14374 | ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); | ||||||||
14375 | if (AssignmentOp.isInvalid()) | ||||||||
14376 | continue; | ||||||||
14377 | |||||||||
14378 | DeclRefExpr *Ref = nullptr; | ||||||||
14379 | if (!VD && !CurContext->isDependentContext()) { | ||||||||
14380 | if (TopDVar.CKind == OMPC_firstprivate) { | ||||||||
14381 | Ref = TopDVar.PrivateCopy; | ||||||||
14382 | } else { | ||||||||
14383 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); | ||||||||
14384 | if (!isOpenMPCapturedDecl(D)) | ||||||||
14385 | ExprCaptures.push_back(Ref->getDecl()); | ||||||||
14386 | } | ||||||||
14387 | if (TopDVar.CKind == OMPC_firstprivate || | ||||||||
14388 | (!isOpenMPCapturedDecl(D) && | ||||||||
14389 | Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { | ||||||||
14390 | ExprResult RefRes = DefaultLvalueConversion(Ref); | ||||||||
14391 | if (!RefRes.isUsable()) | ||||||||
14392 | continue; | ||||||||
14393 | ExprResult PostUpdateRes = | ||||||||
14394 | BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, | ||||||||
14395 | RefRes.get()); | ||||||||
14396 | if (!PostUpdateRes.isUsable()) | ||||||||
14397 | continue; | ||||||||
14398 | ExprPostUpdates.push_back( | ||||||||
14399 | IgnoredValueConversions(PostUpdateRes.get()).get()); | ||||||||
14400 | } | ||||||||
14401 | } | ||||||||
14402 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); | ||||||||
14403 | Vars.push_back((VD || CurContext->isDependentContext()) | ||||||||
14404 | ? RefExpr->IgnoreParens() | ||||||||
14405 | : Ref); | ||||||||
14406 | SrcExprs.push_back(PseudoSrcExpr); | ||||||||
14407 | DstExprs.push_back(PseudoDstExpr); | ||||||||
14408 | AssignmentOps.push_back(AssignmentOp.get()); | ||||||||
14409 | } | ||||||||
14410 | |||||||||
14411 | if (Vars.empty()) | ||||||||
14412 | return nullptr; | ||||||||
14413 | |||||||||
14414 | return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, | ||||||||
14415 | Vars, SrcExprs, DstExprs, AssignmentOps, | ||||||||
14416 | LPKind, LPKindLoc, ColonLoc, | ||||||||
14417 | buildPreInits(Context, ExprCaptures), | ||||||||
14418 | buildPostUpdate(*this, ExprPostUpdates)); | ||||||||
14419 | } | ||||||||
14420 | |||||||||
14421 | OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, | ||||||||
14422 | SourceLocation StartLoc, | ||||||||
14423 | SourceLocation LParenLoc, | ||||||||
14424 | SourceLocation EndLoc) { | ||||||||
14425 | SmallVector<Expr *, 8> Vars; | ||||||||
14426 | for (Expr *RefExpr : VarList) { | ||||||||
14427 | 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.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 14427, __PRETTY_FUNCTION__)); | ||||||||
14428 | SourceLocation ELoc; | ||||||||
14429 | SourceRange ERange; | ||||||||
14430 | Expr *SimpleRefExpr = RefExpr; | ||||||||
14431 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||||||
14432 | if (Res.second) { | ||||||||
14433 | // It will be analyzed later. | ||||||||
14434 | Vars.push_back(RefExpr); | ||||||||
14435 | } | ||||||||
14436 | ValueDecl *D = Res.first; | ||||||||
14437 | if (!D) | ||||||||
14438 | continue; | ||||||||
14439 | |||||||||
14440 | auto *VD = dyn_cast<VarDecl>(D); | ||||||||
14441 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||||
14442 | // in a Construct] | ||||||||
14443 | // Variables with the predetermined data-sharing attributes may not be | ||||||||
14444 | // listed in data-sharing attributes clauses, except for the cases | ||||||||
14445 | // listed below. For these exceptions only, listing a predetermined | ||||||||
14446 | // variable in a data-sharing attribute clause is allowed and overrides | ||||||||
14447 | // the variable's predetermined data-sharing attributes. | ||||||||
14448 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); | ||||||||
14449 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && | ||||||||
14450 | DVar.RefExpr) { | ||||||||
14451 | Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) | ||||||||
14452 | << getOpenMPClauseName(OMPC_shared); | ||||||||
14453 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||||
14454 | continue; | ||||||||
14455 | } | ||||||||
14456 | |||||||||
14457 | DeclRefExpr *Ref = nullptr; | ||||||||
14458 | if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) | ||||||||
14459 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); | ||||||||
14460 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); | ||||||||
14461 | Vars.push_back((VD || !Ref || CurContext->isDependentContext()) | ||||||||
14462 | ? RefExpr->IgnoreParens() | ||||||||
14463 | : Ref); | ||||||||
14464 | } | ||||||||
14465 | |||||||||
14466 | if (Vars.empty()) | ||||||||
14467 | return nullptr; | ||||||||
14468 | |||||||||
14469 | return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); | ||||||||
14470 | } | ||||||||
14471 | |||||||||
14472 | namespace { | ||||||||
14473 | class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { | ||||||||
14474 | DSAStackTy *Stack; | ||||||||
14475 | |||||||||
14476 | public: | ||||||||
14477 | bool VisitDeclRefExpr(DeclRefExpr *E) { | ||||||||
14478 | if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { | ||||||||
14479 | DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); | ||||||||
14480 | if (DVar.CKind == OMPC_shared && !DVar.RefExpr) | ||||||||
14481 | return false; | ||||||||
14482 | if (DVar.CKind != OMPC_unknown) | ||||||||
14483 | return true; | ||||||||
14484 | DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( | ||||||||
14485 | VD, | ||||||||
14486 | [](OpenMPClauseKind C, bool AppliedToPointee) { | ||||||||
14487 | return isOpenMPPrivate(C) && !AppliedToPointee; | ||||||||
14488 | }, | ||||||||
14489 | [](OpenMPDirectiveKind) { return true; }, | ||||||||
14490 | /*FromParent=*/true); | ||||||||
14491 | return DVarPrivate.CKind != OMPC_unknown; | ||||||||
14492 | } | ||||||||
14493 | return false; | ||||||||
14494 | } | ||||||||
14495 | bool VisitStmt(Stmt *S) { | ||||||||
14496 | for (Stmt *Child : S->children()) { | ||||||||
14497 | if (Child && Visit(Child)) | ||||||||
14498 | return true; | ||||||||
14499 | } | ||||||||
14500 | return false; | ||||||||
14501 | } | ||||||||
14502 | explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} | ||||||||
14503 | }; | ||||||||
14504 | } // namespace | ||||||||
14505 | |||||||||
14506 | namespace { | ||||||||
14507 | // Transform MemberExpression for specified FieldDecl of current class to | ||||||||
14508 | // DeclRefExpr to specified OMPCapturedExprDecl. | ||||||||
14509 | class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { | ||||||||
14510 | typedef TreeTransform<TransformExprToCaptures> BaseTransform; | ||||||||
14511 | ValueDecl *Field = nullptr; | ||||||||
14512 | DeclRefExpr *CapturedExpr = nullptr; | ||||||||
14513 | |||||||||
14514 | public: | ||||||||
14515 | TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) | ||||||||
14516 | : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} | ||||||||
14517 | |||||||||
14518 | ExprResult TransformMemberExpr(MemberExpr *E) { | ||||||||
14519 | if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && | ||||||||
| |||||||||
14520 | E->getMemberDecl() == Field) { | ||||||||
14521 | CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); | ||||||||
14522 | return CapturedExpr; | ||||||||
14523 | } | ||||||||
14524 | return BaseTransform::TransformMemberExpr(E); | ||||||||
14525 | } | ||||||||
14526 | DeclRefExpr *getCapturedExpr() { return CapturedExpr; } | ||||||||
14527 | }; | ||||||||
14528 | } // namespace | ||||||||
14529 | |||||||||
14530 | template <typename T, typename U> | ||||||||
14531 | static T filterLookupForUDReductionAndMapper( | ||||||||
14532 | SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { | ||||||||
14533 | for (U &Set : Lookups) { | ||||||||
14534 | for (auto *D : Set) { | ||||||||
14535 | if (T Res = Gen(cast<ValueDecl>(D))) | ||||||||
14536 | return Res; | ||||||||
14537 | } | ||||||||
14538 | } | ||||||||
14539 | return T(); | ||||||||
14540 | } | ||||||||
14541 | |||||||||
14542 | static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { | ||||||||
14543 | assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case")((!LookupResult::isVisible(SemaRef, D) && "not in slow case" ) ? static_cast<void> (0) : __assert_fail ("!LookupResult::isVisible(SemaRef, D) && \"not in slow case\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 14543, __PRETTY_FUNCTION__)); | ||||||||
14544 | |||||||||
14545 | for (auto RD : D->redecls()) { | ||||||||
14546 | // Don't bother with extra checks if we already know this one isn't visible. | ||||||||
14547 | if (RD == D) | ||||||||
14548 | continue; | ||||||||
14549 | |||||||||
14550 | auto ND = cast<NamedDecl>(RD); | ||||||||
14551 | if (LookupResult::isVisible(SemaRef, ND)) | ||||||||
14552 | return ND; | ||||||||
14553 | } | ||||||||
14554 | |||||||||
14555 | return nullptr; | ||||||||
14556 | } | ||||||||
14557 | |||||||||
14558 | static void | ||||||||
14559 | argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, | ||||||||
14560 | SourceLocation Loc, QualType Ty, | ||||||||
14561 | SmallVectorImpl<UnresolvedSet<8>> &Lookups) { | ||||||||
14562 | // Find all of the associated namespaces and classes based on the | ||||||||
14563 | // arguments we have. | ||||||||
14564 | Sema::AssociatedNamespaceSet AssociatedNamespaces; | ||||||||
14565 | Sema::AssociatedClassSet AssociatedClasses; | ||||||||
14566 | OpaqueValueExpr OVE(Loc, Ty, VK_LValue); | ||||||||
14567 | SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, | ||||||||
14568 | AssociatedClasses); | ||||||||
14569 | |||||||||
14570 | // C++ [basic.lookup.argdep]p3: | ||||||||
14571 | // Let X be the lookup set produced by unqualified lookup (3.4.1) | ||||||||
14572 | // and let Y be the lookup set produced by argument dependent | ||||||||
14573 | // lookup (defined as follows). If X contains [...] then Y is | ||||||||
14574 | // empty. Otherwise Y is the set of declarations found in the | ||||||||
14575 | // namespaces associated with the argument types as described | ||||||||
14576 | // below. The set of declarations found by the lookup of the name | ||||||||
14577 | // is the union of X and Y. | ||||||||
14578 | // | ||||||||
14579 | // Here, we compute Y and add its members to the overloaded | ||||||||
14580 | // candidate set. | ||||||||
14581 | for (auto *NS : AssociatedNamespaces) { | ||||||||
14582 | // When considering an associated namespace, the lookup is the | ||||||||
14583 | // same as the lookup performed when the associated namespace is | ||||||||
14584 | // used as a qualifier (3.4.3.2) except that: | ||||||||
14585 | // | ||||||||
14586 | // -- Any using-directives in the associated namespace are | ||||||||
14587 | // ignored. | ||||||||
14588 | // | ||||||||
14589 | // -- Any namespace-scope friend functions declared in | ||||||||
14590 | // associated classes are visible within their respective | ||||||||
14591 | // namespaces even if they are not visible during an ordinary | ||||||||
14592 | // lookup (11.4). | ||||||||
14593 | DeclContext::lookup_result R = NS->lookup(Id.getName()); | ||||||||
14594 | for (auto *D : R) { | ||||||||
14595 | auto *Underlying = D; | ||||||||
14596 | if (auto *USD = dyn_cast<UsingShadowDecl>(D)) | ||||||||
14597 | Underlying = USD->getTargetDecl(); | ||||||||
14598 | |||||||||
14599 | if (!isa<OMPDeclareReductionDecl>(Underlying) && | ||||||||
14600 | !isa<OMPDeclareMapperDecl>(Underlying)) | ||||||||
14601 | continue; | ||||||||
14602 | |||||||||
14603 | if (!SemaRef.isVisible(D)) { | ||||||||
14604 | D = findAcceptableDecl(SemaRef, D); | ||||||||
14605 | if (!D) | ||||||||
14606 | continue; | ||||||||
14607 | if (auto *USD = dyn_cast<UsingShadowDecl>(D)) | ||||||||
14608 | Underlying = USD->getTargetDecl(); | ||||||||
14609 | } | ||||||||
14610 | Lookups.emplace_back(); | ||||||||
14611 | Lookups.back().addDecl(Underlying); | ||||||||
14612 | } | ||||||||
14613 | } | ||||||||
14614 | } | ||||||||
14615 | |||||||||
14616 | static ExprResult | ||||||||
14617 | buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, | ||||||||
14618 | Scope *S, CXXScopeSpec &ReductionIdScopeSpec, | ||||||||
14619 | const DeclarationNameInfo &ReductionId, QualType Ty, | ||||||||
14620 | CXXCastPath &BasePath, Expr *UnresolvedReduction) { | ||||||||
14621 | if (ReductionIdScopeSpec.isInvalid()) | ||||||||
14622 | return ExprError(); | ||||||||
14623 | SmallVector<UnresolvedSet<8>, 4> Lookups; | ||||||||
14624 | if (S) { | ||||||||
14625 | LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); | ||||||||
14626 | Lookup.suppressDiagnostics(); | ||||||||
14627 | while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { | ||||||||
14628 | NamedDecl *D = Lookup.getRepresentativeDecl(); | ||||||||
14629 | do { | ||||||||
14630 | S = S->getParent(); | ||||||||
14631 | } while (S && !S->isDeclScope(D)); | ||||||||
14632 | if (S) | ||||||||
14633 | S = S->getParent(); | ||||||||
14634 | Lookups.emplace_back(); | ||||||||
14635 | Lookups.back().append(Lookup.begin(), Lookup.end()); | ||||||||
14636 | Lookup.clear(); | ||||||||
14637 | } | ||||||||
14638 | } else if (auto *ULE = | ||||||||
14639 | cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { | ||||||||
14640 | Lookups.push_back(UnresolvedSet<8>()); | ||||||||
14641 | Decl *PrevD = nullptr; | ||||||||
14642 | for (NamedDecl *D : ULE->decls()) { | ||||||||
14643 | if (D == PrevD) | ||||||||
14644 | Lookups.push_back(UnresolvedSet<8>()); | ||||||||
14645 | else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) | ||||||||
14646 | Lookups.back().addDecl(DRD); | ||||||||
14647 | PrevD = D; | ||||||||
14648 | } | ||||||||
14649 | } | ||||||||
14650 | if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || | ||||||||
14651 | Ty->isInstantiationDependentType() || | ||||||||
14652 | Ty->containsUnexpandedParameterPack() || | ||||||||
14653 | filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { | ||||||||
14654 | return !D->isInvalidDecl() && | ||||||||
14655 | (D->getType()->isDependentType() || | ||||||||
14656 | D->getType()->isInstantiationDependentType() || | ||||||||
14657 | D->getType()->containsUnexpandedParameterPack()); | ||||||||
14658 | })) { | ||||||||
14659 | UnresolvedSet<8> ResSet; | ||||||||
14660 | for (const UnresolvedSet<8> &Set : Lookups) { | ||||||||
14661 | if (Set.empty()) | ||||||||
14662 | continue; | ||||||||
14663 | ResSet.append(Set.begin(), Set.end()); | ||||||||
14664 | // The last item marks the end of all declarations at the specified scope. | ||||||||
14665 | ResSet.addDecl(Set[Set.size() - 1]); | ||||||||
14666 | } | ||||||||
14667 | return UnresolvedLookupExpr::Create( | ||||||||
14668 | SemaRef.Context, /*NamingClass=*/nullptr, | ||||||||
14669 | ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, | ||||||||
14670 | /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); | ||||||||
14671 | } | ||||||||
14672 | // Lookup inside the classes. | ||||||||
14673 | // C++ [over.match.oper]p3: | ||||||||
14674 | // For a unary operator @ with an operand of a type whose | ||||||||
14675 | // cv-unqualified version is T1, and for a binary operator @ with | ||||||||
14676 | // a left operand of a type whose cv-unqualified version is T1 and | ||||||||
14677 | // a right operand of a type whose cv-unqualified version is T2, | ||||||||
14678 | // three sets of candidate functions, designated member | ||||||||
14679 | // candidates, non-member candidates and built-in candidates, are | ||||||||
14680 | // constructed as follows: | ||||||||
14681 | // -- If T1 is a complete class type or a class currently being | ||||||||
14682 | // defined, the set of member candidates is the result of the | ||||||||
14683 | // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, | ||||||||
14684 | // the set of member candidates is empty. | ||||||||
14685 | LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); | ||||||||
14686 | Lookup.suppressDiagnostics(); | ||||||||
14687 | if (const auto *TyRec = Ty->getAs<RecordType>()) { | ||||||||
14688 | // Complete the type if it can be completed. | ||||||||
14689 | // If the type is neither complete nor being defined, bail out now. | ||||||||
14690 | if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || | ||||||||
14691 | TyRec->getDecl()->getDefinition()) { | ||||||||
14692 | Lookup.clear(); | ||||||||
14693 | SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); | ||||||||
14694 | if (Lookup.empty()) { | ||||||||
14695 | Lookups.emplace_back(); | ||||||||
14696 | Lookups.back().append(Lookup.begin(), Lookup.end()); | ||||||||
14697 | } | ||||||||
14698 | } | ||||||||
14699 | } | ||||||||
14700 | // Perform ADL. | ||||||||
14701 | if (SemaRef.getLangOpts().CPlusPlus) | ||||||||
14702 | argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); | ||||||||
14703 | if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( | ||||||||
14704 | Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { | ||||||||
14705 | if (!D->isInvalidDecl() && | ||||||||
14706 | SemaRef.Context.hasSameType(D->getType(), Ty)) | ||||||||
14707 | return D; | ||||||||
14708 | return nullptr; | ||||||||
14709 | })) | ||||||||
14710 | return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), | ||||||||
14711 | VK_LValue, Loc); | ||||||||
14712 | if (SemaRef.getLangOpts().CPlusPlus) { | ||||||||
14713 | if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( | ||||||||
14714 | Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { | ||||||||
14715 | if (!D->isInvalidDecl() && | ||||||||
14716 | SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && | ||||||||
14717 | !Ty.isMoreQualifiedThan(D->getType())) | ||||||||
14718 | return D; | ||||||||
14719 | return nullptr; | ||||||||
14720 | })) { | ||||||||
14721 | CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, | ||||||||
14722 | /*DetectVirtual=*/false); | ||||||||
14723 | if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { | ||||||||
14724 | if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( | ||||||||
14725 | VD->getType().getUnqualifiedType()))) { | ||||||||
14726 | if (SemaRef.CheckBaseClassAccess( | ||||||||
14727 | Loc, VD->getType(), Ty, Paths.front(), | ||||||||
14728 | /*DiagID=*/0) != Sema::AR_inaccessible) { | ||||||||
14729 | SemaRef.BuildBasePathArray(Paths, BasePath); | ||||||||
14730 | return SemaRef.BuildDeclRefExpr( | ||||||||
14731 | VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); | ||||||||
14732 | } | ||||||||
14733 | } | ||||||||
14734 | } | ||||||||
14735 | } | ||||||||
14736 | } | ||||||||
14737 | if (ReductionIdScopeSpec.isSet()) { | ||||||||
14738 | SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) | ||||||||
14739 | << Ty << Range; | ||||||||
14740 | return ExprError(); | ||||||||
14741 | } | ||||||||
14742 | return ExprEmpty(); | ||||||||
14743 | } | ||||||||
14744 | |||||||||
14745 | namespace { | ||||||||
14746 | /// Data for the reduction-based clauses. | ||||||||
14747 | struct ReductionData { | ||||||||
14748 | /// List of original reduction items. | ||||||||
14749 | SmallVector<Expr *, 8> Vars; | ||||||||
14750 | /// List of private copies of the reduction items. | ||||||||
14751 | SmallVector<Expr *, 8> Privates; | ||||||||
14752 | /// LHS expressions for the reduction_op expressions. | ||||||||
14753 | SmallVector<Expr *, 8> LHSs; | ||||||||
14754 | /// RHS expressions for the reduction_op expressions. | ||||||||
14755 | SmallVector<Expr *, 8> RHSs; | ||||||||
14756 | /// Reduction operation expression. | ||||||||
14757 | SmallVector<Expr *, 8> ReductionOps; | ||||||||
14758 | /// inscan copy operation expressions. | ||||||||
14759 | SmallVector<Expr *, 8> InscanCopyOps; | ||||||||
14760 | /// inscan copy temp array expressions for prefix sums. | ||||||||
14761 | SmallVector<Expr *, 8> InscanCopyArrayTemps; | ||||||||
14762 | /// inscan copy temp array element expressions for prefix sums. | ||||||||
14763 | SmallVector<Expr *, 8> InscanCopyArrayElems; | ||||||||
14764 | /// Taskgroup descriptors for the corresponding reduction items in | ||||||||
14765 | /// in_reduction clauses. | ||||||||
14766 | SmallVector<Expr *, 8> TaskgroupDescriptors; | ||||||||
14767 | /// List of captures for clause. | ||||||||
14768 | SmallVector<Decl *, 4> ExprCaptures; | ||||||||
14769 | /// List of postupdate expressions. | ||||||||
14770 | SmallVector<Expr *, 4> ExprPostUpdates; | ||||||||
14771 | /// Reduction modifier. | ||||||||
14772 | unsigned RedModifier = 0; | ||||||||
14773 | ReductionData() = delete; | ||||||||
14774 | /// Reserves required memory for the reduction data. | ||||||||
14775 | ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) { | ||||||||
14776 | Vars.reserve(Size); | ||||||||
14777 | Privates.reserve(Size); | ||||||||
14778 | LHSs.reserve(Size); | ||||||||
14779 | RHSs.reserve(Size); | ||||||||
14780 | ReductionOps.reserve(Size); | ||||||||
14781 | if (RedModifier == OMPC_REDUCTION_inscan) { | ||||||||
14782 | InscanCopyOps.reserve(Size); | ||||||||
14783 | InscanCopyArrayTemps.reserve(Size); | ||||||||
14784 | InscanCopyArrayElems.reserve(Size); | ||||||||
14785 | } | ||||||||
14786 | TaskgroupDescriptors.reserve(Size); | ||||||||
14787 | ExprCaptures.reserve(Size); | ||||||||
14788 | ExprPostUpdates.reserve(Size); | ||||||||
14789 | } | ||||||||
14790 | /// Stores reduction item and reduction operation only (required for dependent | ||||||||
14791 | /// reduction item). | ||||||||
14792 | void push(Expr *Item, Expr *ReductionOp) { | ||||||||
14793 | Vars.emplace_back(Item); | ||||||||
14794 | Privates.emplace_back(nullptr); | ||||||||
14795 | LHSs.emplace_back(nullptr); | ||||||||
14796 | RHSs.emplace_back(nullptr); | ||||||||
14797 | ReductionOps.emplace_back(ReductionOp); | ||||||||
14798 | TaskgroupDescriptors.emplace_back(nullptr); | ||||||||
14799 | if (RedModifier == OMPC_REDUCTION_inscan) { | ||||||||
14800 | InscanCopyOps.push_back(nullptr); | ||||||||
14801 | InscanCopyArrayTemps.push_back(nullptr); | ||||||||
14802 | InscanCopyArrayElems.push_back(nullptr); | ||||||||
14803 | } | ||||||||
14804 | } | ||||||||
14805 | /// Stores reduction data. | ||||||||
14806 | void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, | ||||||||
14807 | Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp, | ||||||||
14808 | Expr *CopyArrayElem) { | ||||||||
14809 | Vars.emplace_back(Item); | ||||||||
14810 | Privates.emplace_back(Private); | ||||||||
14811 | LHSs.emplace_back(LHS); | ||||||||
14812 | RHSs.emplace_back(RHS); | ||||||||
14813 | ReductionOps.emplace_back(ReductionOp); | ||||||||
14814 | TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); | ||||||||
14815 | if (RedModifier == OMPC_REDUCTION_inscan) { | ||||||||
14816 | InscanCopyOps.push_back(CopyOp); | ||||||||
14817 | InscanCopyArrayTemps.push_back(CopyArrayTemp); | ||||||||
14818 | InscanCopyArrayElems.push_back(CopyArrayElem); | ||||||||
14819 | } else { | ||||||||
14820 | assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&((CopyOp == nullptr && CopyArrayTemp == nullptr && CopyArrayElem == nullptr && "Copy operation must be used for inscan reductions only." ) ? static_cast<void> (0) : __assert_fail ("CopyOp == nullptr && CopyArrayTemp == nullptr && CopyArrayElem == nullptr && \"Copy operation must be used for inscan reductions only.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 14822, __PRETTY_FUNCTION__)) | ||||||||
14821 | CopyArrayElem == nullptr &&((CopyOp == nullptr && CopyArrayTemp == nullptr && CopyArrayElem == nullptr && "Copy operation must be used for inscan reductions only." ) ? static_cast<void> (0) : __assert_fail ("CopyOp == nullptr && CopyArrayTemp == nullptr && CopyArrayElem == nullptr && \"Copy operation must be used for inscan reductions only.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 14822, __PRETTY_FUNCTION__)) | ||||||||
14822 | "Copy operation must be used for inscan reductions only.")((CopyOp == nullptr && CopyArrayTemp == nullptr && CopyArrayElem == nullptr && "Copy operation must be used for inscan reductions only." ) ? static_cast<void> (0) : __assert_fail ("CopyOp == nullptr && CopyArrayTemp == nullptr && CopyArrayElem == nullptr && \"Copy operation must be used for inscan reductions only.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 14822, __PRETTY_FUNCTION__)); | ||||||||
14823 | } | ||||||||
14824 | } | ||||||||
14825 | }; | ||||||||
14826 | } // namespace | ||||||||
14827 | |||||||||
14828 | static bool checkOMPArraySectionConstantForReduction( | ||||||||
14829 | ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, | ||||||||
14830 | SmallVectorImpl<llvm::APSInt> &ArraySizes) { | ||||||||
14831 | const Expr *Length = OASE->getLength(); | ||||||||
14832 | if (Length == nullptr) { | ||||||||
14833 | // For array sections of the form [1:] or [:], we would need to analyze | ||||||||
14834 | // the lower bound... | ||||||||
14835 | if (OASE->getColonLocFirst().isValid()) | ||||||||
14836 | return false; | ||||||||
14837 | |||||||||
14838 | // This is an array subscript which has implicit length 1! | ||||||||
14839 | SingleElement = true; | ||||||||
14840 | ArraySizes.push_back(llvm::APSInt::get(1)); | ||||||||
14841 | } else { | ||||||||
14842 | Expr::EvalResult Result; | ||||||||
14843 | if (!Length->EvaluateAsInt(Result, Context)) | ||||||||
14844 | return false; | ||||||||
14845 | |||||||||
14846 | llvm::APSInt ConstantLengthValue = Result.Val.getInt(); | ||||||||
14847 | SingleElement = (ConstantLengthValue.getSExtValue() == 1); | ||||||||
14848 | ArraySizes.push_back(ConstantLengthValue); | ||||||||
14849 | } | ||||||||
14850 | |||||||||
14851 | // Get the base of this array section and walk up from there. | ||||||||
14852 | const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); | ||||||||
14853 | |||||||||
14854 | // We require length = 1 for all array sections except the right-most to | ||||||||
14855 | // guarantee that the memory region is contiguous and has no holes in it. | ||||||||
14856 | while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { | ||||||||
14857 | Length = TempOASE->getLength(); | ||||||||
14858 | if (Length == nullptr) { | ||||||||
14859 | // For array sections of the form [1:] or [:], we would need to analyze | ||||||||
14860 | // the lower bound... | ||||||||
14861 | if (OASE->getColonLocFirst().isValid()) | ||||||||
14862 | return false; | ||||||||
14863 | |||||||||
14864 | // This is an array subscript which has implicit length 1! | ||||||||
14865 | ArraySizes.push_back(llvm::APSInt::get(1)); | ||||||||
14866 | } else { | ||||||||
14867 | Expr::EvalResult Result; | ||||||||
14868 | if (!Length->EvaluateAsInt(Result, Context)) | ||||||||
14869 | return false; | ||||||||
14870 | |||||||||
14871 | llvm::APSInt ConstantLengthValue = Result.Val.getInt(); | ||||||||
14872 | if (ConstantLengthValue.getSExtValue() != 1) | ||||||||
14873 | return false; | ||||||||
14874 | |||||||||
14875 | ArraySizes.push_back(ConstantLengthValue); | ||||||||
14876 | } | ||||||||
14877 | Base = TempOASE->getBase()->IgnoreParenImpCasts(); | ||||||||
14878 | } | ||||||||
14879 | |||||||||
14880 | // If we have a single element, we don't need to add the implicit lengths. | ||||||||
14881 | if (!SingleElement) { | ||||||||
14882 | while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { | ||||||||
14883 | // Has implicit length 1! | ||||||||
14884 | ArraySizes.push_back(llvm::APSInt::get(1)); | ||||||||
14885 | Base = TempASE->getBase()->IgnoreParenImpCasts(); | ||||||||
14886 | } | ||||||||
14887 | } | ||||||||
14888 | |||||||||
14889 | // This array section can be privatized as a single value or as a constant | ||||||||
14890 | // sized array. | ||||||||
14891 | return true; | ||||||||
14892 | } | ||||||||
14893 | |||||||||
14894 | static bool actOnOMPReductionKindClause( | ||||||||
14895 | Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, | ||||||||
14896 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, | ||||||||
14897 | SourceLocation ColonLoc, SourceLocation EndLoc, | ||||||||
14898 | CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, | ||||||||
14899 | ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { | ||||||||
14900 | DeclarationName DN = ReductionId.getName(); | ||||||||
14901 | OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); | ||||||||
14902 | BinaryOperatorKind BOK = BO_Comma; | ||||||||
14903 | |||||||||
14904 | ASTContext &Context = S.Context; | ||||||||
14905 | // OpenMP [2.14.3.6, reduction clause] | ||||||||
14906 | // C | ||||||||
14907 | // reduction-identifier is either an identifier or one of the following | ||||||||
14908 | // operators: +, -, *, &, |, ^, && and || | ||||||||
14909 | // C++ | ||||||||
14910 | // reduction-identifier is either an id-expression or one of the following | ||||||||
14911 | // operators: +, -, *, &, |, ^, && and || | ||||||||
14912 | switch (OOK) { | ||||||||
14913 | case OO_Plus: | ||||||||
14914 | case OO_Minus: | ||||||||
14915 | BOK = BO_Add; | ||||||||
14916 | break; | ||||||||
14917 | case OO_Star: | ||||||||
14918 | BOK = BO_Mul; | ||||||||
14919 | break; | ||||||||
14920 | case OO_Amp: | ||||||||
14921 | BOK = BO_And; | ||||||||
14922 | break; | ||||||||
14923 | case OO_Pipe: | ||||||||
14924 | BOK = BO_Or; | ||||||||
14925 | break; | ||||||||
14926 | case OO_Caret: | ||||||||
14927 | BOK = BO_Xor; | ||||||||
14928 | break; | ||||||||
14929 | case OO_AmpAmp: | ||||||||
14930 | BOK = BO_LAnd; | ||||||||
14931 | break; | ||||||||
14932 | case OO_PipePipe: | ||||||||
14933 | BOK = BO_LOr; | ||||||||
14934 | break; | ||||||||
14935 | case OO_New: | ||||||||
14936 | case OO_Delete: | ||||||||
14937 | case OO_Array_New: | ||||||||
14938 | case OO_Array_Delete: | ||||||||
14939 | case OO_Slash: | ||||||||
14940 | case OO_Percent: | ||||||||
14941 | case OO_Tilde: | ||||||||
14942 | case OO_Exclaim: | ||||||||
14943 | case OO_Equal: | ||||||||
14944 | case OO_Less: | ||||||||
14945 | case OO_Greater: | ||||||||
14946 | case OO_LessEqual: | ||||||||
14947 | case OO_GreaterEqual: | ||||||||
14948 | case OO_PlusEqual: | ||||||||
14949 | case OO_MinusEqual: | ||||||||
14950 | case OO_StarEqual: | ||||||||
14951 | case OO_SlashEqual: | ||||||||
14952 | case OO_PercentEqual: | ||||||||
14953 | case OO_CaretEqual: | ||||||||
14954 | case OO_AmpEqual: | ||||||||
14955 | case OO_PipeEqual: | ||||||||
14956 | case OO_LessLess: | ||||||||
14957 | case OO_GreaterGreater: | ||||||||
14958 | case OO_LessLessEqual: | ||||||||
14959 | case OO_GreaterGreaterEqual: | ||||||||
14960 | case OO_EqualEqual: | ||||||||
14961 | case OO_ExclaimEqual: | ||||||||
14962 | case OO_Spaceship: | ||||||||
14963 | case OO_PlusPlus: | ||||||||
14964 | case OO_MinusMinus: | ||||||||
14965 | case OO_Comma: | ||||||||
14966 | case OO_ArrowStar: | ||||||||
14967 | case OO_Arrow: | ||||||||
14968 | case OO_Call: | ||||||||
14969 | case OO_Subscript: | ||||||||
14970 | case OO_Conditional: | ||||||||
14971 | case OO_Coawait: | ||||||||
14972 | case NUM_OVERLOADED_OPERATORS: | ||||||||
14973 | llvm_unreachable("Unexpected reduction identifier")::llvm::llvm_unreachable_internal("Unexpected reduction identifier" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 14973); | ||||||||
14974 | case OO_None: | ||||||||
14975 | if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { | ||||||||
14976 | if (II->isStr("max")) | ||||||||
14977 | BOK = BO_GT; | ||||||||
14978 | else if (II->isStr("min")) | ||||||||
14979 | BOK = BO_LT; | ||||||||
14980 | } | ||||||||
14981 | break; | ||||||||
14982 | } | ||||||||
14983 | SourceRange ReductionIdRange; | ||||||||
14984 | if (ReductionIdScopeSpec.isValid()) | ||||||||
14985 | ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); | ||||||||
14986 | else | ||||||||
14987 | ReductionIdRange.setBegin(ReductionId.getBeginLoc()); | ||||||||
14988 | ReductionIdRange.setEnd(ReductionId.getEndLoc()); | ||||||||
14989 | |||||||||
14990 | auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); | ||||||||
14991 | bool FirstIter = true; | ||||||||
14992 | for (Expr *RefExpr : VarList) { | ||||||||
14993 | 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.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 14993, __PRETTY_FUNCTION__)); | ||||||||
14994 | // OpenMP [2.1, C/C++] | ||||||||
14995 | // A list item is a variable or array section, subject to the restrictions | ||||||||
14996 | // specified in Section 2.4 on page 42 and in each of the sections | ||||||||
14997 | // describing clauses and directives for which a list appears. | ||||||||
14998 | // OpenMP [2.14.3.3, Restrictions, p.1] | ||||||||
14999 | // A variable that is part of another variable (as an array or | ||||||||
15000 | // structure element) cannot appear in a private clause. | ||||||||
15001 | if (!FirstIter && IR != ER) | ||||||||
15002 | ++IR; | ||||||||
15003 | FirstIter = false; | ||||||||
15004 | SourceLocation ELoc; | ||||||||
15005 | SourceRange ERange; | ||||||||
15006 | Expr *SimpleRefExpr = RefExpr; | ||||||||
15007 | auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, | ||||||||
15008 | /*AllowArraySection=*/true); | ||||||||
15009 | if (Res.second) { | ||||||||
15010 | // Try to find 'declare reduction' corresponding construct before using | ||||||||
15011 | // builtin/overloaded operators. | ||||||||
15012 | QualType Type = Context.DependentTy; | ||||||||
15013 | CXXCastPath BasePath; | ||||||||
15014 | ExprResult DeclareReductionRef = buildDeclareReductionRef( | ||||||||
15015 | S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, | ||||||||
15016 | ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); | ||||||||
15017 | Expr *ReductionOp = nullptr; | ||||||||
15018 | if (S.CurContext->isDependentContext() && | ||||||||
15019 | (DeclareReductionRef.isUnset() || | ||||||||
15020 | isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) | ||||||||
15021 | ReductionOp = DeclareReductionRef.get(); | ||||||||
15022 | // It will be analyzed later. | ||||||||
15023 | RD.push(RefExpr, ReductionOp); | ||||||||
15024 | } | ||||||||
15025 | ValueDecl *D = Res.first; | ||||||||
15026 | if (!D) | ||||||||
15027 | continue; | ||||||||
15028 | |||||||||
15029 | Expr *TaskgroupDescriptor = nullptr; | ||||||||
15030 | QualType Type; | ||||||||
15031 | auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); | ||||||||
15032 | auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); | ||||||||
15033 | if (ASE) { | ||||||||
15034 | Type = ASE->getType().getNonReferenceType(); | ||||||||
15035 | } else if (OASE) { | ||||||||
15036 | QualType BaseType = | ||||||||
15037 | OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); | ||||||||
15038 | if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) | ||||||||
15039 | Type = ATy->getElementType(); | ||||||||
15040 | else | ||||||||
15041 | Type = BaseType->getPointeeType(); | ||||||||
15042 | Type = Type.getNonReferenceType(); | ||||||||
15043 | } else { | ||||||||
15044 | Type = Context.getBaseElementType(D->getType().getNonReferenceType()); | ||||||||
15045 | } | ||||||||
15046 | auto *VD = dyn_cast<VarDecl>(D); | ||||||||
15047 | |||||||||
15048 | // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] | ||||||||
15049 | // A variable that appears in a private clause must not have an incomplete | ||||||||
15050 | // type or a reference type. | ||||||||
15051 | if (S.RequireCompleteType(ELoc, D->getType(), | ||||||||
15052 | diag::err_omp_reduction_incomplete_type)) | ||||||||
15053 | continue; | ||||||||
15054 | // OpenMP [2.14.3.6, reduction clause, Restrictions] | ||||||||
15055 | // A list item that appears in a reduction clause must not be | ||||||||
15056 | // const-qualified. | ||||||||
15057 | if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, | ||||||||
15058 | /*AcceptIfMutable*/ false, ASE || OASE)) | ||||||||
15059 | continue; | ||||||||
15060 | |||||||||
15061 | OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); | ||||||||
15062 | // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] | ||||||||
15063 | // If a list-item is a reference type then it must bind to the same object | ||||||||
15064 | // for all threads of the team. | ||||||||
15065 | if (!ASE && !OASE) { | ||||||||
15066 | if (VD) { | ||||||||
15067 | VarDecl *VDDef = VD->getDefinition(); | ||||||||
15068 | if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { | ||||||||
15069 | DSARefChecker Check(Stack); | ||||||||
15070 | if (Check.Visit(VDDef->getInit())) { | ||||||||
15071 | S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) | ||||||||
15072 | << getOpenMPClauseName(ClauseKind) << ERange; | ||||||||
15073 | S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; | ||||||||
15074 | continue; | ||||||||
15075 | } | ||||||||
15076 | } | ||||||||
15077 | } | ||||||||
15078 | |||||||||
15079 | // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||||
15080 | // in a Construct] | ||||||||
15081 | // Variables with the predetermined data-sharing attributes may not be | ||||||||
15082 | // listed in data-sharing attributes clauses, except for the cases | ||||||||
15083 | // listed below. For these exceptions only, listing a predetermined | ||||||||
15084 | // variable in a data-sharing attribute clause is allowed and overrides | ||||||||
15085 | // the variable's predetermined data-sharing attributes. | ||||||||
15086 | // OpenMP [2.14.3.6, Restrictions, p.3] | ||||||||
15087 | // Any number of reduction clauses can be specified on the directive, | ||||||||
15088 | // but a list item can appear only once in the reduction clauses for that | ||||||||
15089 | // directive. | ||||||||
15090 | DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); | ||||||||
15091 | if (DVar.CKind == OMPC_reduction) { | ||||||||
15092 | S.Diag(ELoc, diag::err_omp_once_referenced) | ||||||||
15093 | << getOpenMPClauseName(ClauseKind); | ||||||||
15094 | if (DVar.RefExpr) | ||||||||
15095 | S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); | ||||||||
15096 | continue; | ||||||||
15097 | } | ||||||||
15098 | if (DVar.CKind != OMPC_unknown) { | ||||||||
15099 | S.Diag(ELoc, diag::err_omp_wrong_dsa) | ||||||||
15100 | << getOpenMPClauseName(DVar.CKind) | ||||||||
15101 | << getOpenMPClauseName(OMPC_reduction); | ||||||||
15102 | reportOriginalDsa(S, Stack, D, DVar); | ||||||||
15103 | continue; | ||||||||
15104 | } | ||||||||
15105 | |||||||||
15106 | // OpenMP [2.14.3.6, Restrictions, p.1] | ||||||||
15107 | // A list item that appears in a reduction clause of a worksharing | ||||||||
15108 | // construct must be shared in the parallel regions to which any of the | ||||||||
15109 | // worksharing regions arising from the worksharing construct bind. | ||||||||
15110 | if (isOpenMPWorksharingDirective(CurrDir) && | ||||||||
15111 | !isOpenMPParallelDirective(CurrDir) && | ||||||||
15112 | !isOpenMPTeamsDirective(CurrDir)) { | ||||||||
15113 | DVar = Stack->getImplicitDSA(D, true); | ||||||||
15114 | if (DVar.CKind != OMPC_shared) { | ||||||||
15115 | S.Diag(ELoc, diag::err_omp_required_access) | ||||||||
15116 | << getOpenMPClauseName(OMPC_reduction) | ||||||||
15117 | << getOpenMPClauseName(OMPC_shared); | ||||||||
15118 | reportOriginalDsa(S, Stack, D, DVar); | ||||||||
15119 | continue; | ||||||||
15120 | } | ||||||||
15121 | } | ||||||||
15122 | } | ||||||||
15123 | |||||||||
15124 | // Try to find 'declare reduction' corresponding construct before using | ||||||||
15125 | // builtin/overloaded operators. | ||||||||
15126 | CXXCastPath BasePath; | ||||||||
15127 | ExprResult DeclareReductionRef = buildDeclareReductionRef( | ||||||||
15128 | S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, | ||||||||
15129 | ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); | ||||||||
15130 | if (DeclareReductionRef.isInvalid()) | ||||||||
15131 | continue; | ||||||||
15132 | if (S.CurContext->isDependentContext() && | ||||||||
15133 | (DeclareReductionRef.isUnset() || | ||||||||
15134 | isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { | ||||||||
15135 | RD.push(RefExpr, DeclareReductionRef.get()); | ||||||||
15136 | continue; | ||||||||
15137 | } | ||||||||
15138 | if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { | ||||||||
15139 | // Not allowed reduction identifier is found. | ||||||||
15140 | S.Diag(ReductionId.getBeginLoc(), | ||||||||
15141 | diag::err_omp_unknown_reduction_identifier) | ||||||||
15142 | << Type << ReductionIdRange; | ||||||||
15143 | continue; | ||||||||
15144 | } | ||||||||
15145 | |||||||||
15146 | // OpenMP [2.14.3.6, reduction clause, Restrictions] | ||||||||
15147 | // The type of a list item that appears in a reduction clause must be valid | ||||||||
15148 | // for the reduction-identifier. For a max or min reduction in C, the type | ||||||||
15149 | // of the list item must be an allowed arithmetic data type: char, int, | ||||||||
15150 | // float, double, or _Bool, possibly modified with long, short, signed, or | ||||||||
15151 | // unsigned. For a max or min reduction in C++, the type of the list item | ||||||||
15152 | // must be an allowed arithmetic data type: char, wchar_t, int, float, | ||||||||
15153 | // double, or bool, possibly modified with long, short, signed, or unsigned. | ||||||||
15154 | if (DeclareReductionRef.isUnset()) { | ||||||||
15155 | if ((BOK == BO_GT || BOK == BO_LT) && | ||||||||
15156 | !(Type->isScalarType() || | ||||||||
15157 | (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { | ||||||||
15158 | S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) | ||||||||
15159 | << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; | ||||||||
15160 | if (!ASE && !OASE) { | ||||||||
15161 | bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == | ||||||||
15162 | VarDecl::DeclarationOnly; | ||||||||
15163 | S.Diag(D->getLocation(), | ||||||||
15164 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||||
15165 | << D; | ||||||||
15166 | } | ||||||||
15167 | continue; | ||||||||
15168 | } | ||||||||
15169 | if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && | ||||||||
15170 | !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { | ||||||||
15171 | S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) | ||||||||
15172 | << getOpenMPClauseName(ClauseKind); | ||||||||
15173 | if (!ASE && !OASE) { | ||||||||
15174 | bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == | ||||||||
15175 | VarDecl::DeclarationOnly; | ||||||||
15176 | S.Diag(D->getLocation(), | ||||||||
15177 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||||
15178 | << D; | ||||||||
15179 | } | ||||||||
15180 | continue; | ||||||||
15181 | } | ||||||||
15182 | } | ||||||||
15183 | |||||||||
15184 | Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); | ||||||||
15185 | VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", | ||||||||
15186 | D->hasAttrs() ? &D->getAttrs() : nullptr); | ||||||||
15187 | VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), | ||||||||
15188 | D->hasAttrs() ? &D->getAttrs() : nullptr); | ||||||||
15189 | QualType PrivateTy = Type; | ||||||||
15190 | |||||||||
15191 | // Try if we can determine constant lengths for all array sections and avoid | ||||||||
15192 | // the VLA. | ||||||||
15193 | bool ConstantLengthOASE = false; | ||||||||
15194 | if (OASE) { | ||||||||
15195 | bool SingleElement; | ||||||||
15196 | llvm::SmallVector<llvm::APSInt, 4> ArraySizes; | ||||||||
15197 | ConstantLengthOASE = checkOMPArraySectionConstantForReduction( | ||||||||
15198 | Context, OASE, SingleElement, ArraySizes); | ||||||||
15199 | |||||||||
15200 | // If we don't have a single element, we must emit a constant array type. | ||||||||
15201 | if (ConstantLengthOASE && !SingleElement) { | ||||||||
15202 | for (llvm::APSInt &Size : ArraySizes) | ||||||||
15203 | PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, | ||||||||
15204 | ArrayType::Normal, | ||||||||
15205 | /*IndexTypeQuals=*/0); | ||||||||
15206 | } | ||||||||
15207 | } | ||||||||
15208 | |||||||||
15209 | if ((OASE && !ConstantLengthOASE) || | ||||||||
15210 | (!OASE && !ASE && | ||||||||
15211 | D->getType().getNonReferenceType()->isVariablyModifiedType())) { | ||||||||
15212 | if (!Context.getTargetInfo().isVLASupported()) { | ||||||||
15213 | if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { | ||||||||
15214 | S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; | ||||||||
15215 | S.Diag(ELoc, diag::note_vla_unsupported); | ||||||||
15216 | continue; | ||||||||
15217 | } else { | ||||||||
15218 | S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; | ||||||||
15219 | S.targetDiag(ELoc, diag::note_vla_unsupported); | ||||||||
15220 | } | ||||||||
15221 | } | ||||||||
15222 | // For arrays/array sections only: | ||||||||
15223 | // Create pseudo array type for private copy. The size for this array will | ||||||||
15224 | // be generated during codegen. | ||||||||
15225 | // For array subscripts or single variables Private Ty is the same as Type | ||||||||
15226 | // (type of the variable or single array element). | ||||||||
15227 | PrivateTy = Context.getVariableArrayType( | ||||||||
15228 | Type, | ||||||||
15229 | new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), | ||||||||
15230 | ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); | ||||||||
15231 | } else if (!ASE && !OASE && | ||||||||
15232 | Context.getAsArrayType(D->getType().getNonReferenceType())) { | ||||||||
15233 | PrivateTy = D->getType().getNonReferenceType(); | ||||||||
15234 | } | ||||||||
15235 | // Private copy. | ||||||||
15236 | VarDecl *PrivateVD = | ||||||||
15237 | buildVarDecl(S, ELoc, PrivateTy, D->getName(), | ||||||||
15238 | D->hasAttrs() ? &D->getAttrs() : nullptr, | ||||||||
15239 | VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); | ||||||||
15240 | // Add initializer for private variable. | ||||||||
15241 | Expr *Init = nullptr; | ||||||||
15242 | DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); | ||||||||
15243 | DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); | ||||||||
15244 | if (DeclareReductionRef.isUsable()) { | ||||||||
15245 | auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); | ||||||||
15246 | auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); | ||||||||
15247 | if (DRD->getInitializer()) { | ||||||||
15248 | S.ActOnUninitializedDecl(PrivateVD); | ||||||||
15249 | Init = DRDRef; | ||||||||
15250 | RHSVD->setInit(DRDRef); | ||||||||
15251 | RHSVD->setInitStyle(VarDecl::CallInit); | ||||||||
15252 | } | ||||||||
15253 | } else { | ||||||||
15254 | switch (BOK) { | ||||||||
15255 | case BO_Add: | ||||||||
15256 | case BO_Xor: | ||||||||
15257 | case BO_Or: | ||||||||
15258 | case BO_LOr: | ||||||||
15259 | // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. | ||||||||
15260 | if (Type->isScalarType() || Type->isAnyComplexType()) | ||||||||
15261 | Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); | ||||||||
15262 | break; | ||||||||
15263 | case BO_Mul: | ||||||||
15264 | case BO_LAnd: | ||||||||
15265 | if (Type->isScalarType() || Type->isAnyComplexType()) { | ||||||||
15266 | // '*' and '&&' reduction ops - initializer is '1'. | ||||||||
15267 | Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); | ||||||||
15268 | } | ||||||||
15269 | break; | ||||||||
15270 | case BO_And: { | ||||||||
15271 | // '&' reduction op - initializer is '~0'. | ||||||||
15272 | QualType OrigType = Type; | ||||||||
15273 | if (auto *ComplexTy = OrigType->getAs<ComplexType>()) | ||||||||
15274 | Type = ComplexTy->getElementType(); | ||||||||
15275 | if (Type->isRealFloatingType()) { | ||||||||
15276 | llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue( | ||||||||
15277 | Context.getFloatTypeSemantics(Type), | ||||||||
15278 | Context.getTypeSize(Type)); | ||||||||
15279 | Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, | ||||||||
15280 | Type, ELoc); | ||||||||
15281 | } else if (Type->isScalarType()) { | ||||||||
15282 | uint64_t Size = Context.getTypeSize(Type); | ||||||||
15283 | QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); | ||||||||
15284 | llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); | ||||||||
15285 | Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); | ||||||||
15286 | } | ||||||||
15287 | if (Init && OrigType->isAnyComplexType()) { | ||||||||
15288 | // Init = 0xFFFF + 0xFFFFi; | ||||||||
15289 | auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); | ||||||||
15290 | Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); | ||||||||
15291 | } | ||||||||
15292 | Type = OrigType; | ||||||||
15293 | break; | ||||||||
15294 | } | ||||||||
15295 | case BO_LT: | ||||||||
15296 | case BO_GT: { | ||||||||
15297 | // 'min' reduction op - initializer is 'Largest representable number in | ||||||||
15298 | // the reduction list item type'. | ||||||||
15299 | // 'max' reduction op - initializer is 'Least representable number in | ||||||||
15300 | // the reduction list item type'. | ||||||||
15301 | if (Type->isIntegerType() || Type->isPointerType()) { | ||||||||
15302 | bool IsSigned = Type->hasSignedIntegerRepresentation(); | ||||||||
15303 | uint64_t Size = Context.getTypeSize(Type); | ||||||||
15304 | QualType IntTy = | ||||||||
15305 | Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); | ||||||||
15306 | llvm::APInt InitValue = | ||||||||
15307 | (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) | ||||||||
15308 | : llvm::APInt::getMinValue(Size) | ||||||||
15309 | : IsSigned ? llvm::APInt::getSignedMaxValue(Size) | ||||||||
15310 | : llvm::APInt::getMaxValue(Size); | ||||||||
15311 | Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); | ||||||||
15312 | if (Type->isPointerType()) { | ||||||||
15313 | // Cast to pointer type. | ||||||||
15314 | ExprResult CastExpr = S.BuildCStyleCastExpr( | ||||||||
15315 | ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); | ||||||||
15316 | if (CastExpr.isInvalid()) | ||||||||
15317 | continue; | ||||||||
15318 | Init = CastExpr.get(); | ||||||||
15319 | } | ||||||||
15320 | } else if (Type->isRealFloatingType()) { | ||||||||
15321 | llvm::APFloat InitValue = llvm::APFloat::getLargest( | ||||||||
15322 | Context.getFloatTypeSemantics(Type), BOK != BO_LT); | ||||||||
15323 | Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, | ||||||||
15324 | Type, ELoc); | ||||||||
15325 | } | ||||||||
15326 | break; | ||||||||
15327 | } | ||||||||
15328 | case BO_PtrMemD: | ||||||||
15329 | case BO_PtrMemI: | ||||||||
15330 | case BO_MulAssign: | ||||||||
15331 | case BO_Div: | ||||||||
15332 | case BO_Rem: | ||||||||
15333 | case BO_Sub: | ||||||||
15334 | case BO_Shl: | ||||||||
15335 | case BO_Shr: | ||||||||
15336 | case BO_LE: | ||||||||
15337 | case BO_GE: | ||||||||
15338 | case BO_EQ: | ||||||||
15339 | case BO_NE: | ||||||||
15340 | case BO_Cmp: | ||||||||
15341 | case BO_AndAssign: | ||||||||
15342 | case BO_XorAssign: | ||||||||
15343 | case BO_OrAssign: | ||||||||
15344 | case BO_Assign: | ||||||||
15345 | case BO_AddAssign: | ||||||||
15346 | case BO_SubAssign: | ||||||||
15347 | case BO_DivAssign: | ||||||||
15348 | case BO_RemAssign: | ||||||||
15349 | case BO_ShlAssign: | ||||||||
15350 | case BO_ShrAssign: | ||||||||
15351 | case BO_Comma: | ||||||||
15352 | llvm_unreachable("Unexpected reduction operation")::llvm::llvm_unreachable_internal("Unexpected reduction operation" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 15352); | ||||||||
15353 | } | ||||||||
15354 | } | ||||||||
15355 | if (Init && DeclareReductionRef.isUnset()) { | ||||||||
15356 | S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); | ||||||||
15357 | // Store initializer for single element in private copy. Will be used | ||||||||
15358 | // during codegen. | ||||||||
15359 | PrivateVD->setInit(RHSVD->getInit()); | ||||||||
15360 | PrivateVD->setInitStyle(RHSVD->getInitStyle()); | ||||||||
15361 | } else if (!Init) { | ||||||||
15362 | S.ActOnUninitializedDecl(RHSVD); | ||||||||
15363 | // Store initializer for single element in private copy. Will be used | ||||||||
15364 | // during codegen. | ||||||||
15365 | PrivateVD->setInit(RHSVD->getInit()); | ||||||||
15366 | PrivateVD->setInitStyle(RHSVD->getInitStyle()); | ||||||||
15367 | } | ||||||||
15368 | if (RHSVD->isInvalidDecl()) | ||||||||
15369 | continue; | ||||||||
15370 | if (!RHSVD->hasInit() && | ||||||||
15371 | (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { | ||||||||
15372 | S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) | ||||||||
15373 | << Type << ReductionIdRange; | ||||||||
15374 | bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == | ||||||||
15375 | VarDecl::DeclarationOnly; | ||||||||
15376 | S.Diag(D->getLocation(), | ||||||||
15377 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||||
15378 | << D; | ||||||||
15379 | continue; | ||||||||
15380 | } | ||||||||
15381 | DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); | ||||||||
15382 | ExprResult ReductionOp; | ||||||||
15383 | if (DeclareReductionRef.isUsable()) { | ||||||||
15384 | QualType RedTy = DeclareReductionRef.get()->getType(); | ||||||||
15385 | QualType PtrRedTy = Context.getPointerType(RedTy); | ||||||||
15386 | ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); | ||||||||
15387 | ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); | ||||||||
15388 | if (!BasePath.empty()) { | ||||||||
15389 | LHS = S.DefaultLvalueConversion(LHS.get()); | ||||||||
15390 | RHS = S.DefaultLvalueConversion(RHS.get()); | ||||||||
15391 | LHS = ImplicitCastExpr::Create( | ||||||||
15392 | Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath, | ||||||||
15393 | LHS.get()->getValueKind(), FPOptionsOverride()); | ||||||||
15394 | RHS = ImplicitCastExpr::Create( | ||||||||
15395 | Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath, | ||||||||
15396 | RHS.get()->getValueKind(), FPOptionsOverride()); | ||||||||
15397 | } | ||||||||
15398 | FunctionProtoType::ExtProtoInfo EPI; | ||||||||
15399 | QualType Params[] = {PtrRedTy, PtrRedTy}; | ||||||||
15400 | QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); | ||||||||
15401 | auto *OVE = new (Context) OpaqueValueExpr( | ||||||||
15402 | ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, | ||||||||
15403 | S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); | ||||||||
15404 | Expr *Args[] = {LHS.get(), RHS.get()}; | ||||||||
15405 | ReductionOp = | ||||||||
15406 | CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc, | ||||||||
15407 | S.CurFPFeatureOverrides()); | ||||||||
15408 | } else { | ||||||||
15409 | ReductionOp = S.BuildBinOp( | ||||||||
15410 | Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); | ||||||||
15411 | if (ReductionOp.isUsable()) { | ||||||||
15412 | if (BOK != BO_LT && BOK != BO_GT) { | ||||||||
15413 | ReductionOp = | ||||||||
15414 | S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), | ||||||||
15415 | BO_Assign, LHSDRE, ReductionOp.get()); | ||||||||
15416 | } else { | ||||||||
15417 | auto *ConditionalOp = new (Context) | ||||||||
15418 | ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, | ||||||||
15419 | Type, VK_LValue, OK_Ordinary); | ||||||||
15420 | ReductionOp = | ||||||||
15421 | S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), | ||||||||
15422 | BO_Assign, LHSDRE, ConditionalOp); | ||||||||
15423 | } | ||||||||
15424 | if (ReductionOp.isUsable()) | ||||||||
15425 | ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), | ||||||||
15426 | /*DiscardedValue*/ false); | ||||||||
15427 | } | ||||||||
15428 | if (!ReductionOp.isUsable()) | ||||||||
15429 | continue; | ||||||||
15430 | } | ||||||||
15431 | |||||||||
15432 | // Add copy operations for inscan reductions. | ||||||||
15433 | // LHS = RHS; | ||||||||
15434 | ExprResult CopyOpRes, TempArrayRes, TempArrayElem; | ||||||||
15435 | if (ClauseKind == OMPC_reduction && | ||||||||
15436 | RD.RedModifier == OMPC_REDUCTION_inscan) { | ||||||||
15437 | ExprResult RHS = S.DefaultLvalueConversion(RHSDRE); | ||||||||
15438 | CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE, | ||||||||
15439 | RHS.get()); | ||||||||
15440 | if (!CopyOpRes.isUsable()) | ||||||||
15441 | continue; | ||||||||
15442 | CopyOpRes = | ||||||||
15443 | S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true); | ||||||||
15444 | if (!CopyOpRes.isUsable()) | ||||||||
15445 | continue; | ||||||||
15446 | // For simd directive and simd-based directives in simd mode no need to | ||||||||
15447 | // construct temp array, need just a single temp element. | ||||||||
15448 | if (Stack->getCurrentDirective() == OMPD_simd || | ||||||||
15449 | (S.getLangOpts().OpenMPSimd && | ||||||||
15450 | isOpenMPSimdDirective(Stack->getCurrentDirective()))) { | ||||||||
15451 | VarDecl *TempArrayVD = | ||||||||
15452 | buildVarDecl(S, ELoc, PrivateTy, D->getName(), | ||||||||
15453 | D->hasAttrs() ? &D->getAttrs() : nullptr); | ||||||||
15454 | // Add a constructor to the temp decl. | ||||||||
15455 | S.ActOnUninitializedDecl(TempArrayVD); | ||||||||
15456 | TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc); | ||||||||
15457 | } else { | ||||||||
15458 | // Build temp array for prefix sum. | ||||||||
15459 | auto *Dim = new (S.Context) | ||||||||
15460 | OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue); | ||||||||
15461 | QualType ArrayTy = | ||||||||
15462 | S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal, | ||||||||
15463 | /*IndexTypeQuals=*/0, {ELoc, ELoc}); | ||||||||
15464 | VarDecl *TempArrayVD = | ||||||||
15465 | buildVarDecl(S, ELoc, ArrayTy, D->getName(), | ||||||||
15466 | D->hasAttrs() ? &D->getAttrs() : nullptr); | ||||||||
15467 | // Add a constructor to the temp decl. | ||||||||
15468 | S.ActOnUninitializedDecl(TempArrayVD); | ||||||||
15469 | TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc); | ||||||||
15470 | TempArrayElem = | ||||||||
15471 | S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get()); | ||||||||
15472 | auto *Idx = new (S.Context) | ||||||||
15473 | OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue); | ||||||||
15474 | TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(), | ||||||||
15475 | ELoc, Idx, ELoc); | ||||||||
15476 | } | ||||||||
15477 | } | ||||||||
15478 | |||||||||
15479 | // OpenMP [2.15.4.6, Restrictions, p.2] | ||||||||
15480 | // A list item that appears in an in_reduction clause of a task construct | ||||||||
15481 | // must appear in a task_reduction clause of a construct associated with a | ||||||||
15482 | // taskgroup region that includes the participating task in its taskgroup | ||||||||
15483 | // set. The construct associated with the innermost region that meets this | ||||||||
15484 | // condition must specify the same reduction-identifier as the in_reduction | ||||||||
15485 | // clause. | ||||||||
15486 | if (ClauseKind == OMPC_in_reduction) { | ||||||||
15487 | SourceRange ParentSR; | ||||||||
15488 | BinaryOperatorKind ParentBOK; | ||||||||
15489 | const Expr *ParentReductionOp = nullptr; | ||||||||
15490 | Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr; | ||||||||
15491 | DSAStackTy::DSAVarData ParentBOKDSA = | ||||||||
15492 | Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, | ||||||||
15493 | ParentBOKTD); | ||||||||
15494 | DSAStackTy::DSAVarData ParentReductionOpDSA = | ||||||||
15495 | Stack->getTopMostTaskgroupReductionData( | ||||||||
15496 | D, ParentSR, ParentReductionOp, ParentReductionOpTD); | ||||||||
15497 | bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; | ||||||||
15498 | bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; | ||||||||
15499 | if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || | ||||||||
15500 | (DeclareReductionRef.isUsable() && IsParentBOK) || | ||||||||
15501 | (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) { | ||||||||
15502 | bool EmitError = true; | ||||||||
15503 | if (IsParentReductionOp && DeclareReductionRef.isUsable()) { | ||||||||
15504 | llvm::FoldingSetNodeID RedId, ParentRedId; | ||||||||
15505 | ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); | ||||||||
15506 | DeclareReductionRef.get()->Profile(RedId, Context, | ||||||||
15507 | /*Canonical=*/true); | ||||||||
15508 | EmitError = RedId != ParentRedId; | ||||||||
15509 | } | ||||||||
15510 | if (EmitError) { | ||||||||
15511 | S.Diag(ReductionId.getBeginLoc(), | ||||||||
15512 | diag::err_omp_reduction_identifier_mismatch) | ||||||||
15513 | << ReductionIdRange << RefExpr->getSourceRange(); | ||||||||
15514 | S.Diag(ParentSR.getBegin(), | ||||||||
15515 | diag::note_omp_previous_reduction_identifier) | ||||||||
15516 | << ParentSR | ||||||||
15517 | << (IsParentBOK ? ParentBOKDSA.RefExpr | ||||||||
15518 | : ParentReductionOpDSA.RefExpr) | ||||||||
15519 | ->getSourceRange(); | ||||||||
15520 | continue; | ||||||||
15521 | } | ||||||||
15522 | } | ||||||||
15523 | TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; | ||||||||
15524 | } | ||||||||
15525 | |||||||||
15526 | DeclRefExpr *Ref = nullptr; | ||||||||
15527 | Expr *VarsExpr = RefExpr->IgnoreParens(); | ||||||||
15528 | if (!VD && !S.CurContext->isDependentContext()) { | ||||||||
15529 | if (ASE || OASE) { | ||||||||
15530 | TransformExprToCaptures RebuildToCapture(S, D); | ||||||||
15531 | VarsExpr = | ||||||||
15532 | RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); | ||||||||
15533 | Ref = RebuildToCapture.getCapturedExpr(); | ||||||||
15534 | } else { | ||||||||
15535 | VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); | ||||||||
15536 | } | ||||||||
15537 | if (!S.isOpenMPCapturedDecl(D)) { | ||||||||
15538 | RD.ExprCaptures.emplace_back(Ref->getDecl()); | ||||||||
15539 | if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { | ||||||||
15540 | ExprResult RefRes = S.DefaultLvalueConversion(Ref); | ||||||||
15541 | if (!RefRes.isUsable()) | ||||||||
15542 | continue; | ||||||||
15543 | ExprResult PostUpdateRes = | ||||||||
15544 | S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, | ||||||||
15545 | RefRes.get()); | ||||||||
15546 | if (!PostUpdateRes.isUsable()) | ||||||||
15547 | continue; | ||||||||
15548 | if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || | ||||||||
15549 | Stack->getCurrentDirective() == OMPD_taskgroup) { | ||||||||
15550 | S.Diag(RefExpr->getExprLoc(), | ||||||||
15551 | diag::err_omp_reduction_non_addressable_expression) | ||||||||
15552 | << RefExpr->getSourceRange(); | ||||||||
15553 | continue; | ||||||||
15554 | } | ||||||||
15555 | RD.ExprPostUpdates.emplace_back( | ||||||||
15556 | S.IgnoredValueConversions(PostUpdateRes.get()).get()); | ||||||||
15557 | } | ||||||||
15558 | } | ||||||||
15559 | } | ||||||||
15560 | // All reduction items are still marked as reduction (to do not increase | ||||||||
15561 | // code base size). | ||||||||
15562 | unsigned Modifier = RD.RedModifier; | ||||||||
15563 | // Consider task_reductions as reductions with task modifier. Required for | ||||||||
15564 | // correct analysis of in_reduction clauses. | ||||||||
15565 | if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction) | ||||||||
15566 | Modifier = OMPC_REDUCTION_task; | ||||||||
15567 | Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier, | ||||||||
15568 | ASE || OASE); | ||||||||
15569 | if (Modifier == OMPC_REDUCTION_task && | ||||||||
15570 | (CurrDir == OMPD_taskgroup || | ||||||||
15571 | ((isOpenMPParallelDirective(CurrDir) || | ||||||||
15572 | isOpenMPWorksharingDirective(CurrDir)) && | ||||||||
15573 | !isOpenMPSimdDirective(CurrDir)))) { | ||||||||
15574 | if (DeclareReductionRef.isUsable()) | ||||||||
15575 | Stack->addTaskgroupReductionData(D, ReductionIdRange, | ||||||||
15576 | DeclareReductionRef.get()); | ||||||||
15577 | else | ||||||||
15578 | Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); | ||||||||
15579 | } | ||||||||
15580 | RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), | ||||||||
15581 | TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(), | ||||||||
15582 | TempArrayElem.get()); | ||||||||
15583 | } | ||||||||
15584 | return RD.Vars.empty(); | ||||||||
15585 | } | ||||||||
15586 | |||||||||
15587 | OMPClause *Sema::ActOnOpenMPReductionClause( | ||||||||
15588 | ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, | ||||||||
15589 | SourceLocation StartLoc, SourceLocation LParenLoc, | ||||||||
15590 | SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, | ||||||||
15591 | CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, | ||||||||
15592 | ArrayRef<Expr *> UnresolvedReductions) { | ||||||||
15593 | if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) { | ||||||||
15594 | Diag(LParenLoc, diag::err_omp_unexpected_clause_value) | ||||||||
15595 | << getListOfPossibleValues(OMPC_reduction, /*First=*/0, | ||||||||
15596 | /*Last=*/OMPC_REDUCTION_unknown) | ||||||||
15597 | << getOpenMPClauseName(OMPC_reduction); | ||||||||
15598 | return nullptr; | ||||||||
15599 | } | ||||||||
15600 | // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions | ||||||||
15601 | // A reduction clause with the inscan reduction-modifier may only appear on a | ||||||||
15602 | // worksharing-loop construct, a worksharing-loop SIMD construct, a simd | ||||||||
15603 | // construct, a parallel worksharing-loop construct or a parallel | ||||||||
15604 | // worksharing-loop SIMD construct. | ||||||||
15605 | if (Modifier == OMPC_REDUCTION_inscan && | ||||||||
15606 | (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() != OMPD_for && | ||||||||
15607 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() != OMPD_for_simd && | ||||||||
15608 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() != OMPD_simd && | ||||||||
15609 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() != OMPD_parallel_for && | ||||||||
15610 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() != OMPD_parallel_for_simd)) { | ||||||||
15611 | Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); | ||||||||
15612 | return nullptr; | ||||||||
15613 | } | ||||||||
15614 | |||||||||
15615 | ReductionData RD(VarList.size(), Modifier); | ||||||||
15616 | if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), OMPC_reduction, VarList, | ||||||||
15617 | StartLoc, LParenLoc, ColonLoc, EndLoc, | ||||||||
15618 | ReductionIdScopeSpec, ReductionId, | ||||||||
15619 | UnresolvedReductions, RD)) | ||||||||
15620 | return nullptr; | ||||||||
15621 | |||||||||
15622 | return OMPReductionClause::Create( | ||||||||
15623 | Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier, | ||||||||
15624 | RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, | ||||||||
15625 | RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps, | ||||||||
15626 | RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems, | ||||||||
15627 | buildPreInits(Context, RD.ExprCaptures), | ||||||||
15628 | buildPostUpdate(*this, RD.ExprPostUpdates)); | ||||||||
15629 | } | ||||||||
15630 | |||||||||
15631 | OMPClause *Sema::ActOnOpenMPTaskReductionClause( | ||||||||
15632 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, | ||||||||
15633 | SourceLocation ColonLoc, SourceLocation EndLoc, | ||||||||
15634 | CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, | ||||||||
15635 | ArrayRef<Expr *> UnresolvedReductions) { | ||||||||
15636 | ReductionData RD(VarList.size()); | ||||||||
15637 | if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), OMPC_task_reduction, VarList, | ||||||||
15638 | StartLoc, LParenLoc, ColonLoc, EndLoc, | ||||||||
15639 | ReductionIdScopeSpec, ReductionId, | ||||||||
15640 | UnresolvedReductions, RD)) | ||||||||
15641 | return nullptr; | ||||||||
15642 | |||||||||
15643 | return OMPTaskReductionClause::Create( | ||||||||
15644 | Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, | ||||||||
15645 | ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, | ||||||||
15646 | RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, | ||||||||
15647 | buildPreInits(Context, RD.ExprCaptures), | ||||||||
15648 | buildPostUpdate(*this, RD.ExprPostUpdates)); | ||||||||
15649 | } | ||||||||
15650 | |||||||||
15651 | OMPClause *Sema::ActOnOpenMPInReductionClause( | ||||||||
15652 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, | ||||||||
15653 | SourceLocation ColonLoc, SourceLocation EndLoc, | ||||||||
15654 | CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, | ||||||||
15655 | ArrayRef<Expr *> UnresolvedReductions) { | ||||||||
15656 | ReductionData RD(VarList.size()); | ||||||||
15657 | if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), OMPC_in_reduction, VarList, | ||||||||
15658 | StartLoc, LParenLoc, ColonLoc, EndLoc, | ||||||||
15659 | ReductionIdScopeSpec, ReductionId, | ||||||||
15660 | UnresolvedReductions, RD)) | ||||||||
15661 | return nullptr; | ||||||||
15662 | |||||||||
15663 | return OMPInReductionClause::Create( | ||||||||
15664 | Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, | ||||||||
15665 | ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, | ||||||||
15666 | RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, | ||||||||
15667 | buildPreInits(Context, RD.ExprCaptures), | ||||||||
15668 | buildPostUpdate(*this, RD.ExprPostUpdates)); | ||||||||
15669 | } | ||||||||
15670 | |||||||||
15671 | bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, | ||||||||
15672 | SourceLocation LinLoc) { | ||||||||
15673 | if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || | ||||||||
15674 | LinKind == OMPC_LINEAR_unknown) { | ||||||||
15675 | Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; | ||||||||
15676 | return true; | ||||||||
15677 | } | ||||||||
15678 | return false; | ||||||||
15679 | } | ||||||||
15680 | |||||||||
15681 | bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, | ||||||||
15682 | OpenMPLinearClauseKind LinKind, QualType Type, | ||||||||
15683 | bool IsDeclareSimd) { | ||||||||
15684 | const auto *VD = dyn_cast_or_null<VarDecl>(D); | ||||||||
15685 | // A variable must not have an incomplete type or a reference type. | ||||||||
15686 | if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) | ||||||||
15687 | return true; | ||||||||
15688 | if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && | ||||||||
15689 | !Type->isReferenceType()) { | ||||||||
15690 | Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) | ||||||||
15691 | << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); | ||||||||
15692 | return true; | ||||||||
15693 | } | ||||||||
15694 | Type = Type.getNonReferenceType(); | ||||||||
15695 | |||||||||
15696 | // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] | ||||||||
15697 | // A variable that is privatized must not have a const-qualified type | ||||||||
15698 | // unless it is of class type with a mutable member. This restriction does | ||||||||
15699 | // not apply to the firstprivate clause, nor to the linear clause on | ||||||||
15700 | // declarative directives (like declare simd). | ||||||||
15701 | if (!IsDeclareSimd && | ||||||||
15702 | rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) | ||||||||
15703 | return true; | ||||||||
15704 | |||||||||
15705 | // A list item must be of integral or pointer type. | ||||||||
15706 | Type = Type.getUnqualifiedType().getCanonicalType(); | ||||||||
15707 | const auto *Ty = Type.getTypePtrOrNull(); | ||||||||
15708 | if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && | ||||||||
15709 | !Ty->isIntegralType(Context) && !Ty->isPointerType())) { | ||||||||
15710 | Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; | ||||||||
15711 | if (D) { | ||||||||
15712 | bool IsDecl = | ||||||||
15713 | !VD || | ||||||||
15714 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||||||
15715 | Diag(D->getLocation(), | ||||||||
15716 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||||
15717 | << D; | ||||||||
15718 | } | ||||||||
15719 | return true; | ||||||||
15720 | } | ||||||||
15721 | return false; | ||||||||
15722 | } | ||||||||
15723 | |||||||||
15724 | OMPClause *Sema::ActOnOpenMPLinearClause( | ||||||||
15725 | ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, | ||||||||
15726 | SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, | ||||||||
15727 | SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { | ||||||||
15728 | SmallVector<Expr *, 8> Vars; | ||||||||
15729 | SmallVector<Expr *, 8> Privates; | ||||||||
15730 | SmallVector<Expr *, 8> Inits; | ||||||||
15731 | SmallVector<Decl *, 4> ExprCaptures; | ||||||||
15732 | SmallVector<Expr *, 4> ExprPostUpdates; | ||||||||
15733 | if (CheckOpenMPLinearModifier(LinKind, LinLoc)) | ||||||||
15734 | LinKind = OMPC_LINEAR_val; | ||||||||
15735 | for (Expr *RefExpr : VarList) { | ||||||||
15736 | 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.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 15736, __PRETTY_FUNCTION__)); | ||||||||
15737 | SourceLocation ELoc; | ||||||||
15738 | SourceRange ERange; | ||||||||
15739 | Expr *SimpleRefExpr = RefExpr; | ||||||||
15740 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||||||
15741 | if (Res.second) { | ||||||||
15742 | // It will be analyzed later. | ||||||||
15743 | Vars.push_back(RefExpr); | ||||||||
15744 | Privates.push_back(nullptr); | ||||||||
15745 | Inits.push_back(nullptr); | ||||||||
15746 | } | ||||||||
15747 | ValueDecl *D = Res.first; | ||||||||
15748 | if (!D) | ||||||||
15749 | continue; | ||||||||
15750 | |||||||||
15751 | QualType Type = D->getType(); | ||||||||
15752 | auto *VD = dyn_cast<VarDecl>(D); | ||||||||
15753 | |||||||||
15754 | // OpenMP [2.14.3.7, linear clause] | ||||||||
15755 | // A list-item cannot appear in more than one linear clause. | ||||||||
15756 | // A list-item that appears in a linear clause cannot appear in any | ||||||||
15757 | // other data-sharing attribute clause. | ||||||||
15758 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); | ||||||||
15759 | if (DVar.RefExpr) { | ||||||||
15760 | Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) | ||||||||
15761 | << getOpenMPClauseName(OMPC_linear); | ||||||||
15762 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||||
15763 | continue; | ||||||||
15764 | } | ||||||||
15765 | |||||||||
15766 | if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) | ||||||||
15767 | continue; | ||||||||
15768 | Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); | ||||||||
15769 | |||||||||
15770 | // Build private copy of original var. | ||||||||
15771 | VarDecl *Private = | ||||||||
15772 | buildVarDecl(*this, ELoc, Type, D->getName(), | ||||||||
15773 | D->hasAttrs() ? &D->getAttrs() : nullptr, | ||||||||
15774 | VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); | ||||||||
15775 | DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); | ||||||||
15776 | // Build var to save initial value. | ||||||||
15777 | VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); | ||||||||
15778 | Expr *InitExpr; | ||||||||
15779 | DeclRefExpr *Ref = nullptr; | ||||||||
15780 | if (!VD && !CurContext->isDependentContext()) { | ||||||||
15781 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); | ||||||||
15782 | if (!isOpenMPCapturedDecl(D)) { | ||||||||
15783 | ExprCaptures.push_back(Ref->getDecl()); | ||||||||
15784 | if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { | ||||||||
15785 | ExprResult RefRes = DefaultLvalueConversion(Ref); | ||||||||
15786 | if (!RefRes.isUsable()) | ||||||||
15787 | continue; | ||||||||
15788 | ExprResult PostUpdateRes = | ||||||||
15789 | BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurScope(), ELoc, BO_Assign, | ||||||||
15790 | SimpleRefExpr, RefRes.get()); | ||||||||
15791 | if (!PostUpdateRes.isUsable()) | ||||||||
15792 | continue; | ||||||||
15793 | ExprPostUpdates.push_back( | ||||||||
15794 | IgnoredValueConversions(PostUpdateRes.get()).get()); | ||||||||
15795 | } | ||||||||
15796 | } | ||||||||
15797 | } | ||||||||
15798 | if (LinKind == OMPC_LINEAR_uval) | ||||||||
15799 | InitExpr = VD ? VD->getInit() : SimpleRefExpr; | ||||||||
15800 | else | ||||||||
15801 | InitExpr = VD ? SimpleRefExpr : Ref; | ||||||||
15802 | AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), | ||||||||
15803 | /*DirectInit=*/false); | ||||||||
15804 | DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); | ||||||||
15805 | |||||||||
15806 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); | ||||||||
15807 | Vars.push_back((VD || CurContext->isDependentContext()) | ||||||||
15808 | ? RefExpr->IgnoreParens() | ||||||||
15809 | : Ref); | ||||||||
15810 | Privates.push_back(PrivateRef); | ||||||||
15811 | Inits.push_back(InitRef); | ||||||||
15812 | } | ||||||||
15813 | |||||||||
15814 | if (Vars.empty()) | ||||||||
15815 | return nullptr; | ||||||||
15816 | |||||||||
15817 | Expr *StepExpr = Step; | ||||||||
15818 | Expr *CalcStepExpr = nullptr; | ||||||||
15819 | if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && | ||||||||
15820 | !Step->isInstantiationDependent() && | ||||||||
15821 | !Step->containsUnexpandedParameterPack()) { | ||||||||
15822 | SourceLocation StepLoc = Step->getBeginLoc(); | ||||||||
15823 | ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); | ||||||||
15824 | if (Val.isInvalid()) | ||||||||
15825 | return nullptr; | ||||||||
15826 | StepExpr = Val.get(); | ||||||||
15827 | |||||||||
15828 | // Build var to save the step value. | ||||||||
15829 | VarDecl *SaveVar = | ||||||||
15830 | buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); | ||||||||
15831 | ExprResult SaveRef = | ||||||||
15832 | buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); | ||||||||
15833 | ExprResult CalcStep = | ||||||||
15834 | BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); | ||||||||
15835 | CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); | ||||||||
15836 | |||||||||
15837 | // Warn about zero linear step (it would be probably better specified as | ||||||||
15838 | // making corresponding variables 'const'). | ||||||||
15839 | if (Optional<llvm::APSInt> Result = | ||||||||
15840 | StepExpr->getIntegerConstantExpr(Context)) { | ||||||||
15841 | if (!Result->isNegative() && !Result->isStrictlyPositive()) | ||||||||
15842 | Diag(StepLoc, diag::warn_omp_linear_step_zero) | ||||||||
15843 | << Vars[0] << (Vars.size() > 1); | ||||||||
15844 | } else if (CalcStep.isUsable()) { | ||||||||
15845 | // Calculate the step beforehand instead of doing this on each iteration. | ||||||||
15846 | // (This is not used if the number of iterations may be kfold-ed). | ||||||||
15847 | CalcStepExpr = CalcStep.get(); | ||||||||
15848 | } | ||||||||
15849 | } | ||||||||
15850 | |||||||||
15851 | return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, | ||||||||
15852 | ColonLoc, EndLoc, Vars, Privates, Inits, | ||||||||
15853 | StepExpr, CalcStepExpr, | ||||||||
15854 | buildPreInits(Context, ExprCaptures), | ||||||||
15855 | buildPostUpdate(*this, ExprPostUpdates)); | ||||||||
15856 | } | ||||||||
15857 | |||||||||
15858 | static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, | ||||||||
15859 | Expr *NumIterations, Sema &SemaRef, | ||||||||
15860 | Scope *S, DSAStackTy *Stack) { | ||||||||
15861 | // Walk the vars and build update/final expressions for the CodeGen. | ||||||||
15862 | SmallVector<Expr *, 8> Updates; | ||||||||
15863 | SmallVector<Expr *, 8> Finals; | ||||||||
15864 | SmallVector<Expr *, 8> UsedExprs; | ||||||||
15865 | Expr *Step = Clause.getStep(); | ||||||||
15866 | Expr *CalcStep = Clause.getCalcStep(); | ||||||||
15867 | // OpenMP [2.14.3.7, linear clause] | ||||||||
15868 | // If linear-step is not specified it is assumed to be 1. | ||||||||
15869 | if (!Step) | ||||||||
15870 | Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); | ||||||||
15871 | else if (CalcStep) | ||||||||
15872 | Step = cast<BinaryOperator>(CalcStep)->getLHS(); | ||||||||
15873 | bool HasErrors = false; | ||||||||
15874 | auto CurInit = Clause.inits().begin(); | ||||||||
15875 | auto CurPrivate = Clause.privates().begin(); | ||||||||
15876 | OpenMPLinearClauseKind LinKind = Clause.getModifier(); | ||||||||
15877 | for (Expr *RefExpr : Clause.varlists()) { | ||||||||
15878 | SourceLocation ELoc; | ||||||||
15879 | SourceRange ERange; | ||||||||
15880 | Expr *SimpleRefExpr = RefExpr; | ||||||||
15881 | auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); | ||||||||
15882 | ValueDecl *D = Res.first; | ||||||||
15883 | if (Res.second || !D) { | ||||||||
15884 | Updates.push_back(nullptr); | ||||||||
15885 | Finals.push_back(nullptr); | ||||||||
15886 | HasErrors = true; | ||||||||
15887 | continue; | ||||||||
15888 | } | ||||||||
15889 | auto &&Info = Stack->isLoopControlVariable(D); | ||||||||
15890 | // OpenMP [2.15.11, distribute simd Construct] | ||||||||
15891 | // A list item may not appear in a linear clause, unless it is the loop | ||||||||
15892 | // iteration variable. | ||||||||
15893 | if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && | ||||||||
15894 | isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { | ||||||||
15895 | SemaRef.Diag(ELoc, | ||||||||
15896 | diag::err_omp_linear_distribute_var_non_loop_iteration); | ||||||||
15897 | Updates.push_back(nullptr); | ||||||||
15898 | Finals.push_back(nullptr); | ||||||||
15899 | HasErrors = true; | ||||||||
15900 | continue; | ||||||||
15901 | } | ||||||||
15902 | Expr *InitExpr = *CurInit; | ||||||||
15903 | |||||||||
15904 | // Build privatized reference to the current linear var. | ||||||||
15905 | auto *DE = cast<DeclRefExpr>(SimpleRefExpr); | ||||||||
15906 | Expr *CapturedRef; | ||||||||
15907 | if (LinKind == OMPC_LINEAR_uval) | ||||||||
15908 | CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); | ||||||||
15909 | else | ||||||||
15910 | CapturedRef = | ||||||||
15911 | buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), | ||||||||
15912 | DE->getType().getUnqualifiedType(), DE->getExprLoc(), | ||||||||
15913 | /*RefersToCapture=*/true); | ||||||||
15914 | |||||||||
15915 | // Build update: Var = InitExpr + IV * Step | ||||||||
15916 | ExprResult Update; | ||||||||
15917 | if (!Info.first) | ||||||||
15918 | Update = buildCounterUpdate( | ||||||||
15919 | SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, | ||||||||
15920 | /*Subtract=*/false, /*IsNonRectangularLB=*/false); | ||||||||
15921 | else | ||||||||
15922 | Update = *CurPrivate; | ||||||||
15923 | Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), | ||||||||
15924 | /*DiscardedValue*/ false); | ||||||||
15925 | |||||||||
15926 | // Build final: Var = InitExpr + NumIterations * Step | ||||||||
15927 | ExprResult Final; | ||||||||
15928 | if (!Info.first) | ||||||||
15929 | Final = | ||||||||
15930 | buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, | ||||||||
15931 | InitExpr, NumIterations, Step, /*Subtract=*/false, | ||||||||
15932 | /*IsNonRectangularLB=*/false); | ||||||||
15933 | else | ||||||||
15934 | Final = *CurPrivate; | ||||||||
15935 | Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), | ||||||||
15936 | /*DiscardedValue*/ false); | ||||||||
15937 | |||||||||
15938 | if (!Update.isUsable() || !Final.isUsable()) { | ||||||||
15939 | Updates.push_back(nullptr); | ||||||||
15940 | Finals.push_back(nullptr); | ||||||||
15941 | UsedExprs.push_back(nullptr); | ||||||||
15942 | HasErrors = true; | ||||||||
15943 | } else { | ||||||||
15944 | Updates.push_back(Update.get()); | ||||||||
15945 | Finals.push_back(Final.get()); | ||||||||
15946 | if (!Info.first) | ||||||||
15947 | UsedExprs.push_back(SimpleRefExpr); | ||||||||
15948 | } | ||||||||
15949 | ++CurInit; | ||||||||
15950 | ++CurPrivate; | ||||||||
15951 | } | ||||||||
15952 | if (Expr *S = Clause.getStep()) | ||||||||
15953 | UsedExprs.push_back(S); | ||||||||
15954 | // Fill the remaining part with the nullptr. | ||||||||
15955 | UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); | ||||||||
15956 | Clause.setUpdates(Updates); | ||||||||
15957 | Clause.setFinals(Finals); | ||||||||
15958 | Clause.setUsedExprs(UsedExprs); | ||||||||
15959 | return HasErrors; | ||||||||
15960 | } | ||||||||
15961 | |||||||||
15962 | OMPClause *Sema::ActOnOpenMPAlignedClause( | ||||||||
15963 | ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, | ||||||||
15964 | SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { | ||||||||
15965 | SmallVector<Expr *, 8> Vars; | ||||||||
15966 | for (Expr *RefExpr : VarList) { | ||||||||
15967 | 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.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 15967, __PRETTY_FUNCTION__)); | ||||||||
15968 | SourceLocation ELoc; | ||||||||
15969 | SourceRange ERange; | ||||||||
15970 | Expr *SimpleRefExpr = RefExpr; | ||||||||
15971 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||||||
15972 | if (Res.second) { | ||||||||
15973 | // It will be analyzed later. | ||||||||
15974 | Vars.push_back(RefExpr); | ||||||||
15975 | } | ||||||||
15976 | ValueDecl *D = Res.first; | ||||||||
15977 | if (!D) | ||||||||
15978 | continue; | ||||||||
15979 | |||||||||
15980 | QualType QType = D->getType(); | ||||||||
15981 | auto *VD = dyn_cast<VarDecl>(D); | ||||||||
15982 | |||||||||
15983 | // OpenMP [2.8.1, simd construct, Restrictions] | ||||||||
15984 | // The type of list items appearing in the aligned clause must be | ||||||||
15985 | // array, pointer, reference to array, or reference to pointer. | ||||||||
15986 | QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); | ||||||||
15987 | const Type *Ty = QType.getTypePtrOrNull(); | ||||||||
15988 | if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { | ||||||||
15989 | Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) | ||||||||
15990 | << QType << getLangOpts().CPlusPlus << ERange; | ||||||||
15991 | bool IsDecl = | ||||||||
15992 | !VD || | ||||||||
15993 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||||||
15994 | Diag(D->getLocation(), | ||||||||
15995 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||||
15996 | << D; | ||||||||
15997 | continue; | ||||||||
15998 | } | ||||||||
15999 | |||||||||
16000 | // OpenMP [2.8.1, simd construct, Restrictions] | ||||||||
16001 | // A list-item cannot appear in more than one aligned clause. | ||||||||
16002 | if (const Expr *PrevRef = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addUniqueAligned(D, SimpleRefExpr)) { | ||||||||
16003 | Diag(ELoc, diag::err_omp_used_in_clause_twice) | ||||||||
16004 | << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; | ||||||||
16005 | Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) | ||||||||
16006 | << getOpenMPClauseName(OMPC_aligned); | ||||||||
16007 | continue; | ||||||||
16008 | } | ||||||||
16009 | |||||||||
16010 | DeclRefExpr *Ref = nullptr; | ||||||||
16011 | if (!VD && isOpenMPCapturedDecl(D)) | ||||||||
16012 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); | ||||||||
16013 | Vars.push_back(DefaultFunctionArrayConversion( | ||||||||
16014 | (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) | ||||||||
16015 | .get()); | ||||||||
16016 | } | ||||||||
16017 | |||||||||
16018 | // OpenMP [2.8.1, simd construct, Description] | ||||||||
16019 | // The parameter of the aligned clause, alignment, must be a constant | ||||||||
16020 | // positive integer expression. | ||||||||
16021 | // If no optional parameter is specified, implementation-defined default | ||||||||
16022 | // alignments for SIMD instructions on the target platforms are assumed. | ||||||||
16023 | if (Alignment != nullptr) { | ||||||||
16024 | ExprResult AlignResult = | ||||||||
16025 | VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); | ||||||||
16026 | if (AlignResult.isInvalid()) | ||||||||
16027 | return nullptr; | ||||||||
16028 | Alignment = AlignResult.get(); | ||||||||
16029 | } | ||||||||
16030 | if (Vars.empty()) | ||||||||
16031 | return nullptr; | ||||||||
16032 | |||||||||
16033 | return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, | ||||||||
16034 | EndLoc, Vars, Alignment); | ||||||||
16035 | } | ||||||||
16036 | |||||||||
16037 | OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, | ||||||||
16038 | SourceLocation StartLoc, | ||||||||
16039 | SourceLocation LParenLoc, | ||||||||
16040 | SourceLocation EndLoc) { | ||||||||
16041 | SmallVector<Expr *, 8> Vars; | ||||||||
16042 | SmallVector<Expr *, 8> SrcExprs; | ||||||||
16043 | SmallVector<Expr *, 8> DstExprs; | ||||||||
16044 | SmallVector<Expr *, 8> AssignmentOps; | ||||||||
16045 | for (Expr *RefExpr : VarList) { | ||||||||
16046 | 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.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 16046, __PRETTY_FUNCTION__)); | ||||||||
16047 | if (isa<DependentScopeDeclRefExpr>(RefExpr)) { | ||||||||
16048 | // It will be analyzed later. | ||||||||
16049 | Vars.push_back(RefExpr); | ||||||||
16050 | SrcExprs.push_back(nullptr); | ||||||||
16051 | DstExprs.push_back(nullptr); | ||||||||
16052 | AssignmentOps.push_back(nullptr); | ||||||||
16053 | continue; | ||||||||
16054 | } | ||||||||
16055 | |||||||||
16056 | SourceLocation ELoc = RefExpr->getExprLoc(); | ||||||||
16057 | // OpenMP [2.1, C/C++] | ||||||||
16058 | // A list item is a variable name. | ||||||||
16059 | // OpenMP [2.14.4.1, Restrictions, p.1] | ||||||||
16060 | // A list item that appears in a copyin clause must be threadprivate. | ||||||||
16061 | auto *DE = dyn_cast<DeclRefExpr>(RefExpr); | ||||||||
16062 | if (!DE || !isa<VarDecl>(DE->getDecl())) { | ||||||||
16063 | Diag(ELoc, diag::err_omp_expected_var_name_member_expr) | ||||||||
16064 | << 0 << RefExpr->getSourceRange(); | ||||||||
16065 | continue; | ||||||||
16066 | } | ||||||||
16067 | |||||||||
16068 | Decl *D = DE->getDecl(); | ||||||||
16069 | auto *VD = cast<VarDecl>(D); | ||||||||
16070 | |||||||||
16071 | QualType Type = VD->getType(); | ||||||||
16072 | if (Type->isDependentType() || Type->isInstantiationDependentType()) { | ||||||||
16073 | // It will be analyzed later. | ||||||||
16074 | Vars.push_back(DE); | ||||||||
16075 | SrcExprs.push_back(nullptr); | ||||||||
16076 | DstExprs.push_back(nullptr); | ||||||||
16077 | AssignmentOps.push_back(nullptr); | ||||||||
16078 | continue; | ||||||||
16079 | } | ||||||||
16080 | |||||||||
16081 | // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] | ||||||||
16082 | // A list item that appears in a copyin clause must be threadprivate. | ||||||||
16083 | if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isThreadPrivate(VD)) { | ||||||||
16084 | Diag(ELoc, diag::err_omp_required_access) | ||||||||
16085 | << getOpenMPClauseName(OMPC_copyin) | ||||||||
16086 | << getOpenMPDirectiveName(OMPD_threadprivate); | ||||||||
16087 | continue; | ||||||||
16088 | } | ||||||||
16089 | |||||||||
16090 | // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] | ||||||||
16091 | // A variable of class type (or array thereof) that appears in a | ||||||||
16092 | // copyin clause requires an accessible, unambiguous copy assignment | ||||||||
16093 | // operator for the class type. | ||||||||
16094 | QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); | ||||||||
16095 | VarDecl *SrcVD = | ||||||||
16096 | buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), | ||||||||
16097 | ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); | ||||||||
16098 | DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( | ||||||||
16099 | *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); | ||||||||
16100 | VarDecl *DstVD = | ||||||||
16101 | buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", | ||||||||
16102 | VD->hasAttrs() ? &VD->getAttrs() : nullptr); | ||||||||
16103 | DeclRefExpr *PseudoDstExpr = | ||||||||
16104 | buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); | ||||||||
16105 | // For arrays generate assignment operation for single element and replace | ||||||||
16106 | // it by the original array element in CodeGen. | ||||||||
16107 | ExprResult AssignmentOp = | ||||||||
16108 | BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, | ||||||||
16109 | PseudoSrcExpr); | ||||||||
16110 | if (AssignmentOp.isInvalid()) | ||||||||
16111 | continue; | ||||||||
16112 | AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), | ||||||||
16113 | /*DiscardedValue*/ false); | ||||||||
16114 | if (AssignmentOp.isInvalid()) | ||||||||
16115 | continue; | ||||||||
16116 | |||||||||
16117 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(VD, DE, OMPC_copyin); | ||||||||
16118 | Vars.push_back(DE); | ||||||||
16119 | SrcExprs.push_back(PseudoSrcExpr); | ||||||||
16120 | DstExprs.push_back(PseudoDstExpr); | ||||||||
16121 | AssignmentOps.push_back(AssignmentOp.get()); | ||||||||
16122 | } | ||||||||
16123 | |||||||||
16124 | if (Vars.empty()) | ||||||||
16125 | return nullptr; | ||||||||
16126 | |||||||||
16127 | return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, | ||||||||
16128 | SrcExprs, DstExprs, AssignmentOps); | ||||||||
16129 | } | ||||||||
16130 | |||||||||
16131 | OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, | ||||||||
16132 | SourceLocation StartLoc, | ||||||||
16133 | SourceLocation LParenLoc, | ||||||||
16134 | SourceLocation EndLoc) { | ||||||||
16135 | SmallVector<Expr *, 8> Vars; | ||||||||
16136 | SmallVector<Expr *, 8> SrcExprs; | ||||||||
16137 | SmallVector<Expr *, 8> DstExprs; | ||||||||
16138 | SmallVector<Expr *, 8> AssignmentOps; | ||||||||
16139 | for (Expr *RefExpr : VarList) { | ||||||||
16140 | 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.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 16140, __PRETTY_FUNCTION__)); | ||||||||
16141 | SourceLocation ELoc; | ||||||||
16142 | SourceRange ERange; | ||||||||
16143 | Expr *SimpleRefExpr = RefExpr; | ||||||||
16144 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||||||
16145 | if (Res.second) { | ||||||||
16146 | // It will be analyzed later. | ||||||||
16147 | Vars.push_back(RefExpr); | ||||||||
16148 | SrcExprs.push_back(nullptr); | ||||||||
16149 | DstExprs.push_back(nullptr); | ||||||||
16150 | AssignmentOps.push_back(nullptr); | ||||||||
16151 | } | ||||||||
16152 | ValueDecl *D = Res.first; | ||||||||
16153 | if (!D) | ||||||||
16154 | continue; | ||||||||
16155 | |||||||||
16156 | QualType Type = D->getType(); | ||||||||
16157 | auto *VD = dyn_cast<VarDecl>(D); | ||||||||
16158 | |||||||||
16159 | // OpenMP [2.14.4.2, Restrictions, p.2] | ||||||||
16160 | // A list item that appears in a copyprivate clause may not appear in a | ||||||||
16161 | // private or firstprivate clause on the single construct. | ||||||||
16162 | if (!VD || !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isThreadPrivate(VD)) { | ||||||||
16163 | DSAStackTy::DSAVarData DVar = | ||||||||
16164 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); | ||||||||
16165 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && | ||||||||
16166 | DVar.RefExpr) { | ||||||||
16167 | Diag(ELoc, diag::err_omp_wrong_dsa) | ||||||||
16168 | << getOpenMPClauseName(DVar.CKind) | ||||||||
16169 | << getOpenMPClauseName(OMPC_copyprivate); | ||||||||
16170 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||||
16171 | continue; | ||||||||
16172 | } | ||||||||
16173 | |||||||||
16174 | // OpenMP [2.11.4.2, Restrictions, p.1] | ||||||||
16175 | // All list items that appear in a copyprivate clause must be either | ||||||||
16176 | // threadprivate or private in the enclosing context. | ||||||||
16177 | if (DVar.CKind == OMPC_unknown) { | ||||||||
16178 | DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getImplicitDSA(D, false); | ||||||||
16179 | if (DVar.CKind == OMPC_shared) { | ||||||||
16180 | Diag(ELoc, diag::err_omp_required_access) | ||||||||
16181 | << getOpenMPClauseName(OMPC_copyprivate) | ||||||||
16182 | << "threadprivate or private in the enclosing context"; | ||||||||
16183 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||||
16184 | continue; | ||||||||
16185 | } | ||||||||
16186 | } | ||||||||
16187 | } | ||||||||
16188 | |||||||||
16189 | // Variably modified types are not supported. | ||||||||
16190 | if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { | ||||||||
16191 | Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) | ||||||||
16192 | << getOpenMPClauseName(OMPC_copyprivate) << Type | ||||||||
16193 | << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()); | ||||||||
16194 | bool IsDecl = | ||||||||
16195 | !VD || | ||||||||
16196 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||||||
16197 | Diag(D->getLocation(), | ||||||||
16198 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||||
16199 | << D; | ||||||||
16200 | continue; | ||||||||
16201 | } | ||||||||
16202 | |||||||||
16203 | // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] | ||||||||
16204 | // A variable of class type (or array thereof) that appears in a | ||||||||
16205 | // copyin clause requires an accessible, unambiguous copy assignment | ||||||||
16206 | // operator for the class type. | ||||||||
16207 | Type = Context.getBaseElementType(Type.getNonReferenceType()) | ||||||||
16208 | .getUnqualifiedType(); | ||||||||
16209 | VarDecl *SrcVD = | ||||||||
16210 | buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", | ||||||||
16211 | D->hasAttrs() ? &D->getAttrs() : nullptr); | ||||||||
16212 | DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); | ||||||||
16213 | VarDecl *DstVD = | ||||||||
16214 | buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", | ||||||||
16215 | D->hasAttrs() ? &D->getAttrs() : nullptr); | ||||||||
16216 | DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); | ||||||||
16217 | ExprResult AssignmentOp = BuildBinOp( | ||||||||
16218 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); | ||||||||
16219 | if (AssignmentOp.isInvalid()) | ||||||||
16220 | continue; | ||||||||
16221 | AssignmentOp = | ||||||||
16222 | ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); | ||||||||
16223 | if (AssignmentOp.isInvalid()) | ||||||||
16224 | continue; | ||||||||
16225 | |||||||||
16226 | // No need to mark vars as copyprivate, they are already threadprivate or | ||||||||
16227 | // implicitly private. | ||||||||
16228 | assert(VD || isOpenMPCapturedDecl(D))((VD || isOpenMPCapturedDecl(D)) ? static_cast<void> (0 ) : __assert_fail ("VD || isOpenMPCapturedDecl(D)", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 16228, __PRETTY_FUNCTION__)); | ||||||||
16229 | Vars.push_back( | ||||||||
16230 | VD ? RefExpr->IgnoreParens() | ||||||||
16231 | : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); | ||||||||
16232 | SrcExprs.push_back(PseudoSrcExpr); | ||||||||
16233 | DstExprs.push_back(PseudoDstExpr); | ||||||||
16234 | AssignmentOps.push_back(AssignmentOp.get()); | ||||||||
16235 | } | ||||||||
16236 | |||||||||
16237 | if (Vars.empty()) | ||||||||
16238 | return nullptr; | ||||||||
16239 | |||||||||
16240 | return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, | ||||||||
16241 | Vars, SrcExprs, DstExprs, AssignmentOps); | ||||||||
16242 | } | ||||||||
16243 | |||||||||
16244 | OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, | ||||||||
16245 | SourceLocation StartLoc, | ||||||||
16246 | SourceLocation LParenLoc, | ||||||||
16247 | SourceLocation EndLoc) { | ||||||||
16248 | if (VarList.empty()) | ||||||||
16249 | return nullptr; | ||||||||
16250 | |||||||||
16251 | return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); | ||||||||
16252 | } | ||||||||
16253 | |||||||||
16254 | /// Tries to find omp_depend_t. type. | ||||||||
16255 | static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, | ||||||||
16256 | bool Diagnose = true) { | ||||||||
16257 | QualType OMPDependT = Stack->getOMPDependT(); | ||||||||
16258 | if (!OMPDependT.isNull()) | ||||||||
16259 | return true; | ||||||||
16260 | IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t"); | ||||||||
16261 | ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); | ||||||||
16262 | if (!PT.getAsOpaquePtr() || PT.get().isNull()) { | ||||||||
16263 | if (Diagnose) | ||||||||
16264 | S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t"; | ||||||||
16265 | return false; | ||||||||
16266 | } | ||||||||
16267 | Stack->setOMPDependT(PT.get()); | ||||||||
16268 | return true; | ||||||||
16269 | } | ||||||||
16270 | |||||||||
16271 | OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, | ||||||||
16272 | SourceLocation LParenLoc, | ||||||||
16273 | SourceLocation EndLoc) { | ||||||||
16274 | if (!Depobj) | ||||||||
16275 | return nullptr; | ||||||||
16276 | |||||||||
16277 | bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )); | ||||||||
16278 | |||||||||
16279 | // OpenMP 5.0, 2.17.10.1 depobj Construct | ||||||||
16280 | // depobj is an lvalue expression of type omp_depend_t. | ||||||||
16281 | if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() && | ||||||||
16282 | !Depobj->isInstantiationDependent() && | ||||||||
16283 | !Depobj->containsUnexpandedParameterPack() && | ||||||||
16284 | (OMPDependTFound && | ||||||||
16285 | !Context.typesAreCompatible(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPDependT(), Depobj->getType(), | ||||||||
16286 | /*CompareUnqualified=*/true))) { | ||||||||
16287 | Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) | ||||||||
16288 | << 0 << Depobj->getType() << Depobj->getSourceRange(); | ||||||||
16289 | } | ||||||||
16290 | |||||||||
16291 | if (!Depobj->isLValue()) { | ||||||||
16292 | Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) | ||||||||
16293 | << 1 << Depobj->getSourceRange(); | ||||||||
16294 | } | ||||||||
16295 | |||||||||
16296 | return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj); | ||||||||
16297 | } | ||||||||
16298 | |||||||||
16299 | OMPClause * | ||||||||
16300 | Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, | ||||||||
16301 | SourceLocation DepLoc, SourceLocation ColonLoc, | ||||||||
16302 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, | ||||||||
16303 | SourceLocation LParenLoc, SourceLocation EndLoc) { | ||||||||
16304 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() == OMPD_ordered && | ||||||||
16305 | DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { | ||||||||
16306 | Diag(DepLoc, diag::err_omp_unexpected_clause_value) | ||||||||
16307 | << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); | ||||||||
16308 | return nullptr; | ||||||||
16309 | } | ||||||||
16310 | if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() != OMPD_ordered || | ||||||||
16311 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() == OMPD_depobj) && | ||||||||
16312 | (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || | ||||||||
16313 | DepKind == OMPC_DEPEND_sink || | ||||||||
16314 | ((LangOpts.OpenMP < 50 || | ||||||||
16315 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() == OMPD_depobj) && | ||||||||
16316 | DepKind == OMPC_DEPEND_depobj))) { | ||||||||
16317 | SmallVector<unsigned, 3> Except; | ||||||||
16318 | Except.push_back(OMPC_DEPEND_source); | ||||||||
16319 | Except.push_back(OMPC_DEPEND_sink); | ||||||||
16320 | if (LangOpts.OpenMP < 50 || DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() == OMPD_depobj) | ||||||||
16321 | Except.push_back(OMPC_DEPEND_depobj); | ||||||||
16322 | std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier) | ||||||||
16323 | ? "depend modifier(iterator) or " | ||||||||
16324 | : ""; | ||||||||
16325 | Diag(DepLoc, diag::err_omp_unexpected_clause_value) | ||||||||
16326 | << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0, | ||||||||
16327 | /*Last=*/OMPC_DEPEND_unknown, | ||||||||
16328 | Except) | ||||||||
16329 | << getOpenMPClauseName(OMPC_depend); | ||||||||
16330 | return nullptr; | ||||||||
16331 | } | ||||||||
16332 | if (DepModifier && | ||||||||
16333 | (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) { | ||||||||
16334 | Diag(DepModifier->getExprLoc(), | ||||||||
16335 | diag::err_omp_depend_sink_source_with_modifier); | ||||||||
16336 | return nullptr; | ||||||||
16337 | } | ||||||||
16338 | if (DepModifier && | ||||||||
16339 | !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator)) | ||||||||
16340 | Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator); | ||||||||
16341 | |||||||||
16342 | SmallVector<Expr *, 8> Vars; | ||||||||
16343 | DSAStackTy::OperatorOffsetTy OpsOffs; | ||||||||
16344 | llvm::APSInt DepCounter(/*BitWidth=*/32); | ||||||||
16345 | llvm::APSInt TotalDepCount(/*BitWidth=*/32); | ||||||||
16346 | if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { | ||||||||
16347 | if (const Expr *OrderedCountExpr = | ||||||||
16348 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentOrderedRegionParam().first) { | ||||||||
16349 | TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); | ||||||||
16350 | TotalDepCount.setIsUnsigned(/*Val=*/true); | ||||||||
16351 | } | ||||||||
16352 | } | ||||||||
16353 | for (Expr *RefExpr : VarList) { | ||||||||
16354 | 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.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 16354, __PRETTY_FUNCTION__)); | ||||||||
16355 | if (isa<DependentScopeDeclRefExpr>(RefExpr)) { | ||||||||
16356 | // It will be analyzed later. | ||||||||
16357 | Vars.push_back(RefExpr); | ||||||||
16358 | continue; | ||||||||
16359 | } | ||||||||
16360 | |||||||||
16361 | SourceLocation ELoc = RefExpr->getExprLoc(); | ||||||||
16362 | Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); | ||||||||
16363 | if (DepKind == OMPC_DEPEND_sink) { | ||||||||
16364 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentOrderedRegionParam().first && | ||||||||
16365 | DepCounter >= TotalDepCount) { | ||||||||
16366 | Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); | ||||||||
16367 | continue; | ||||||||
16368 | } | ||||||||
16369 | ++DepCounter; | ||||||||
16370 | // OpenMP [2.13.9, Summary] | ||||||||
16371 | // depend(dependence-type : vec), where dependence-type is: | ||||||||
16372 | // 'sink' and where vec is the iteration vector, which has the form: | ||||||||
16373 | // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] | ||||||||
16374 | // where n is the value specified by the ordered clause in the loop | ||||||||
16375 | // directive, xi denotes the loop iteration variable of the i-th nested | ||||||||
16376 | // loop associated with the loop directive, and di is a constant | ||||||||
16377 | // non-negative integer. | ||||||||
16378 | if (CurContext->isDependentContext()) { | ||||||||
16379 | // It will be analyzed later. | ||||||||
16380 | Vars.push_back(RefExpr); | ||||||||
16381 | continue; | ||||||||
16382 | } | ||||||||
16383 | SimpleExpr = SimpleExpr->IgnoreImplicit(); | ||||||||
16384 | OverloadedOperatorKind OOK = OO_None; | ||||||||
16385 | SourceLocation OOLoc; | ||||||||
16386 | Expr *LHS = SimpleExpr; | ||||||||
16387 | Expr *RHS = nullptr; | ||||||||
16388 | if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { | ||||||||
16389 | OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); | ||||||||
16390 | OOLoc = BO->getOperatorLoc(); | ||||||||
16391 | LHS = BO->getLHS()->IgnoreParenImpCasts(); | ||||||||
16392 | RHS = BO->getRHS()->IgnoreParenImpCasts(); | ||||||||
16393 | } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { | ||||||||
16394 | OOK = OCE->getOperator(); | ||||||||
16395 | OOLoc = OCE->getOperatorLoc(); | ||||||||
16396 | LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); | ||||||||
16397 | RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); | ||||||||
16398 | } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { | ||||||||
16399 | OOK = MCE->getMethodDecl() | ||||||||
16400 | ->getNameInfo() | ||||||||
16401 | .getName() | ||||||||
16402 | .getCXXOverloadedOperator(); | ||||||||
16403 | OOLoc = MCE->getCallee()->getExprLoc(); | ||||||||
16404 | LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); | ||||||||
16405 | RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); | ||||||||
16406 | } | ||||||||
16407 | SourceLocation ELoc; | ||||||||
16408 | SourceRange ERange; | ||||||||
16409 | auto Res = getPrivateItem(*this, LHS, ELoc, ERange); | ||||||||
16410 | if (Res.second) { | ||||||||
16411 | // It will be analyzed later. | ||||||||
16412 | Vars.push_back(RefExpr); | ||||||||
16413 | } | ||||||||
16414 | ValueDecl *D = Res.first; | ||||||||
16415 | if (!D) | ||||||||
16416 | continue; | ||||||||
16417 | |||||||||
16418 | if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { | ||||||||
16419 | Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); | ||||||||
16420 | continue; | ||||||||
16421 | } | ||||||||
16422 | if (RHS) { | ||||||||
16423 | ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( | ||||||||
16424 | RHS, OMPC_depend, /*StrictlyPositive=*/false); | ||||||||
16425 | if (RHSRes.isInvalid()) | ||||||||
16426 | continue; | ||||||||
16427 | } | ||||||||
16428 | if (!CurContext->isDependentContext() && | ||||||||
16429 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentOrderedRegionParam().first && | ||||||||
16430 | DepCounter != DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isParentLoopControlVariable(D).first) { | ||||||||
16431 | const ValueDecl *VD = | ||||||||
16432 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentLoopControlVariable(DepCounter.getZExtValue()); | ||||||||
16433 | if (VD) | ||||||||
16434 | Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) | ||||||||
16435 | << 1 << VD; | ||||||||
16436 | else | ||||||||
16437 | Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; | ||||||||
16438 | continue; | ||||||||
16439 | } | ||||||||
16440 | OpsOffs.emplace_back(RHS, OOK); | ||||||||
16441 | } else { | ||||||||
16442 | bool OMPDependTFound = LangOpts.OpenMP >= 50; | ||||||||
16443 | if (OMPDependTFound) | ||||||||
16444 | OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||||
16445 | DepKind == OMPC_DEPEND_depobj); | ||||||||
16446 | if (DepKind == OMPC_DEPEND_depobj) { | ||||||||
16447 | // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ | ||||||||
16448 | // List items used in depend clauses with the depobj dependence type | ||||||||
16449 | // must be expressions of the omp_depend_t type. | ||||||||
16450 | if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && | ||||||||
16451 | !RefExpr->isInstantiationDependent() && | ||||||||
16452 | !RefExpr->containsUnexpandedParameterPack() && | ||||||||
16453 | (OMPDependTFound && | ||||||||
16454 | !Context.hasSameUnqualifiedType(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPDependT(), | ||||||||
16455 | RefExpr->getType()))) { | ||||||||
16456 | Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) | ||||||||
16457 | << 0 << RefExpr->getType() << RefExpr->getSourceRange(); | ||||||||
16458 | continue; | ||||||||
16459 | } | ||||||||
16460 | if (!RefExpr->isLValue()) { | ||||||||
16461 | Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) | ||||||||
16462 | << 1 << RefExpr->getType() << RefExpr->getSourceRange(); | ||||||||
16463 | continue; | ||||||||
16464 | } | ||||||||
16465 | } else { | ||||||||
16466 | // OpenMP 5.0 [2.17.11, Restrictions] | ||||||||
16467 | // List items used in depend clauses cannot be zero-length array | ||||||||
16468 | // sections. | ||||||||
16469 | QualType ExprTy = RefExpr->getType().getNonReferenceType(); | ||||||||
16470 | const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); | ||||||||
16471 | if (OASE) { | ||||||||
16472 | QualType BaseType = | ||||||||
16473 | OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); | ||||||||
16474 | if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) | ||||||||
16475 | ExprTy = ATy->getElementType(); | ||||||||
16476 | else | ||||||||
16477 | ExprTy = BaseType->getPointeeType(); | ||||||||
16478 | ExprTy = ExprTy.getNonReferenceType(); | ||||||||
16479 | const Expr *Length = OASE->getLength(); | ||||||||
16480 | Expr::EvalResult Result; | ||||||||
16481 | if (Length && !Length->isValueDependent() && | ||||||||
16482 | Length->EvaluateAsInt(Result, Context) && | ||||||||
16483 | Result.Val.getInt().isNullValue()) { | ||||||||
16484 | Diag(ELoc, | ||||||||
16485 | diag::err_omp_depend_zero_length_array_section_not_allowed) | ||||||||
16486 | << SimpleExpr->getSourceRange(); | ||||||||
16487 | continue; | ||||||||
16488 | } | ||||||||
16489 | } | ||||||||
16490 | |||||||||
16491 | // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ | ||||||||
16492 | // List items used in depend clauses with the in, out, inout or | ||||||||
16493 | // mutexinoutset dependence types cannot be expressions of the | ||||||||
16494 | // omp_depend_t type. | ||||||||
16495 | if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && | ||||||||
16496 | !RefExpr->isInstantiationDependent() && | ||||||||
16497 | !RefExpr->containsUnexpandedParameterPack() && | ||||||||
16498 | (OMPDependTFound && | ||||||||
16499 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) { | ||||||||
16500 | Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) | ||||||||
16501 | << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1 | ||||||||
16502 | << RefExpr->getSourceRange(); | ||||||||
16503 | continue; | ||||||||
16504 | } | ||||||||
16505 | |||||||||
16506 | auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); | ||||||||
16507 | if (!RefExpr->IgnoreParenImpCasts()->isLValue() || | ||||||||
16508 | (ASE && !ASE->getBase()->isTypeDependent() && | ||||||||
16509 | !ASE->getBase() | ||||||||
16510 | ->getType() | ||||||||
16511 | .getNonReferenceType() | ||||||||
16512 | ->isPointerType() && | ||||||||
16513 | !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { | ||||||||
16514 | Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) | ||||||||
16515 | << (LangOpts.OpenMP >= 50 ? 1 : 0) | ||||||||
16516 | << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); | ||||||||
16517 | continue; | ||||||||
16518 | } | ||||||||
16519 | |||||||||
16520 | ExprResult Res; | ||||||||
16521 | { | ||||||||
16522 | Sema::TentativeAnalysisScope Trap(*this); | ||||||||
16523 | Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, | ||||||||
16524 | RefExpr->IgnoreParenImpCasts()); | ||||||||
16525 | } | ||||||||
16526 | if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && | ||||||||
16527 | !isa<OMPArrayShapingExpr>(SimpleExpr)) { | ||||||||
16528 | Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) | ||||||||
16529 | << (LangOpts.OpenMP >= 50 ? 1 : 0) | ||||||||
16530 | << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); | ||||||||
16531 | continue; | ||||||||
16532 | } | ||||||||
16533 | } | ||||||||
16534 | } | ||||||||
16535 | Vars.push_back(RefExpr->IgnoreParenImpCasts()); | ||||||||
16536 | } | ||||||||
16537 | |||||||||
16538 | if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && | ||||||||
16539 | TotalDepCount > VarList.size() && | ||||||||
16540 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentOrderedRegionParam().first && | ||||||||
16541 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentLoopControlVariable(VarList.size() + 1)) { | ||||||||
16542 | Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) | ||||||||
16543 | << 1 << DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentLoopControlVariable(VarList.size() + 1); | ||||||||
16544 | } | ||||||||
16545 | if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && | ||||||||
16546 | Vars.empty()) | ||||||||
16547 | return nullptr; | ||||||||
16548 | |||||||||
16549 | auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, | ||||||||
16550 | DepModifier, DepKind, DepLoc, ColonLoc, | ||||||||
16551 | Vars, TotalDepCount.getZExtValue()); | ||||||||
16552 | if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && | ||||||||
16553 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isParentOrderedRegion()) | ||||||||
16554 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDoacrossDependClause(C, OpsOffs); | ||||||||
16555 | return C; | ||||||||
16556 | } | ||||||||
16557 | |||||||||
16558 | OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, | ||||||||
16559 | Expr *Device, SourceLocation StartLoc, | ||||||||
16560 | SourceLocation LParenLoc, | ||||||||
16561 | SourceLocation ModifierLoc, | ||||||||
16562 | SourceLocation EndLoc) { | ||||||||
16563 | assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&(((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && "Unexpected device modifier in OpenMP < 50.") ? static_cast <void> (0) : __assert_fail ("(ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && \"Unexpected device modifier in OpenMP < 50.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 16564, __PRETTY_FUNCTION__)) | ||||||||
16564 | "Unexpected device modifier in OpenMP < 50.")(((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && "Unexpected device modifier in OpenMP < 50.") ? static_cast <void> (0) : __assert_fail ("(ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && \"Unexpected device modifier in OpenMP < 50.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 16564, __PRETTY_FUNCTION__)); | ||||||||
16565 | |||||||||
16566 | bool ErrorFound = false; | ||||||||
16567 | if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) { | ||||||||
16568 | std::string Values = | ||||||||
16569 | getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown); | ||||||||
16570 | Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) | ||||||||
16571 | << Values << getOpenMPClauseName(OMPC_device); | ||||||||
16572 | ErrorFound = true; | ||||||||
16573 | } | ||||||||
16574 | |||||||||
16575 | Expr *ValExpr = Device; | ||||||||
16576 | Stmt *HelperValStmt = nullptr; | ||||||||
16577 | |||||||||
16578 | // OpenMP [2.9.1, Restrictions] | ||||||||
16579 | // The device expression must evaluate to a non-negative integer value. | ||||||||
16580 | ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, | ||||||||
16581 | /*StrictlyPositive=*/false) || | ||||||||
16582 | ErrorFound; | ||||||||
16583 | if (ErrorFound) | ||||||||
16584 | return nullptr; | ||||||||
16585 | |||||||||
16586 | OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); | ||||||||
16587 | OpenMPDirectiveKind CaptureRegion = | ||||||||
16588 | getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); | ||||||||
16589 | if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { | ||||||||
16590 | ValExpr = MakeFullExpr(ValExpr).get(); | ||||||||
16591 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; | ||||||||
16592 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); | ||||||||
16593 | HelperValStmt = buildPreInits(Context, Captures); | ||||||||
16594 | } | ||||||||
16595 | |||||||||
16596 | return new (Context) | ||||||||
16597 | OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, | ||||||||
16598 | LParenLoc, ModifierLoc, EndLoc); | ||||||||
16599 | } | ||||||||
16600 | |||||||||
16601 | static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, | ||||||||
16602 | DSAStackTy *Stack, QualType QTy, | ||||||||
16603 | bool FullCheck = true) { | ||||||||
16604 | NamedDecl *ND; | ||||||||
16605 | if (QTy->isIncompleteType(&ND)) { | ||||||||
16606 | SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; | ||||||||
16607 | return false; | ||||||||
16608 | } | ||||||||
16609 | if (FullCheck && !SemaRef.CurContext->isDependentContext() && | ||||||||
16610 | !QTy.isTriviallyCopyableType(SemaRef.Context)) | ||||||||
16611 | SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; | ||||||||
16612 | return true; | ||||||||
16613 | } | ||||||||
16614 | |||||||||
16615 | /// Return true if it can be proven that the provided array expression | ||||||||
16616 | /// (array section or array subscript) does NOT specify the whole size of the | ||||||||
16617 | /// array whose base type is \a BaseQTy. | ||||||||
16618 | static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, | ||||||||
16619 | const Expr *E, | ||||||||
16620 | QualType BaseQTy) { | ||||||||
16621 | const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); | ||||||||
16622 | |||||||||
16623 | // If this is an array subscript, it refers to the whole size if the size of | ||||||||
16624 | // the dimension is constant and equals 1. Also, an array section assumes the | ||||||||
16625 | // format of an array subscript if no colon is used. | ||||||||
16626 | if (isa<ArraySubscriptExpr>(E) || | ||||||||
16627 | (OASE && OASE->getColonLocFirst().isInvalid())) { | ||||||||
16628 | if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) | ||||||||
16629 | return ATy->getSize().getSExtValue() != 1; | ||||||||
16630 | // Size can't be evaluated statically. | ||||||||
16631 | return false; | ||||||||
16632 | } | ||||||||
16633 | |||||||||
16634 | assert(OASE && "Expecting array section if not an array subscript.")((OASE && "Expecting array section if not an array subscript." ) ? static_cast<void> (0) : __assert_fail ("OASE && \"Expecting array section if not an array subscript.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 16634, __PRETTY_FUNCTION__)); | ||||||||
16635 | const Expr *LowerBound = OASE->getLowerBound(); | ||||||||
16636 | const Expr *Length = OASE->getLength(); | ||||||||
16637 | |||||||||
16638 | // If there is a lower bound that does not evaluates to zero, we are not | ||||||||
16639 | // covering the whole dimension. | ||||||||
16640 | if (LowerBound) { | ||||||||
16641 | Expr::EvalResult Result; | ||||||||
16642 | if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) | ||||||||
16643 | return false; // Can't get the integer value as a constant. | ||||||||
16644 | |||||||||
16645 | llvm::APSInt ConstLowerBound = Result.Val.getInt(); | ||||||||
16646 | if (ConstLowerBound.getSExtValue()) | ||||||||
16647 | return true; | ||||||||
16648 | } | ||||||||
16649 | |||||||||
16650 | // If we don't have a length we covering the whole dimension. | ||||||||
16651 | if (!Length) | ||||||||
16652 | return false; | ||||||||
16653 | |||||||||
16654 | // If the base is a pointer, we don't have a way to get the size of the | ||||||||
16655 | // pointee. | ||||||||
16656 | if (BaseQTy->isPointerType()) | ||||||||
16657 | return false; | ||||||||
16658 | |||||||||
16659 | // We can only check if the length is the same as the size of the dimension | ||||||||
16660 | // if we have a constant array. | ||||||||
16661 | const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); | ||||||||
16662 | if (!CATy) | ||||||||
16663 | return false; | ||||||||
16664 | |||||||||
16665 | Expr::EvalResult Result; | ||||||||
16666 | if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) | ||||||||
16667 | return false; // Can't get the integer value as a constant. | ||||||||
16668 | |||||||||
16669 | llvm::APSInt ConstLength = Result.Val.getInt(); | ||||||||
16670 | return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); | ||||||||
16671 | } | ||||||||
16672 | |||||||||
16673 | // Return true if it can be proven that the provided array expression (array | ||||||||
16674 | // section or array subscript) does NOT specify a single element of the array | ||||||||
16675 | // whose base type is \a BaseQTy. | ||||||||
16676 | static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, | ||||||||
16677 | const Expr *E, | ||||||||
16678 | QualType BaseQTy) { | ||||||||
16679 | const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); | ||||||||
16680 | |||||||||
16681 | // An array subscript always refer to a single element. Also, an array section | ||||||||
16682 | // assumes the format of an array subscript if no colon is used. | ||||||||
16683 | if (isa<ArraySubscriptExpr>(E) || | ||||||||
16684 | (OASE && OASE->getColonLocFirst().isInvalid())) | ||||||||
16685 | return false; | ||||||||
16686 | |||||||||
16687 | assert(OASE && "Expecting array section if not an array subscript.")((OASE && "Expecting array section if not an array subscript." ) ? static_cast<void> (0) : __assert_fail ("OASE && \"Expecting array section if not an array subscript.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 16687, __PRETTY_FUNCTION__)); | ||||||||
16688 | const Expr *Length = OASE->getLength(); | ||||||||
16689 | |||||||||
16690 | // If we don't have a length we have to check if the array has unitary size | ||||||||
16691 | // for this dimension. Also, we should always expect a length if the base type | ||||||||
16692 | // is pointer. | ||||||||
16693 | if (!Length) { | ||||||||
16694 | if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) | ||||||||
16695 | return ATy->getSize().getSExtValue() != 1; | ||||||||
16696 | // We cannot assume anything. | ||||||||
16697 | return false; | ||||||||
16698 | } | ||||||||
16699 | |||||||||
16700 | // Check if the length evaluates to 1. | ||||||||
16701 | Expr::EvalResult Result; | ||||||||
16702 | if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) | ||||||||
16703 | return false; // Can't get the integer value as a constant. | ||||||||
16704 | |||||||||
16705 | llvm::APSInt ConstLength = Result.Val.getInt(); | ||||||||
16706 | return ConstLength.getSExtValue() != 1; | ||||||||
16707 | } | ||||||||
16708 | |||||||||
16709 | // The base of elements of list in a map clause have to be either: | ||||||||
16710 | // - a reference to variable or field. | ||||||||
16711 | // - a member expression. | ||||||||
16712 | // - an array expression. | ||||||||
16713 | // | ||||||||
16714 | // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the | ||||||||
16715 | // reference to 'r'. | ||||||||
16716 | // | ||||||||
16717 | // If we have: | ||||||||
16718 | // | ||||||||
16719 | // struct SS { | ||||||||
16720 | // Bla S; | ||||||||
16721 | // foo() { | ||||||||
16722 | // #pragma omp target map (S.Arr[:12]); | ||||||||
16723 | // } | ||||||||
16724 | // } | ||||||||
16725 | // | ||||||||
16726 | // We want to retrieve the member expression 'this->S'; | ||||||||
16727 | |||||||||
16728 | // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2] | ||||||||
16729 | // If a list item is an array section, it must specify contiguous storage. | ||||||||
16730 | // | ||||||||
16731 | // For this restriction it is sufficient that we make sure only references | ||||||||
16732 | // to variables or fields and array expressions, and that no array sections | ||||||||
16733 | // exist except in the rightmost expression (unless they cover the whole | ||||||||
16734 | // dimension of the array). E.g. these would be invalid: | ||||||||
16735 | // | ||||||||
16736 | // r.ArrS[3:5].Arr[6:7] | ||||||||
16737 | // | ||||||||
16738 | // r.ArrS[3:5].x | ||||||||
16739 | // | ||||||||
16740 | // but these would be valid: | ||||||||
16741 | // r.ArrS[3].Arr[6:7] | ||||||||
16742 | // | ||||||||
16743 | // r.ArrS[3].x | ||||||||
16744 | namespace { | ||||||||
16745 | class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> { | ||||||||
16746 | Sema &SemaRef; | ||||||||
16747 | OpenMPClauseKind CKind = OMPC_unknown; | ||||||||
16748 | OMPClauseMappableExprCommon::MappableExprComponentList &Components; | ||||||||
16749 | bool NoDiagnose = false; | ||||||||
16750 | const Expr *RelevantExpr = nullptr; | ||||||||
16751 | bool AllowUnitySizeArraySection = true; | ||||||||
16752 | bool AllowWholeSizeArraySection = true; | ||||||||
16753 | SourceLocation ELoc; | ||||||||
16754 | SourceRange ERange; | ||||||||
16755 | |||||||||
16756 | void emitErrorMsg() { | ||||||||
16757 | // If nothing else worked, this is not a valid map clause expression. | ||||||||
16758 | if (SemaRef.getLangOpts().OpenMP < 50) { | ||||||||
16759 | SemaRef.Diag(ELoc, | ||||||||
16760 | diag::err_omp_expected_named_var_member_or_array_expression) | ||||||||
16761 | << ERange; | ||||||||
16762 | } else { | ||||||||
16763 | SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) | ||||||||
16764 | << getOpenMPClauseName(CKind) << ERange; | ||||||||
16765 | } | ||||||||
16766 | } | ||||||||
16767 | |||||||||
16768 | public: | ||||||||
16769 | bool VisitDeclRefExpr(DeclRefExpr *DRE) { | ||||||||
16770 | if (!isa<VarDecl>(DRE->getDecl())) { | ||||||||
16771 | emitErrorMsg(); | ||||||||
16772 | return false; | ||||||||
16773 | } | ||||||||
16774 | assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr" ) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 16774, __PRETTY_FUNCTION__)); | ||||||||
16775 | RelevantExpr = DRE; | ||||||||
16776 | // Record the component. | ||||||||
16777 | Components.emplace_back(DRE, DRE->getDecl()); | ||||||||
16778 | return true; | ||||||||
16779 | } | ||||||||
16780 | |||||||||
16781 | bool VisitMemberExpr(MemberExpr *ME) { | ||||||||
16782 | Expr *E = ME; | ||||||||
16783 | Expr *BaseE = ME->getBase()->IgnoreParenCasts(); | ||||||||
16784 | |||||||||
16785 | if (isa<CXXThisExpr>(BaseE)) { | ||||||||
16786 | assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr" ) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 16786, __PRETTY_FUNCTION__)); | ||||||||
16787 | // We found a base expression: this->Val. | ||||||||
16788 | RelevantExpr = ME; | ||||||||
16789 | } else { | ||||||||
16790 | E = BaseE; | ||||||||
16791 | } | ||||||||
16792 | |||||||||
16793 | if (!isa<FieldDecl>(ME->getMemberDecl())) { | ||||||||
16794 | if (!NoDiagnose) { | ||||||||
16795 | SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) | ||||||||
16796 | << ME->getSourceRange(); | ||||||||
16797 | return false; | ||||||||
16798 | } | ||||||||
16799 | if (RelevantExpr) | ||||||||
16800 | return false; | ||||||||
16801 | return Visit(E); | ||||||||
16802 | } | ||||||||
16803 | |||||||||
16804 | auto *FD = cast<FieldDecl>(ME->getMemberDecl()); | ||||||||
16805 | |||||||||
16806 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] | ||||||||
16807 | // A bit-field cannot appear in a map clause. | ||||||||
16808 | // | ||||||||
16809 | if (FD->isBitField()) { | ||||||||
16810 | if (!NoDiagnose) { | ||||||||
16811 | SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) | ||||||||
16812 | << ME->getSourceRange() << getOpenMPClauseName(CKind); | ||||||||
16813 | return false; | ||||||||
16814 | } | ||||||||
16815 | if (RelevantExpr) | ||||||||
16816 | return false; | ||||||||
16817 | return Visit(E); | ||||||||
16818 | } | ||||||||
16819 | |||||||||
16820 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] | ||||||||
16821 | // If the type of a list item is a reference to a type T then the type | ||||||||
16822 | // will be considered to be T for all purposes of this clause. | ||||||||
16823 | QualType CurType = BaseE->getType().getNonReferenceType(); | ||||||||
16824 | |||||||||
16825 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] | ||||||||
16826 | // A list item cannot be a variable that is a member of a structure with | ||||||||
16827 | // a union type. | ||||||||
16828 | // | ||||||||
16829 | if (CurType->isUnionType()) { | ||||||||
16830 | if (!NoDiagnose) { | ||||||||
16831 | SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) | ||||||||
16832 | << ME->getSourceRange(); | ||||||||
16833 | return false; | ||||||||
16834 | } | ||||||||
16835 | return RelevantExpr || Visit(E); | ||||||||
16836 | } | ||||||||
16837 | |||||||||
16838 | // If we got a member expression, we should not expect any array section | ||||||||
16839 | // before that: | ||||||||
16840 | // | ||||||||
16841 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] | ||||||||
16842 | // If a list item is an element of a structure, only the rightmost symbol | ||||||||
16843 | // of the variable reference can be an array section. | ||||||||
16844 | // | ||||||||
16845 | AllowUnitySizeArraySection = false; | ||||||||
16846 | AllowWholeSizeArraySection = false; | ||||||||
16847 | |||||||||
16848 | // Record the component. | ||||||||
16849 | Components.emplace_back(ME, FD); | ||||||||
16850 | return RelevantExpr || Visit(E); | ||||||||
16851 | } | ||||||||
16852 | |||||||||
16853 | bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) { | ||||||||
16854 | Expr *E = AE->getBase()->IgnoreParenImpCasts(); | ||||||||
16855 | |||||||||
16856 | if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { | ||||||||
16857 | if (!NoDiagnose) { | ||||||||
16858 | SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) | ||||||||
16859 | << 0 << AE->getSourceRange(); | ||||||||
16860 | return false; | ||||||||
16861 | } | ||||||||
16862 | return RelevantExpr || Visit(E); | ||||||||
16863 | } | ||||||||
16864 | |||||||||
16865 | // If we got an array subscript that express the whole dimension we | ||||||||
16866 | // can have any array expressions before. If it only expressing part of | ||||||||
16867 | // the dimension, we can only have unitary-size array expressions. | ||||||||
16868 | if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, | ||||||||
16869 | E->getType())) | ||||||||
16870 | AllowWholeSizeArraySection = false; | ||||||||
16871 | |||||||||
16872 | if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) { | ||||||||
16873 | Expr::EvalResult Result; | ||||||||
16874 | if (!AE->getIdx()->isValueDependent() && | ||||||||
16875 | AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) && | ||||||||
16876 | !Result.Val.getInt().isNullValue()) { | ||||||||
16877 | SemaRef.Diag(AE->getIdx()->getExprLoc(), | ||||||||
16878 | diag::err_omp_invalid_map_this_expr); | ||||||||
16879 | SemaRef.Diag(AE->getIdx()->getExprLoc(), | ||||||||
16880 | diag::note_omp_invalid_subscript_on_this_ptr_map); | ||||||||
16881 | } | ||||||||
16882 | assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr" ) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 16882, __PRETTY_FUNCTION__)); | ||||||||
16883 | RelevantExpr = TE; | ||||||||
16884 | } | ||||||||
16885 | |||||||||
16886 | // Record the component - we don't have any declaration associated. | ||||||||
16887 | Components.emplace_back(AE, nullptr); | ||||||||
16888 | |||||||||
16889 | return RelevantExpr || Visit(E); | ||||||||
16890 | } | ||||||||
16891 | |||||||||
16892 | bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) { | ||||||||
16893 | assert(!NoDiagnose && "Array sections cannot be implicitly mapped.")((!NoDiagnose && "Array sections cannot be implicitly mapped." ) ? static_cast<void> (0) : __assert_fail ("!NoDiagnose && \"Array sections cannot be implicitly mapped.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 16893, __PRETTY_FUNCTION__)); | ||||||||
16894 | Expr *E = OASE->getBase()->IgnoreParenImpCasts(); | ||||||||
16895 | QualType CurType = | ||||||||
16896 | OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); | ||||||||
16897 | |||||||||
16898 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] | ||||||||
16899 | // If the type of a list item is a reference to a type T then the type | ||||||||
16900 | // will be considered to be T for all purposes of this clause. | ||||||||
16901 | if (CurType->isReferenceType()) | ||||||||
16902 | CurType = CurType->getPointeeType(); | ||||||||
16903 | |||||||||
16904 | bool IsPointer = CurType->isAnyPointerType(); | ||||||||
16905 | |||||||||
16906 | if (!IsPointer && !CurType->isArrayType()) { | ||||||||
16907 | SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) | ||||||||
16908 | << 0 << OASE->getSourceRange(); | ||||||||
16909 | return false; | ||||||||
16910 | } | ||||||||
16911 | |||||||||
16912 | bool NotWhole = | ||||||||
16913 | checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType); | ||||||||
16914 | bool NotUnity = | ||||||||
16915 | checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType); | ||||||||
16916 | |||||||||
16917 | if (AllowWholeSizeArraySection) { | ||||||||
16918 | // Any array section is currently allowed. Allowing a whole size array | ||||||||
16919 | // section implies allowing a unity array section as well. | ||||||||
16920 | // | ||||||||
16921 | // If this array section refers to the whole dimension we can still | ||||||||
16922 | // accept other array sections before this one, except if the base is a | ||||||||
16923 | // pointer. Otherwise, only unitary sections are accepted. | ||||||||
16924 | if (NotWhole || IsPointer) | ||||||||
16925 | AllowWholeSizeArraySection = false; | ||||||||
16926 | } else if (AllowUnitySizeArraySection && NotUnity) { | ||||||||
16927 | // A unity or whole array section is not allowed and that is not | ||||||||
16928 | // compatible with the properties of the current array section. | ||||||||
16929 | SemaRef.Diag( | ||||||||
16930 | ELoc, diag::err_array_section_does_not_specify_contiguous_storage) | ||||||||
16931 | << OASE->getSourceRange(); | ||||||||
16932 | return false; | ||||||||
16933 | } | ||||||||
16934 | |||||||||
16935 | if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { | ||||||||
16936 | Expr::EvalResult ResultR; | ||||||||
16937 | Expr::EvalResult ResultL; | ||||||||
16938 | if (!OASE->getLength()->isValueDependent() && | ||||||||
16939 | OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) && | ||||||||
16940 | !ResultR.Val.getInt().isOneValue()) { | ||||||||
16941 | SemaRef.Diag(OASE->getLength()->getExprLoc(), | ||||||||
16942 | diag::err_omp_invalid_map_this_expr); | ||||||||
16943 | SemaRef.Diag(OASE->getLength()->getExprLoc(), | ||||||||
16944 | diag::note_omp_invalid_length_on_this_ptr_mapping); | ||||||||
16945 | } | ||||||||
16946 | if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() && | ||||||||
16947 | OASE->getLowerBound()->EvaluateAsInt(ResultL, | ||||||||
16948 | SemaRef.getASTContext()) && | ||||||||
16949 | !ResultL.Val.getInt().isNullValue()) { | ||||||||
16950 | SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), | ||||||||
16951 | diag::err_omp_invalid_map_this_expr); | ||||||||
16952 | SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), | ||||||||
16953 | diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); | ||||||||
16954 | } | ||||||||
16955 | assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr" ) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 16955, __PRETTY_FUNCTION__)); | ||||||||
16956 | RelevantExpr = TE; | ||||||||
16957 | } | ||||||||
16958 | |||||||||
16959 | // Record the component - we don't have any declaration associated. | ||||||||
16960 | Components.emplace_back(OASE, nullptr); | ||||||||
16961 | return RelevantExpr || Visit(E); | ||||||||
16962 | } | ||||||||
16963 | bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { | ||||||||
16964 | Expr *Base = E->getBase(); | ||||||||
16965 | |||||||||
16966 | // Record the component - we don't have any declaration associated. | ||||||||
16967 | Components.emplace_back(E, nullptr); | ||||||||
16968 | |||||||||
16969 | return Visit(Base->IgnoreParenImpCasts()); | ||||||||
16970 | } | ||||||||
16971 | |||||||||
16972 | bool VisitUnaryOperator(UnaryOperator *UO) { | ||||||||
16973 | if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() || | ||||||||
16974 | UO->getOpcode() != UO_Deref) { | ||||||||
16975 | emitErrorMsg(); | ||||||||
16976 | return false; | ||||||||
16977 | } | ||||||||
16978 | if (!RelevantExpr) { | ||||||||
16979 | // Record the component if haven't found base decl. | ||||||||
16980 | Components.emplace_back(UO, nullptr); | ||||||||
16981 | } | ||||||||
16982 | return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts()); | ||||||||
16983 | } | ||||||||
16984 | bool VisitBinaryOperator(BinaryOperator *BO) { | ||||||||
16985 | if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) { | ||||||||
16986 | emitErrorMsg(); | ||||||||
16987 | return false; | ||||||||
16988 | } | ||||||||
16989 | |||||||||
16990 | // Pointer arithmetic is the only thing we expect to happen here so after we | ||||||||
16991 | // make sure the binary operator is a pointer type, the we only thing need | ||||||||
16992 | // to to is to visit the subtree that has the same type as root (so that we | ||||||||
16993 | // know the other subtree is just an offset) | ||||||||
16994 | Expr *LE = BO->getLHS()->IgnoreParenImpCasts(); | ||||||||
16995 | Expr *RE = BO->getRHS()->IgnoreParenImpCasts(); | ||||||||
16996 | Components.emplace_back(BO, nullptr); | ||||||||
16997 | assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||(((LE->getType().getTypePtr() == BO->getType().getTypePtr () || RE->getType().getTypePtr() == BO->getType().getTypePtr ()) && "Either LHS or RHS have base decl inside") ? static_cast <void> (0) : __assert_fail ("(LE->getType().getTypePtr() == BO->getType().getTypePtr() || RE->getType().getTypePtr() == BO->getType().getTypePtr()) && \"Either LHS or RHS have base decl inside\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 16999, __PRETTY_FUNCTION__)) | ||||||||
16998 | RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&(((LE->getType().getTypePtr() == BO->getType().getTypePtr () || RE->getType().getTypePtr() == BO->getType().getTypePtr ()) && "Either LHS or RHS have base decl inside") ? static_cast <void> (0) : __assert_fail ("(LE->getType().getTypePtr() == BO->getType().getTypePtr() || RE->getType().getTypePtr() == BO->getType().getTypePtr()) && \"Either LHS or RHS have base decl inside\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 16999, __PRETTY_FUNCTION__)) | ||||||||
16999 | "Either LHS or RHS have base decl inside")(((LE->getType().getTypePtr() == BO->getType().getTypePtr () || RE->getType().getTypePtr() == BO->getType().getTypePtr ()) && "Either LHS or RHS have base decl inside") ? static_cast <void> (0) : __assert_fail ("(LE->getType().getTypePtr() == BO->getType().getTypePtr() || RE->getType().getTypePtr() == BO->getType().getTypePtr()) && \"Either LHS or RHS have base decl inside\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 16999, __PRETTY_FUNCTION__)); | ||||||||
17000 | if (BO->getType().getTypePtr() == LE->getType().getTypePtr()) | ||||||||
17001 | return RelevantExpr || Visit(LE); | ||||||||
17002 | return RelevantExpr || Visit(RE); | ||||||||
17003 | } | ||||||||
17004 | bool VisitCXXThisExpr(CXXThisExpr *CTE) { | ||||||||
17005 | assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr" ) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17005, __PRETTY_FUNCTION__)); | ||||||||
17006 | RelevantExpr = CTE; | ||||||||
17007 | Components.emplace_back(CTE, nullptr); | ||||||||
17008 | return true; | ||||||||
17009 | } | ||||||||
17010 | bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) { | ||||||||
17011 | assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr" ) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17011, __PRETTY_FUNCTION__)); | ||||||||
17012 | Components.emplace_back(COCE, nullptr); | ||||||||
17013 | return true; | ||||||||
17014 | } | ||||||||
17015 | bool VisitStmt(Stmt *) { | ||||||||
17016 | emitErrorMsg(); | ||||||||
17017 | return false; | ||||||||
17018 | } | ||||||||
17019 | const Expr *getFoundBase() const { | ||||||||
17020 | return RelevantExpr; | ||||||||
17021 | } | ||||||||
17022 | explicit MapBaseChecker( | ||||||||
17023 | Sema &SemaRef, OpenMPClauseKind CKind, | ||||||||
17024 | OMPClauseMappableExprCommon::MappableExprComponentList &Components, | ||||||||
17025 | bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange) | ||||||||
17026 | : SemaRef(SemaRef), CKind(CKind), Components(Components), | ||||||||
17027 | NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {} | ||||||||
17028 | }; | ||||||||
17029 | } // namespace | ||||||||
17030 | |||||||||
17031 | /// Return the expression of the base of the mappable expression or null if it | ||||||||
17032 | /// cannot be determined and do all the necessary checks to see if the expression | ||||||||
17033 | /// is valid as a standalone mappable expression. In the process, record all the | ||||||||
17034 | /// components of the expression. | ||||||||
17035 | static const Expr *checkMapClauseExpressionBase( | ||||||||
17036 | Sema &SemaRef, Expr *E, | ||||||||
17037 | OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, | ||||||||
17038 | OpenMPClauseKind CKind, bool NoDiagnose) { | ||||||||
17039 | SourceLocation ELoc = E->getExprLoc(); | ||||||||
17040 | SourceRange ERange = E->getSourceRange(); | ||||||||
17041 | MapBaseChecker Checker(SemaRef, CKind, CurComponents, NoDiagnose, ELoc, | ||||||||
17042 | ERange); | ||||||||
17043 | if (Checker.Visit(E->IgnoreParens())) | ||||||||
17044 | return Checker.getFoundBase(); | ||||||||
17045 | return nullptr; | ||||||||
17046 | } | ||||||||
17047 | |||||||||
17048 | // Return true if expression E associated with value VD has conflicts with other | ||||||||
17049 | // map information. | ||||||||
17050 | static bool checkMapConflicts( | ||||||||
17051 | Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, | ||||||||
17052 | bool CurrentRegionOnly, | ||||||||
17053 | OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, | ||||||||
17054 | OpenMPClauseKind CKind) { | ||||||||
17055 | assert(VD && E)((VD && E) ? static_cast<void> (0) : __assert_fail ("VD && E", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17055, __PRETTY_FUNCTION__)); | ||||||||
17056 | SourceLocation ELoc = E->getExprLoc(); | ||||||||
17057 | SourceRange ERange = E->getSourceRange(); | ||||||||
17058 | |||||||||
17059 | // In order to easily check the conflicts we need to match each component of | ||||||||
17060 | // the expression under test with the components of the expressions that are | ||||||||
17061 | // already in the stack. | ||||||||
17062 | |||||||||
17063 | assert(!CurComponents.empty() && "Map clause expression with no components!")((!CurComponents.empty() && "Map clause expression with no components!" ) ? static_cast<void> (0) : __assert_fail ("!CurComponents.empty() && \"Map clause expression with no components!\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17063, __PRETTY_FUNCTION__)); | ||||||||
17064 | assert(CurComponents.back().getAssociatedDeclaration() == VD &&((CurComponents.back().getAssociatedDeclaration() == VD && "Map clause expression with unexpected base!") ? static_cast <void> (0) : __assert_fail ("CurComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17065, __PRETTY_FUNCTION__)) | ||||||||
17065 | "Map clause expression with unexpected base!")((CurComponents.back().getAssociatedDeclaration() == VD && "Map clause expression with unexpected base!") ? static_cast <void> (0) : __assert_fail ("CurComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17065, __PRETTY_FUNCTION__)); | ||||||||
17066 | |||||||||
17067 | // Variables to help detecting enclosing problems in data environment nests. | ||||||||
17068 | bool IsEnclosedByDataEnvironmentExpr = false; | ||||||||
17069 | const Expr *EnclosingExpr = nullptr; | ||||||||
17070 | |||||||||
17071 | bool FoundError = DSAS->checkMappableExprComponentListsForDecl( | ||||||||
17072 | VD, CurrentRegionOnly, | ||||||||
17073 | [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, | ||||||||
17074 | ERange, CKind, &EnclosingExpr, | ||||||||
17075 | CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef | ||||||||
17076 | StackComponents, | ||||||||
17077 | OpenMPClauseKind) { | ||||||||
17078 | assert(!StackComponents.empty() &&((!StackComponents.empty() && "Map clause expression with no components!" ) ? static_cast<void> (0) : __assert_fail ("!StackComponents.empty() && \"Map clause expression with no components!\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17079, __PRETTY_FUNCTION__)) | ||||||||
17079 | "Map clause expression with no components!")((!StackComponents.empty() && "Map clause expression with no components!" ) ? static_cast<void> (0) : __assert_fail ("!StackComponents.empty() && \"Map clause expression with no components!\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17079, __PRETTY_FUNCTION__)); | ||||||||
17080 | assert(StackComponents.back().getAssociatedDeclaration() == VD &&((StackComponents.back().getAssociatedDeclaration() == VD && "Map clause expression with unexpected base!") ? static_cast <void> (0) : __assert_fail ("StackComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17081, __PRETTY_FUNCTION__)) | ||||||||
17081 | "Map clause expression with unexpected base!")((StackComponents.back().getAssociatedDeclaration() == VD && "Map clause expression with unexpected base!") ? static_cast <void> (0) : __assert_fail ("StackComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17081, __PRETTY_FUNCTION__)); | ||||||||
17082 | (void)VD; | ||||||||
17083 | |||||||||
17084 | // The whole expression in the stack. | ||||||||
17085 | const Expr *RE = StackComponents.front().getAssociatedExpression(); | ||||||||
17086 | |||||||||
17087 | // Expressions must start from the same base. Here we detect at which | ||||||||
17088 | // point both expressions diverge from each other and see if we can | ||||||||
17089 | // detect if the memory referred to both expressions is contiguous and | ||||||||
17090 | // do not overlap. | ||||||||
17091 | auto CI = CurComponents.rbegin(); | ||||||||
17092 | auto CE = CurComponents.rend(); | ||||||||
17093 | auto SI = StackComponents.rbegin(); | ||||||||
17094 | auto SE = StackComponents.rend(); | ||||||||
17095 | for (; CI != CE && SI != SE; ++CI, ++SI) { | ||||||||
17096 | |||||||||
17097 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] | ||||||||
17098 | // At most one list item can be an array item derived from a given | ||||||||
17099 | // variable in map clauses of the same construct. | ||||||||
17100 | if (CurrentRegionOnly && | ||||||||
17101 | (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || | ||||||||
17102 | isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) || | ||||||||
17103 | isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) && | ||||||||
17104 | (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || | ||||||||
17105 | isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) || | ||||||||
17106 | isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) { | ||||||||
17107 | SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), | ||||||||
17108 | diag::err_omp_multiple_array_items_in_map_clause) | ||||||||
17109 | << CI->getAssociatedExpression()->getSourceRange(); | ||||||||
17110 | SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), | ||||||||
17111 | diag::note_used_here) | ||||||||
17112 | << SI->getAssociatedExpression()->getSourceRange(); | ||||||||
17113 | return true; | ||||||||
17114 | } | ||||||||
17115 | |||||||||
17116 | // Do both expressions have the same kind? | ||||||||
17117 | if (CI->getAssociatedExpression()->getStmtClass() != | ||||||||
17118 | SI->getAssociatedExpression()->getStmtClass()) | ||||||||
17119 | break; | ||||||||
17120 | |||||||||
17121 | // Are we dealing with different variables/fields? | ||||||||
17122 | if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) | ||||||||
17123 | break; | ||||||||
17124 | } | ||||||||
17125 | // Check if the extra components of the expressions in the enclosing | ||||||||
17126 | // data environment are redundant for the current base declaration. | ||||||||
17127 | // If they are, the maps completely overlap, which is legal. | ||||||||
17128 | for (; SI != SE; ++SI) { | ||||||||
17129 | QualType Type; | ||||||||
17130 | if (const auto *ASE = | ||||||||
17131 | dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { | ||||||||
17132 | Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); | ||||||||
17133 | } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( | ||||||||
17134 | SI->getAssociatedExpression())) { | ||||||||
17135 | const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); | ||||||||
17136 | Type = | ||||||||
17137 | OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); | ||||||||
17138 | } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>( | ||||||||
17139 | SI->getAssociatedExpression())) { | ||||||||
17140 | Type = OASE->getBase()->getType()->getPointeeType(); | ||||||||
17141 | } | ||||||||
17142 | if (Type.isNull() || Type->isAnyPointerType() || | ||||||||
17143 | checkArrayExpressionDoesNotReferToWholeSize( | ||||||||
17144 | SemaRef, SI->getAssociatedExpression(), Type)) | ||||||||
17145 | break; | ||||||||
17146 | } | ||||||||
17147 | |||||||||
17148 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] | ||||||||
17149 | // List items of map clauses in the same construct must not share | ||||||||
17150 | // original storage. | ||||||||
17151 | // | ||||||||
17152 | // If the expressions are exactly the same or one is a subset of the | ||||||||
17153 | // other, it means they are sharing storage. | ||||||||
17154 | if (CI == CE && SI == SE) { | ||||||||
17155 | if (CurrentRegionOnly) { | ||||||||
17156 | if (CKind == OMPC_map) { | ||||||||
17157 | SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; | ||||||||
17158 | } else { | ||||||||
17159 | assert(CKind == OMPC_to || CKind == OMPC_from)((CKind == OMPC_to || CKind == OMPC_from) ? static_cast<void > (0) : __assert_fail ("CKind == OMPC_to || CKind == OMPC_from" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17159, __PRETTY_FUNCTION__)); | ||||||||
17160 | SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) | ||||||||
17161 | << ERange; | ||||||||
17162 | } | ||||||||
17163 | SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) | ||||||||
17164 | << RE->getSourceRange(); | ||||||||
17165 | return true; | ||||||||
17166 | } | ||||||||
17167 | // If we find the same expression in the enclosing data environment, | ||||||||
17168 | // that is legal. | ||||||||
17169 | IsEnclosedByDataEnvironmentExpr = true; | ||||||||
17170 | return false; | ||||||||
17171 | } | ||||||||
17172 | |||||||||
17173 | QualType DerivedType = | ||||||||
17174 | std::prev(CI)->getAssociatedDeclaration()->getType(); | ||||||||
17175 | SourceLocation DerivedLoc = | ||||||||
17176 | std::prev(CI)->getAssociatedExpression()->getExprLoc(); | ||||||||
17177 | |||||||||
17178 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] | ||||||||
17179 | // If the type of a list item is a reference to a type T then the type | ||||||||
17180 | // will be considered to be T for all purposes of this clause. | ||||||||
17181 | DerivedType = DerivedType.getNonReferenceType(); | ||||||||
17182 | |||||||||
17183 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] | ||||||||
17184 | // A variable for which the type is pointer and an array section | ||||||||
17185 | // derived from that variable must not appear as list items of map | ||||||||
17186 | // clauses of the same construct. | ||||||||
17187 | // | ||||||||
17188 | // Also, cover one of the cases in: | ||||||||
17189 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] | ||||||||
17190 | // If any part of the original storage of a list item has corresponding | ||||||||
17191 | // storage in the device data environment, all of the original storage | ||||||||
17192 | // must have corresponding storage in the device data environment. | ||||||||
17193 | // | ||||||||
17194 | if (DerivedType->isAnyPointerType()) { | ||||||||
17195 | if (CI == CE || SI == SE) { | ||||||||
17196 | SemaRef.Diag( | ||||||||
17197 | DerivedLoc, | ||||||||
17198 | diag::err_omp_pointer_mapped_along_with_derived_section) | ||||||||
17199 | << DerivedLoc; | ||||||||
17200 | SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) | ||||||||
17201 | << RE->getSourceRange(); | ||||||||
17202 | return true; | ||||||||
17203 | } | ||||||||
17204 | if (CI->getAssociatedExpression()->getStmtClass() != | ||||||||
17205 | SI->getAssociatedExpression()->getStmtClass() || | ||||||||
17206 | CI->getAssociatedDeclaration()->getCanonicalDecl() == | ||||||||
17207 | SI->getAssociatedDeclaration()->getCanonicalDecl()) { | ||||||||
17208 | assert(CI != CE && SI != SE)((CI != CE && SI != SE) ? static_cast<void> (0) : __assert_fail ("CI != CE && SI != SE", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17208, __PRETTY_FUNCTION__)); | ||||||||
17209 | SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) | ||||||||
17210 | << DerivedLoc; | ||||||||
17211 | SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) | ||||||||
17212 | << RE->getSourceRange(); | ||||||||
17213 | return true; | ||||||||
17214 | } | ||||||||
17215 | } | ||||||||
17216 | |||||||||
17217 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] | ||||||||
17218 | // List items of map clauses in the same construct must not share | ||||||||
17219 | // original storage. | ||||||||
17220 | // | ||||||||
17221 | // An expression is a subset of the other. | ||||||||
17222 | if (CurrentRegionOnly && (CI == CE || SI == SE)) { | ||||||||
17223 | if (CKind == OMPC_map) { | ||||||||
17224 | if (CI != CE || SI != SE) { | ||||||||
17225 | // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is | ||||||||
17226 | // a pointer. | ||||||||
17227 | auto Begin = | ||||||||
17228 | CI != CE ? CurComponents.begin() : StackComponents.begin(); | ||||||||
17229 | auto End = CI != CE ? CurComponents.end() : StackComponents.end(); | ||||||||
17230 | auto It = Begin; | ||||||||
17231 | while (It != End && !It->getAssociatedDeclaration()) | ||||||||
17232 | std::advance(It, 1); | ||||||||
17233 | assert(It != End &&((It != End && "Expected at least one component with the declaration." ) ? static_cast<void> (0) : __assert_fail ("It != End && \"Expected at least one component with the declaration.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17234, __PRETTY_FUNCTION__)) | ||||||||
17234 | "Expected at least one component with the declaration.")((It != End && "Expected at least one component with the declaration." ) ? static_cast<void> (0) : __assert_fail ("It != End && \"Expected at least one component with the declaration.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17234, __PRETTY_FUNCTION__)); | ||||||||
17235 | if (It != Begin && It->getAssociatedDeclaration() | ||||||||
17236 | ->getType() | ||||||||
17237 | .getCanonicalType() | ||||||||
17238 | ->isAnyPointerType()) { | ||||||||
17239 | IsEnclosedByDataEnvironmentExpr = false; | ||||||||
17240 | EnclosingExpr = nullptr; | ||||||||
17241 | return false; | ||||||||
17242 | } | ||||||||
17243 | } | ||||||||
17244 | SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; | ||||||||
17245 | } else { | ||||||||
17246 | assert(CKind == OMPC_to || CKind == OMPC_from)((CKind == OMPC_to || CKind == OMPC_from) ? static_cast<void > (0) : __assert_fail ("CKind == OMPC_to || CKind == OMPC_from" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17246, __PRETTY_FUNCTION__)); | ||||||||
17247 | SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) | ||||||||
17248 | << ERange; | ||||||||
17249 | } | ||||||||
17250 | SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) | ||||||||
17251 | << RE->getSourceRange(); | ||||||||
17252 | return true; | ||||||||
17253 | } | ||||||||
17254 | |||||||||
17255 | // The current expression uses the same base as other expression in the | ||||||||
17256 | // data environment but does not contain it completely. | ||||||||
17257 | if (!CurrentRegionOnly && SI != SE) | ||||||||
17258 | EnclosingExpr = RE; | ||||||||
17259 | |||||||||
17260 | // The current expression is a subset of the expression in the data | ||||||||
17261 | // environment. | ||||||||
17262 | IsEnclosedByDataEnvironmentExpr |= | ||||||||
17263 | (!CurrentRegionOnly && CI != CE && SI == SE); | ||||||||
17264 | |||||||||
17265 | return false; | ||||||||
17266 | }); | ||||||||
17267 | |||||||||
17268 | if (CurrentRegionOnly) | ||||||||
17269 | return FoundError; | ||||||||
17270 | |||||||||
17271 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] | ||||||||
17272 | // If any part of the original storage of a list item has corresponding | ||||||||
17273 | // storage in the device data environment, all of the original storage must | ||||||||
17274 | // have corresponding storage in the device data environment. | ||||||||
17275 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] | ||||||||
17276 | // If a list item is an element of a structure, and a different element of | ||||||||
17277 | // the structure has a corresponding list item in the device data environment | ||||||||
17278 | // prior to a task encountering the construct associated with the map clause, | ||||||||
17279 | // then the list item must also have a corresponding list item in the device | ||||||||
17280 | // data environment prior to the task encountering the construct. | ||||||||
17281 | // | ||||||||
17282 | if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { | ||||||||
17283 | SemaRef.Diag(ELoc, | ||||||||
17284 | diag::err_omp_original_storage_is_shared_and_does_not_contain) | ||||||||
17285 | << ERange; | ||||||||
17286 | SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) | ||||||||
17287 | << EnclosingExpr->getSourceRange(); | ||||||||
17288 | return true; | ||||||||
17289 | } | ||||||||
17290 | |||||||||
17291 | return FoundError; | ||||||||
17292 | } | ||||||||
17293 | |||||||||
17294 | // Look up the user-defined mapper given the mapper name and mapped type, and | ||||||||
17295 | // build a reference to it. | ||||||||
17296 | static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, | ||||||||
17297 | CXXScopeSpec &MapperIdScopeSpec, | ||||||||
17298 | const DeclarationNameInfo &MapperId, | ||||||||
17299 | QualType Type, | ||||||||
17300 | Expr *UnresolvedMapper) { | ||||||||
17301 | if (MapperIdScopeSpec.isInvalid()) | ||||||||
17302 | return ExprError(); | ||||||||
17303 | // Get the actual type for the array type. | ||||||||
17304 | if (Type->isArrayType()) { | ||||||||
17305 | assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type")((Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type" ) ? static_cast<void> (0) : __assert_fail ("Type->getAsArrayTypeUnsafe() && \"Expect to get a valid array type\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17305, __PRETTY_FUNCTION__)); | ||||||||
17306 | Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); | ||||||||
17307 | } | ||||||||
17308 | // Find all user-defined mappers with the given MapperId. | ||||||||
17309 | SmallVector<UnresolvedSet<8>, 4> Lookups; | ||||||||
17310 | LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); | ||||||||
17311 | Lookup.suppressDiagnostics(); | ||||||||
17312 | if (S) { | ||||||||
17313 | while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { | ||||||||
17314 | NamedDecl *D = Lookup.getRepresentativeDecl(); | ||||||||
17315 | while (S && !S->isDeclScope(D)) | ||||||||
17316 | S = S->getParent(); | ||||||||
17317 | if (S) | ||||||||
17318 | S = S->getParent(); | ||||||||
17319 | Lookups.emplace_back(); | ||||||||
17320 | Lookups.back().append(Lookup.begin(), Lookup.end()); | ||||||||
17321 | Lookup.clear(); | ||||||||
17322 | } | ||||||||
17323 | } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { | ||||||||
17324 | // Extract the user-defined mappers with the given MapperId. | ||||||||
17325 | Lookups.push_back(UnresolvedSet<8>()); | ||||||||
17326 | for (NamedDecl *D : ULE->decls()) { | ||||||||
17327 | auto *DMD = cast<OMPDeclareMapperDecl>(D); | ||||||||
17328 | assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.")((DMD && "Expect valid OMPDeclareMapperDecl during instantiation." ) ? static_cast<void> (0) : __assert_fail ("DMD && \"Expect valid OMPDeclareMapperDecl during instantiation.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17328, __PRETTY_FUNCTION__)); | ||||||||
17329 | Lookups.back().addDecl(DMD); | ||||||||
17330 | } | ||||||||
17331 | } | ||||||||
17332 | // Defer the lookup for dependent types. The results will be passed through | ||||||||
17333 | // UnresolvedMapper on instantiation. | ||||||||
17334 | if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || | ||||||||
17335 | Type->isInstantiationDependentType() || | ||||||||
17336 | Type->containsUnexpandedParameterPack() || | ||||||||
17337 | filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { | ||||||||
17338 | return !D->isInvalidDecl() && | ||||||||
17339 | (D->getType()->isDependentType() || | ||||||||
17340 | D->getType()->isInstantiationDependentType() || | ||||||||
17341 | D->getType()->containsUnexpandedParameterPack()); | ||||||||
17342 | })) { | ||||||||
17343 | UnresolvedSet<8> URS; | ||||||||
17344 | for (const UnresolvedSet<8> &Set : Lookups) { | ||||||||
17345 | if (Set.empty()) | ||||||||
17346 | continue; | ||||||||
17347 | URS.append(Set.begin(), Set.end()); | ||||||||
17348 | } | ||||||||
17349 | return UnresolvedLookupExpr::Create( | ||||||||
17350 | SemaRef.Context, /*NamingClass=*/nullptr, | ||||||||
17351 | MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, | ||||||||
17352 | /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); | ||||||||
17353 | } | ||||||||
17354 | SourceLocation Loc = MapperId.getLoc(); | ||||||||
17355 | // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions | ||||||||
17356 | // The type must be of struct, union or class type in C and C++ | ||||||||
17357 | if (!Type->isStructureOrClassType() && !Type->isUnionType() && | ||||||||
17358 | (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { | ||||||||
17359 | SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); | ||||||||
17360 | return ExprError(); | ||||||||
17361 | } | ||||||||
17362 | // Perform argument dependent lookup. | ||||||||
17363 | if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) | ||||||||
17364 | argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); | ||||||||
17365 | // Return the first user-defined mapper with the desired type. | ||||||||
17366 | if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( | ||||||||
17367 | Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { | ||||||||
17368 | if (!D->isInvalidDecl() && | ||||||||
17369 | SemaRef.Context.hasSameType(D->getType(), Type)) | ||||||||
17370 | return D; | ||||||||
17371 | return nullptr; | ||||||||
17372 | })) | ||||||||
17373 | return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); | ||||||||
17374 | // Find the first user-defined mapper with a type derived from the desired | ||||||||
17375 | // type. | ||||||||
17376 | if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( | ||||||||
17377 | Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { | ||||||||
17378 | if (!D->isInvalidDecl() && | ||||||||
17379 | SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && | ||||||||
17380 | !Type.isMoreQualifiedThan(D->getType())) | ||||||||
17381 | return D; | ||||||||
17382 | return nullptr; | ||||||||
17383 | })) { | ||||||||
17384 | CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, | ||||||||
17385 | /*DetectVirtual=*/false); | ||||||||
17386 | if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { | ||||||||
17387 | if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( | ||||||||
17388 | VD->getType().getUnqualifiedType()))) { | ||||||||
17389 | if (SemaRef.CheckBaseClassAccess( | ||||||||
17390 | Loc, VD->getType(), Type, Paths.front(), | ||||||||
17391 | /*DiagID=*/0) != Sema::AR_inaccessible) { | ||||||||
17392 | return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); | ||||||||
17393 | } | ||||||||
17394 | } | ||||||||
17395 | } | ||||||||
17396 | } | ||||||||
17397 | // Report error if a mapper is specified, but cannot be found. | ||||||||
17398 | if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { | ||||||||
17399 | SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) | ||||||||
17400 | << Type << MapperId.getName(); | ||||||||
17401 | return ExprError(); | ||||||||
17402 | } | ||||||||
17403 | return ExprEmpty(); | ||||||||
17404 | } | ||||||||
17405 | |||||||||
17406 | namespace { | ||||||||
17407 | // Utility struct that gathers all the related lists associated with a mappable | ||||||||
17408 | // expression. | ||||||||
17409 | struct MappableVarListInfo { | ||||||||
17410 | // The list of expressions. | ||||||||
17411 | ArrayRef<Expr *> VarList; | ||||||||
17412 | // The list of processed expressions. | ||||||||
17413 | SmallVector<Expr *, 16> ProcessedVarList; | ||||||||
17414 | // The mappble components for each expression. | ||||||||
17415 | OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; | ||||||||
17416 | // The base declaration of the variable. | ||||||||
17417 | SmallVector<ValueDecl *, 16> VarBaseDeclarations; | ||||||||
17418 | // The reference to the user-defined mapper associated with every expression. | ||||||||
17419 | SmallVector<Expr *, 16> UDMapperList; | ||||||||
17420 | |||||||||
17421 | MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { | ||||||||
17422 | // We have a list of components and base declarations for each entry in the | ||||||||
17423 | // variable list. | ||||||||
17424 | VarComponents.reserve(VarList.size()); | ||||||||
17425 | VarBaseDeclarations.reserve(VarList.size()); | ||||||||
17426 | } | ||||||||
17427 | }; | ||||||||
17428 | } | ||||||||
17429 | |||||||||
17430 | // Check the validity of the provided variable list for the provided clause kind | ||||||||
17431 | // \a CKind. In the check process the valid expressions, mappable expression | ||||||||
17432 | // components, variables, and user-defined mappers are extracted and used to | ||||||||
17433 | // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a | ||||||||
17434 | // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, | ||||||||
17435 | // and \a MapperId are expected to be valid if the clause kind is 'map'. | ||||||||
17436 | static void checkMappableExpressionList( | ||||||||
17437 | Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, | ||||||||
17438 | MappableVarListInfo &MVLI, SourceLocation StartLoc, | ||||||||
17439 | CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, | ||||||||
17440 | ArrayRef<Expr *> UnresolvedMappers, | ||||||||
17441 | OpenMPMapClauseKind MapType = OMPC_MAP_unknown, | ||||||||
17442 | bool IsMapTypeImplicit = false) { | ||||||||
17443 | // We only expect mappable expressions in 'to', 'from', and 'map' clauses. | ||||||||
17444 | assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&(((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from ) && "Unexpected clause kind with mappable expressions!" ) ? static_cast<void> (0) : __assert_fail ("(CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && \"Unexpected clause kind with mappable expressions!\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17445, __PRETTY_FUNCTION__)) | ||||||||
17445 | "Unexpected clause kind with mappable expressions!")(((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from ) && "Unexpected clause kind with mappable expressions!" ) ? static_cast<void> (0) : __assert_fail ("(CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && \"Unexpected clause kind with mappable expressions!\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17445, __PRETTY_FUNCTION__)); | ||||||||
17446 | |||||||||
17447 | // If the identifier of user-defined mapper is not specified, it is "default". | ||||||||
17448 | // We do not change the actual name in this clause to distinguish whether a | ||||||||
17449 | // mapper is specified explicitly, i.e., it is not explicitly specified when | ||||||||
17450 | // MapperId.getName() is empty. | ||||||||
17451 | if (!MapperId.getName() || MapperId.getName().isEmpty()) { | ||||||||
17452 | auto &DeclNames = SemaRef.getASTContext().DeclarationNames; | ||||||||
17453 | MapperId.setName(DeclNames.getIdentifier( | ||||||||
17454 | &SemaRef.getASTContext().Idents.get("default"))); | ||||||||
17455 | } | ||||||||
17456 | |||||||||
17457 | // Iterators to find the current unresolved mapper expression. | ||||||||
17458 | auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); | ||||||||
17459 | bool UpdateUMIt = false; | ||||||||
17460 | Expr *UnresolvedMapper = nullptr; | ||||||||
17461 | |||||||||
17462 | // Keep track of the mappable components and base declarations in this clause. | ||||||||
17463 | // Each entry in the list is going to have a list of components associated. We | ||||||||
17464 | // record each set of the components so that we can build the clause later on. | ||||||||
17465 | // In the end we should have the same amount of declarations and component | ||||||||
17466 | // lists. | ||||||||
17467 | |||||||||
17468 | for (Expr *RE : MVLI.VarList) { | ||||||||
17469 | assert(RE && "Null expr in omp to/from/map clause")((RE && "Null expr in omp to/from/map clause") ? static_cast <void> (0) : __assert_fail ("RE && \"Null expr in omp to/from/map clause\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17469, __PRETTY_FUNCTION__)); | ||||||||
17470 | SourceLocation ELoc = RE->getExprLoc(); | ||||||||
17471 | |||||||||
17472 | // Find the current unresolved mapper expression. | ||||||||
17473 | if (UpdateUMIt && UMIt != UMEnd) { | ||||||||
17474 | UMIt++; | ||||||||
17475 | assert(((UMIt != UMEnd && "Expect the size of UnresolvedMappers to match with that of VarList" ) ? static_cast<void> (0) : __assert_fail ("UMIt != UMEnd && \"Expect the size of UnresolvedMappers to match with that of VarList\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17477, __PRETTY_FUNCTION__)) | ||||||||
17476 | UMIt != UMEnd &&((UMIt != UMEnd && "Expect the size of UnresolvedMappers to match with that of VarList" ) ? static_cast<void> (0) : __assert_fail ("UMIt != UMEnd && \"Expect the size of UnresolvedMappers to match with that of VarList\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17477, __PRETTY_FUNCTION__)) | ||||||||
17477 | "Expect the size of UnresolvedMappers to match with that of VarList")((UMIt != UMEnd && "Expect the size of UnresolvedMappers to match with that of VarList" ) ? static_cast<void> (0) : __assert_fail ("UMIt != UMEnd && \"Expect the size of UnresolvedMappers to match with that of VarList\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17477, __PRETTY_FUNCTION__)); | ||||||||
17478 | } | ||||||||
17479 | UpdateUMIt = true; | ||||||||
17480 | if (UMIt != UMEnd) | ||||||||
17481 | UnresolvedMapper = *UMIt; | ||||||||
17482 | |||||||||
17483 | const Expr *VE = RE->IgnoreParenLValueCasts(); | ||||||||
17484 | |||||||||
17485 | if (VE->isValueDependent() || VE->isTypeDependent() || | ||||||||
17486 | VE->isInstantiationDependent() || | ||||||||
17487 | VE->containsUnexpandedParameterPack()) { | ||||||||
17488 | // Try to find the associated user-defined mapper. | ||||||||
17489 | ExprResult ER = buildUserDefinedMapperRef( | ||||||||
17490 | SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, | ||||||||
17491 | VE->getType().getCanonicalType(), UnresolvedMapper); | ||||||||
17492 | if (ER.isInvalid()) | ||||||||
17493 | continue; | ||||||||
17494 | MVLI.UDMapperList.push_back(ER.get()); | ||||||||
17495 | // We can only analyze this information once the missing information is | ||||||||
17496 | // resolved. | ||||||||
17497 | MVLI.ProcessedVarList.push_back(RE); | ||||||||
17498 | continue; | ||||||||
17499 | } | ||||||||
17500 | |||||||||
17501 | Expr *SimpleExpr = RE->IgnoreParenCasts(); | ||||||||
17502 | |||||||||
17503 | if (!RE->isLValue()) { | ||||||||
17504 | if (SemaRef.getLangOpts().OpenMP < 50) { | ||||||||
17505 | SemaRef.Diag( | ||||||||
17506 | ELoc, diag::err_omp_expected_named_var_member_or_array_expression) | ||||||||
17507 | << RE->getSourceRange(); | ||||||||
17508 | } else { | ||||||||
17509 | SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) | ||||||||
17510 | << getOpenMPClauseName(CKind) << RE->getSourceRange(); | ||||||||
17511 | } | ||||||||
17512 | continue; | ||||||||
17513 | } | ||||||||
17514 | |||||||||
17515 | OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; | ||||||||
17516 | ValueDecl *CurDeclaration = nullptr; | ||||||||
17517 | |||||||||
17518 | // Obtain the array or member expression bases if required. Also, fill the | ||||||||
17519 | // components array with all the components identified in the process. | ||||||||
17520 | const Expr *BE = checkMapClauseExpressionBase( | ||||||||
17521 | SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); | ||||||||
17522 | if (!BE) | ||||||||
17523 | continue; | ||||||||
17524 | |||||||||
17525 | assert(!CurComponents.empty() &&((!CurComponents.empty() && "Invalid mappable expression information." ) ? static_cast<void> (0) : __assert_fail ("!CurComponents.empty() && \"Invalid mappable expression information.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17526, __PRETTY_FUNCTION__)) | ||||||||
17526 | "Invalid mappable expression information.")((!CurComponents.empty() && "Invalid mappable expression information." ) ? static_cast<void> (0) : __assert_fail ("!CurComponents.empty() && \"Invalid mappable expression information.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17526, __PRETTY_FUNCTION__)); | ||||||||
17527 | |||||||||
17528 | if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { | ||||||||
17529 | // Add store "this" pointer to class in DSAStackTy for future checking | ||||||||
17530 | DSAS->addMappedClassesQualTypes(TE->getType()); | ||||||||
17531 | // Try to find the associated user-defined mapper. | ||||||||
17532 | ExprResult ER = buildUserDefinedMapperRef( | ||||||||
17533 | SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, | ||||||||
17534 | VE->getType().getCanonicalType(), UnresolvedMapper); | ||||||||
17535 | if (ER.isInvalid()) | ||||||||
17536 | continue; | ||||||||
17537 | MVLI.UDMapperList.push_back(ER.get()); | ||||||||
17538 | // Skip restriction checking for variable or field declarations | ||||||||
17539 | MVLI.ProcessedVarList.push_back(RE); | ||||||||
17540 | MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); | ||||||||
17541 | MVLI.VarComponents.back().append(CurComponents.begin(), | ||||||||
17542 | CurComponents.end()); | ||||||||
17543 | MVLI.VarBaseDeclarations.push_back(nullptr); | ||||||||
17544 | continue; | ||||||||
17545 | } | ||||||||
17546 | |||||||||
17547 | // For the following checks, we rely on the base declaration which is | ||||||||
17548 | // expected to be associated with the last component. The declaration is | ||||||||
17549 | // expected to be a variable or a field (if 'this' is being mapped). | ||||||||
17550 | CurDeclaration = CurComponents.back().getAssociatedDeclaration(); | ||||||||
17551 | assert(CurDeclaration && "Null decl on map clause.")((CurDeclaration && "Null decl on map clause.") ? static_cast <void> (0) : __assert_fail ("CurDeclaration && \"Null decl on map clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17551, __PRETTY_FUNCTION__)); | ||||||||
17552 | assert(((CurDeclaration->isCanonicalDecl() && "Expecting components to have associated only canonical declarations." ) ? static_cast<void> (0) : __assert_fail ("CurDeclaration->isCanonicalDecl() && \"Expecting components to have associated only canonical declarations.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17554, __PRETTY_FUNCTION__)) | ||||||||
17553 | CurDeclaration->isCanonicalDecl() &&((CurDeclaration->isCanonicalDecl() && "Expecting components to have associated only canonical declarations." ) ? static_cast<void> (0) : __assert_fail ("CurDeclaration->isCanonicalDecl() && \"Expecting components to have associated only canonical declarations.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17554, __PRETTY_FUNCTION__)) | ||||||||
17554 | "Expecting components to have associated only canonical declarations.")((CurDeclaration->isCanonicalDecl() && "Expecting components to have associated only canonical declarations." ) ? static_cast<void> (0) : __assert_fail ("CurDeclaration->isCanonicalDecl() && \"Expecting components to have associated only canonical declarations.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17554, __PRETTY_FUNCTION__)); | ||||||||
17555 | |||||||||
17556 | auto *VD = dyn_cast<VarDecl>(CurDeclaration); | ||||||||
17557 | const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); | ||||||||
17558 | |||||||||
17559 | assert((VD || FD) && "Only variables or fields are expected here!")(((VD || FD) && "Only variables or fields are expected here!" ) ? static_cast<void> (0) : __assert_fail ("(VD || FD) && \"Only variables or fields are expected here!\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17559, __PRETTY_FUNCTION__)); | ||||||||
17560 | (void)FD; | ||||||||
17561 | |||||||||
17562 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] | ||||||||
17563 | // threadprivate variables cannot appear in a map clause. | ||||||||
17564 | // OpenMP 4.5 [2.10.5, target update Construct] | ||||||||
17565 | // threadprivate variables cannot appear in a from clause. | ||||||||
17566 | if (VD && DSAS->isThreadPrivate(VD)) { | ||||||||
17567 | DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); | ||||||||
17568 | SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) | ||||||||
17569 | << getOpenMPClauseName(CKind); | ||||||||
17570 | reportOriginalDsa(SemaRef, DSAS, VD, DVar); | ||||||||
17571 | continue; | ||||||||
17572 | } | ||||||||
17573 | |||||||||
17574 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] | ||||||||
17575 | // A list item cannot appear in both a map clause and a data-sharing | ||||||||
17576 | // attribute clause on the same construct. | ||||||||
17577 | |||||||||
17578 | // Check conflicts with other map clause expressions. We check the conflicts | ||||||||
17579 | // with the current construct separately from the enclosing data | ||||||||
17580 | // environment, because the restrictions are different. We only have to | ||||||||
17581 | // check conflicts across regions for the map clauses. | ||||||||
17582 | if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, | ||||||||
17583 | /*CurrentRegionOnly=*/true, CurComponents, CKind)) | ||||||||
17584 | break; | ||||||||
17585 | if (CKind == OMPC_map && | ||||||||
17586 | (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) && | ||||||||
17587 | checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, | ||||||||
17588 | /*CurrentRegionOnly=*/false, CurComponents, CKind)) | ||||||||
17589 | break; | ||||||||
17590 | |||||||||
17591 | // OpenMP 4.5 [2.10.5, target update Construct] | ||||||||
17592 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] | ||||||||
17593 | // If the type of a list item is a reference to a type T then the type will | ||||||||
17594 | // be considered to be T for all purposes of this clause. | ||||||||
17595 | auto I = llvm::find_if( | ||||||||
17596 | CurComponents, | ||||||||
17597 | [](const OMPClauseMappableExprCommon::MappableComponent &MC) { | ||||||||
17598 | return MC.getAssociatedDeclaration(); | ||||||||
17599 | }); | ||||||||
17600 | assert(I != CurComponents.end() && "Null decl on map clause.")((I != CurComponents.end() && "Null decl on map clause." ) ? static_cast<void> (0) : __assert_fail ("I != CurComponents.end() && \"Null decl on map clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17600, __PRETTY_FUNCTION__)); | ||||||||
17601 | QualType Type; | ||||||||
17602 | auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); | ||||||||
17603 | auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); | ||||||||
17604 | auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens()); | ||||||||
17605 | if (ASE) { | ||||||||
17606 | Type = ASE->getType().getNonReferenceType(); | ||||||||
17607 | } else if (OASE) { | ||||||||
17608 | QualType BaseType = | ||||||||
17609 | OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); | ||||||||
17610 | if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) | ||||||||
17611 | Type = ATy->getElementType(); | ||||||||
17612 | else | ||||||||
17613 | Type = BaseType->getPointeeType(); | ||||||||
17614 | Type = Type.getNonReferenceType(); | ||||||||
17615 | } else if (OAShE) { | ||||||||
17616 | Type = OAShE->getBase()->getType()->getPointeeType(); | ||||||||
17617 | } else { | ||||||||
17618 | Type = VE->getType(); | ||||||||
17619 | } | ||||||||
17620 | |||||||||
17621 | // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] | ||||||||
17622 | // A list item in a to or from clause must have a mappable type. | ||||||||
17623 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] | ||||||||
17624 | // A list item must have a mappable type. | ||||||||
17625 | if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, | ||||||||
17626 | DSAS, Type)) | ||||||||
17627 | continue; | ||||||||
17628 | |||||||||
17629 | Type = I->getAssociatedDeclaration()->getType().getNonReferenceType(); | ||||||||
17630 | |||||||||
17631 | if (CKind == OMPC_map) { | ||||||||
17632 | // target enter data | ||||||||
17633 | // OpenMP [2.10.2, Restrictions, p. 99] | ||||||||
17634 | // A map-type must be specified in all map clauses and must be either | ||||||||
17635 | // to or alloc. | ||||||||
17636 | OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); | ||||||||
17637 | if (DKind == OMPD_target_enter_data && | ||||||||
17638 | !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { | ||||||||
17639 | SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) | ||||||||
17640 | << (IsMapTypeImplicit ? 1 : 0) | ||||||||
17641 | << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) | ||||||||
17642 | << getOpenMPDirectiveName(DKind); | ||||||||
17643 | continue; | ||||||||
17644 | } | ||||||||
17645 | |||||||||
17646 | // target exit_data | ||||||||
17647 | // OpenMP [2.10.3, Restrictions, p. 102] | ||||||||
17648 | // A map-type must be specified in all map clauses and must be either | ||||||||
17649 | // from, release, or delete. | ||||||||
17650 | if (DKind == OMPD_target_exit_data && | ||||||||
17651 | !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || | ||||||||
17652 | MapType == OMPC_MAP_delete)) { | ||||||||
17653 | SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) | ||||||||
17654 | << (IsMapTypeImplicit ? 1 : 0) | ||||||||
17655 | << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) | ||||||||
17656 | << getOpenMPDirectiveName(DKind); | ||||||||
17657 | continue; | ||||||||
17658 | } | ||||||||
17659 | |||||||||
17660 | // target, target data | ||||||||
17661 | // OpenMP 5.0 [2.12.2, Restrictions, p. 163] | ||||||||
17662 | // OpenMP 5.0 [2.12.5, Restrictions, p. 174] | ||||||||
17663 | // A map-type in a map clause must be to, from, tofrom or alloc | ||||||||
17664 | if ((DKind == OMPD_target_data || | ||||||||
17665 | isOpenMPTargetExecutionDirective(DKind)) && | ||||||||
17666 | !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from || | ||||||||
17667 | MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) { | ||||||||
17668 | SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) | ||||||||
17669 | << (IsMapTypeImplicit ? 1 : 0) | ||||||||
17670 | << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) | ||||||||
17671 | << getOpenMPDirectiveName(DKind); | ||||||||
17672 | continue; | ||||||||
17673 | } | ||||||||
17674 | |||||||||
17675 | // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] | ||||||||
17676 | // A list item cannot appear in both a map clause and a data-sharing | ||||||||
17677 | // attribute clause on the same construct | ||||||||
17678 | // | ||||||||
17679 | // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] | ||||||||
17680 | // A list item cannot appear in both a map clause and a data-sharing | ||||||||
17681 | // attribute clause on the same construct unless the construct is a | ||||||||
17682 | // combined construct. | ||||||||
17683 | if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && | ||||||||
17684 | isOpenMPTargetExecutionDirective(DKind)) || | ||||||||
17685 | DKind == OMPD_target)) { | ||||||||
17686 | DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); | ||||||||
17687 | if (isOpenMPPrivate(DVar.CKind)) { | ||||||||
17688 | SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) | ||||||||
17689 | << getOpenMPClauseName(DVar.CKind) | ||||||||
17690 | << getOpenMPClauseName(OMPC_map) | ||||||||
17691 | << getOpenMPDirectiveName(DSAS->getCurrentDirective()); | ||||||||
17692 | reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); | ||||||||
17693 | continue; | ||||||||
17694 | } | ||||||||
17695 | } | ||||||||
17696 | } | ||||||||
17697 | |||||||||
17698 | // Try to find the associated user-defined mapper. | ||||||||
17699 | ExprResult ER = buildUserDefinedMapperRef( | ||||||||
17700 | SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, | ||||||||
17701 | Type.getCanonicalType(), UnresolvedMapper); | ||||||||
17702 | if (ER.isInvalid()) | ||||||||
17703 | continue; | ||||||||
17704 | MVLI.UDMapperList.push_back(ER.get()); | ||||||||
17705 | |||||||||
17706 | // Save the current expression. | ||||||||
17707 | MVLI.ProcessedVarList.push_back(RE); | ||||||||
17708 | |||||||||
17709 | // Store the components in the stack so that they can be used to check | ||||||||
17710 | // against other clauses later on. | ||||||||
17711 | DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, | ||||||||
17712 | /*WhereFoundClauseKind=*/OMPC_map); | ||||||||
17713 | |||||||||
17714 | // Save the components and declaration to create the clause. For purposes of | ||||||||
17715 | // the clause creation, any component list that has has base 'this' uses | ||||||||
17716 | // null as base declaration. | ||||||||
17717 | MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); | ||||||||
17718 | MVLI.VarComponents.back().append(CurComponents.begin(), | ||||||||
17719 | CurComponents.end()); | ||||||||
17720 | MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr | ||||||||
17721 | : CurDeclaration); | ||||||||
17722 | } | ||||||||
17723 | } | ||||||||
17724 | |||||||||
17725 | OMPClause *Sema::ActOnOpenMPMapClause( | ||||||||
17726 | ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, | ||||||||
17727 | ArrayRef<SourceLocation> MapTypeModifiersLoc, | ||||||||
17728 | CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, | ||||||||
17729 | OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, | ||||||||
17730 | SourceLocation ColonLoc, ArrayRef<Expr *> VarList, | ||||||||
17731 | const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { | ||||||||
17732 | OpenMPMapModifierKind Modifiers[] = { | ||||||||
17733 | OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, | ||||||||
17734 | OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown}; | ||||||||
17735 | SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers]; | ||||||||
17736 | |||||||||
17737 | // Process map-type-modifiers, flag errors for duplicate modifiers. | ||||||||
17738 | unsigned Count = 0; | ||||||||
17739 | for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { | ||||||||
17740 | if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && | ||||||||
17741 | llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { | ||||||||
17742 | Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); | ||||||||
17743 | continue; | ||||||||
17744 | } | ||||||||
17745 | assert(Count < NumberOfOMPMapClauseModifiers &&((Count < NumberOfOMPMapClauseModifiers && "Modifiers exceed the allowed number of map type modifiers" ) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMapClauseModifiers && \"Modifiers exceed the allowed number of map type modifiers\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17746, __PRETTY_FUNCTION__)) | ||||||||
17746 | "Modifiers exceed the allowed number of map type modifiers")((Count < NumberOfOMPMapClauseModifiers && "Modifiers exceed the allowed number of map type modifiers" ) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMapClauseModifiers && \"Modifiers exceed the allowed number of map type modifiers\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17746, __PRETTY_FUNCTION__)); | ||||||||
17747 | Modifiers[Count] = MapTypeModifiers[I]; | ||||||||
17748 | ModifiersLoc[Count] = MapTypeModifiersLoc[I]; | ||||||||
17749 | ++Count; | ||||||||
17750 | } | ||||||||
17751 | |||||||||
17752 | MappableVarListInfo MVLI(VarList); | ||||||||
17753 | checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), OMPC_map, MVLI, Locs.StartLoc, | ||||||||
17754 | MapperIdScopeSpec, MapperId, UnresolvedMappers, | ||||||||
17755 | MapType, IsMapTypeImplicit); | ||||||||
17756 | |||||||||
17757 | // We need to produce a map clause even if we don't have variables so that | ||||||||
17758 | // other diagnostics related with non-existing map clauses are accurate. | ||||||||
17759 | return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, | ||||||||
17760 | MVLI.VarBaseDeclarations, MVLI.VarComponents, | ||||||||
17761 | MVLI.UDMapperList, Modifiers, ModifiersLoc, | ||||||||
17762 | MapperIdScopeSpec.getWithLocInContext(Context), | ||||||||
17763 | MapperId, MapType, IsMapTypeImplicit, MapLoc); | ||||||||
17764 | } | ||||||||
17765 | |||||||||
17766 | QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, | ||||||||
17767 | TypeResult ParsedType) { | ||||||||
17768 | assert(ParsedType.isUsable())((ParsedType.isUsable()) ? static_cast<void> (0) : __assert_fail ("ParsedType.isUsable()", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 17768, __PRETTY_FUNCTION__)); | ||||||||
17769 | |||||||||
17770 | QualType ReductionType = GetTypeFromParser(ParsedType.get()); | ||||||||
17771 | if (ReductionType.isNull()) | ||||||||
17772 | return QualType(); | ||||||||
17773 | |||||||||
17774 | // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ | ||||||||
17775 | // A type name in a declare reduction directive cannot be a function type, an | ||||||||
17776 | // array type, a reference type, or a type qualified with const, volatile or | ||||||||
17777 | // restrict. | ||||||||
17778 | if (ReductionType.hasQualifiers()) { | ||||||||
17779 | Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; | ||||||||
17780 | return QualType(); | ||||||||
17781 | } | ||||||||
17782 | |||||||||
17783 | if (ReductionType->isFunctionType()) { | ||||||||
17784 | Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; | ||||||||
17785 | return QualType(); | ||||||||
17786 | } | ||||||||
17787 | if (ReductionType->isReferenceType()) { | ||||||||
17788 | Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; | ||||||||
17789 | return QualType(); | ||||||||
17790 | } | ||||||||
17791 | if (ReductionType->isArrayType()) { | ||||||||
17792 | Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; | ||||||||
17793 | return QualType(); | ||||||||
17794 | } | ||||||||
17795 | return ReductionType; | ||||||||
17796 | } | ||||||||
17797 | |||||||||
17798 | Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( | ||||||||
17799 | Scope *S, DeclContext *DC, DeclarationName Name, | ||||||||
17800 | ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, | ||||||||
17801 | AccessSpecifier AS, Decl *PrevDeclInScope) { | ||||||||
17802 | SmallVector<Decl *, 8> Decls; | ||||||||
17803 | Decls.reserve(ReductionTypes.size()); | ||||||||
17804 | |||||||||
17805 | LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, | ||||||||
17806 | forRedeclarationInCurContext()); | ||||||||
17807 | // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions | ||||||||
17808 | // A reduction-identifier may not be re-declared in the current scope for the | ||||||||
17809 | // same type or for a type that is compatible according to the base language | ||||||||
17810 | // rules. | ||||||||
17811 | llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; | ||||||||
17812 | OMPDeclareReductionDecl *PrevDRD = nullptr; | ||||||||
17813 | bool InCompoundScope = true; | ||||||||
17814 | if (S != nullptr) { | ||||||||
17815 | // Find previous declaration with the same name not referenced in other | ||||||||
17816 | // declarations. | ||||||||
17817 | FunctionScopeInfo *ParentFn = getEnclosingFunction(); | ||||||||
17818 | InCompoundScope = | ||||||||
17819 | (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); | ||||||||
17820 | LookupName(Lookup, S); | ||||||||
17821 | FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, | ||||||||
17822 | /*AllowInlineNamespace=*/false); | ||||||||
17823 | llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; | ||||||||
17824 | LookupResult::Filter Filter = Lookup.makeFilter(); | ||||||||
17825 | while (Filter.hasNext()) { | ||||||||
17826 | auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); | ||||||||
17827 | if (InCompoundScope) { | ||||||||
17828 | auto I = UsedAsPrevious.find(PrevDecl); | ||||||||
17829 | if (I == UsedAsPrevious.end()) | ||||||||
17830 | UsedAsPrevious[PrevDecl] = false; | ||||||||
17831 | if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) | ||||||||
17832 | UsedAsPrevious[D] = true; | ||||||||
17833 | } | ||||||||
17834 | PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = | ||||||||
17835 | PrevDecl->getLocation(); | ||||||||
17836 | } | ||||||||
17837 | Filter.done(); | ||||||||
17838 | if (InCompoundScope) { | ||||||||
17839 | for (const auto &PrevData : UsedAsPrevious) { | ||||||||
17840 | if (!PrevData.second) { | ||||||||
17841 | PrevDRD = PrevData.first; | ||||||||
17842 | break; | ||||||||
17843 | } | ||||||||
17844 | } | ||||||||
17845 | } | ||||||||
17846 | } else if (PrevDeclInScope != nullptr) { | ||||||||
17847 | auto *PrevDRDInScope = PrevDRD = | ||||||||
17848 | cast<OMPDeclareReductionDecl>(PrevDeclInScope); | ||||||||
17849 | do { | ||||||||
17850 | PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = | ||||||||
17851 | PrevDRDInScope->getLocation(); | ||||||||
17852 | PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); | ||||||||
17853 | } while (PrevDRDInScope != nullptr); | ||||||||
17854 | } | ||||||||
17855 | for (const auto &TyData : ReductionTypes) { | ||||||||
17856 | const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); | ||||||||
17857 | bool Invalid = false; | ||||||||
17858 | if (I != PreviousRedeclTypes.end()) { | ||||||||
17859 | Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) | ||||||||
17860 | << TyData.first; | ||||||||
17861 | Diag(I->second, diag::note_previous_definition); | ||||||||
17862 | Invalid = true; | ||||||||
17863 | } | ||||||||
17864 | PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; | ||||||||
17865 | auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, | ||||||||
17866 | Name, TyData.first, PrevDRD); | ||||||||
17867 | DC->addDecl(DRD); | ||||||||
17868 | DRD->setAccess(AS); | ||||||||
17869 | Decls.push_back(DRD); | ||||||||
17870 | if (Invalid) | ||||||||
17871 | DRD->setInvalidDecl(); | ||||||||
17872 | else | ||||||||
17873 | PrevDRD = DRD; | ||||||||
17874 | } | ||||||||
17875 | |||||||||
17876 | return DeclGroupPtrTy::make( | ||||||||
17877 | DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); | ||||||||
17878 | } | ||||||||
17879 | |||||||||
17880 | void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { | ||||||||
17881 | auto *DRD = cast<OMPDeclareReductionDecl>(D); | ||||||||
17882 | |||||||||
17883 | // Enter new function scope. | ||||||||
17884 | PushFunctionScope(); | ||||||||
17885 | setFunctionHasBranchProtectedScope(); | ||||||||
17886 | getCurFunction()->setHasOMPDeclareReductionCombiner(); | ||||||||
17887 | |||||||||
17888 | if (S != nullptr) | ||||||||
17889 | PushDeclContext(S, DRD); | ||||||||
17890 | else | ||||||||
17891 | CurContext = DRD; | ||||||||
17892 | |||||||||
17893 | PushExpressionEvaluationContext( | ||||||||
17894 | ExpressionEvaluationContext::PotentiallyEvaluated); | ||||||||
17895 | |||||||||
17896 | QualType ReductionType = DRD->getType(); | ||||||||
17897 | // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will | ||||||||
17898 | // be replaced by '*omp_parm' during codegen. This required because 'omp_in' | ||||||||
17899 | // uses semantics of argument handles by value, but it should be passed by | ||||||||
17900 | // reference. C lang does not support references, so pass all parameters as | ||||||||
17901 | // pointers. | ||||||||
17902 | // Create 'T omp_in;' variable. | ||||||||
17903 | VarDecl *OmpInParm = | ||||||||
17904 | buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); | ||||||||
17905 | // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will | ||||||||
17906 | // be replaced by '*omp_parm' during codegen. This required because 'omp_out' | ||||||||
17907 | // uses semantics of argument handles by value, but it should be passed by | ||||||||
17908 | // reference. C lang does not support references, so pass all parameters as | ||||||||
17909 | // pointers. | ||||||||
17910 | // Create 'T omp_out;' variable. | ||||||||
17911 | VarDecl *OmpOutParm = | ||||||||
17912 | buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); | ||||||||
17913 | if (S != nullptr) { | ||||||||
17914 | PushOnScopeChains(OmpInParm, S); | ||||||||
17915 | PushOnScopeChains(OmpOutParm, S); | ||||||||
17916 | } else { | ||||||||
17917 | DRD->addDecl(OmpInParm); | ||||||||
17918 | DRD->addDecl(OmpOutParm); | ||||||||
17919 | } | ||||||||
17920 | Expr *InE = | ||||||||
17921 | ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); | ||||||||
17922 | Expr *OutE = | ||||||||
17923 | ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); | ||||||||
17924 | DRD->setCombinerData(InE, OutE); | ||||||||
17925 | } | ||||||||
17926 | |||||||||
17927 | void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { | ||||||||
17928 | auto *DRD = cast<OMPDeclareReductionDecl>(D); | ||||||||
17929 | DiscardCleanupsInEvaluationContext(); | ||||||||
17930 | PopExpressionEvaluationContext(); | ||||||||
17931 | |||||||||
17932 | PopDeclContext(); | ||||||||
17933 | PopFunctionScopeInfo(); | ||||||||
17934 | |||||||||
17935 | if (Combiner != nullptr) | ||||||||
17936 | DRD->setCombiner(Combiner); | ||||||||
17937 | else | ||||||||
17938 | DRD->setInvalidDecl(); | ||||||||
17939 | } | ||||||||
17940 | |||||||||
17941 | VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { | ||||||||
17942 | auto *DRD = cast<OMPDeclareReductionDecl>(D); | ||||||||
17943 | |||||||||
17944 | // Enter new function scope. | ||||||||
17945 | PushFunctionScope(); | ||||||||
17946 | setFunctionHasBranchProtectedScope(); | ||||||||
17947 | |||||||||
17948 | if (S != nullptr) | ||||||||
17949 | PushDeclContext(S, DRD); | ||||||||
17950 | else | ||||||||
17951 | CurContext = DRD; | ||||||||
17952 | |||||||||
17953 | PushExpressionEvaluationContext( | ||||||||
17954 | ExpressionEvaluationContext::PotentiallyEvaluated); | ||||||||
17955 | |||||||||
17956 | QualType ReductionType = DRD->getType(); | ||||||||
17957 | // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will | ||||||||
17958 | // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' | ||||||||
17959 | // uses semantics of argument handles by value, but it should be passed by | ||||||||
17960 | // reference. C lang does not support references, so pass all parameters as | ||||||||
17961 | // pointers. | ||||||||
17962 | // Create 'T omp_priv;' variable. | ||||||||
17963 | VarDecl *OmpPrivParm = | ||||||||
17964 | buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); | ||||||||
17965 | // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will | ||||||||
17966 | // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' | ||||||||
17967 | // uses semantics of argument handles by value, but it should be passed by | ||||||||
17968 | // reference. C lang does not support references, so pass all parameters as | ||||||||
17969 | // pointers. | ||||||||
17970 | // Create 'T omp_orig;' variable. | ||||||||
17971 | VarDecl *OmpOrigParm = | ||||||||
17972 | buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); | ||||||||
17973 | if (S != nullptr) { | ||||||||
17974 | PushOnScopeChains(OmpPrivParm, S); | ||||||||
17975 | PushOnScopeChains(OmpOrigParm, S); | ||||||||
17976 | } else { | ||||||||
17977 | DRD->addDecl(OmpPrivParm); | ||||||||
17978 | DRD->addDecl(OmpOrigParm); | ||||||||
17979 | } | ||||||||
17980 | Expr *OrigE = | ||||||||
17981 | ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); | ||||||||
17982 | Expr *PrivE = | ||||||||
17983 | ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); | ||||||||
17984 | DRD->setInitializerData(OrigE, PrivE); | ||||||||
17985 | return OmpPrivParm; | ||||||||
17986 | } | ||||||||
17987 | |||||||||
17988 | void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, | ||||||||
17989 | VarDecl *OmpPrivParm) { | ||||||||
17990 | auto *DRD = cast<OMPDeclareReductionDecl>(D); | ||||||||
17991 | DiscardCleanupsInEvaluationContext(); | ||||||||
17992 | PopExpressionEvaluationContext(); | ||||||||
17993 | |||||||||
17994 | PopDeclContext(); | ||||||||
17995 | PopFunctionScopeInfo(); | ||||||||
17996 | |||||||||
17997 | if (Initializer != nullptr) { | ||||||||
17998 | DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); | ||||||||
17999 | } else if (OmpPrivParm->hasInit()) { | ||||||||
18000 | DRD->setInitializer(OmpPrivParm->getInit(), | ||||||||
18001 | OmpPrivParm->isDirectInit() | ||||||||
18002 | ? OMPDeclareReductionDecl::DirectInit | ||||||||
18003 | : OMPDeclareReductionDecl::CopyInit); | ||||||||
18004 | } else { | ||||||||
18005 | DRD->setInvalidDecl(); | ||||||||
18006 | } | ||||||||
18007 | } | ||||||||
18008 | |||||||||
18009 | Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( | ||||||||
18010 | Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { | ||||||||
18011 | for (Decl *D : DeclReductions.get()) { | ||||||||
18012 | if (IsValid) { | ||||||||
18013 | if (S) | ||||||||
18014 | PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, | ||||||||
18015 | /*AddToContext=*/false); | ||||||||
18016 | } else { | ||||||||
18017 | D->setInvalidDecl(); | ||||||||
18018 | } | ||||||||
18019 | } | ||||||||
18020 | return DeclReductions; | ||||||||
18021 | } | ||||||||
18022 | |||||||||
18023 | TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { | ||||||||
18024 | TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); | ||||||||
18025 | QualType T = TInfo->getType(); | ||||||||
18026 | if (D.isInvalidType()) | ||||||||
18027 | return true; | ||||||||
18028 | |||||||||
18029 | if (getLangOpts().CPlusPlus) { | ||||||||
18030 | // Check that there are no default arguments (C++ only). | ||||||||
18031 | CheckExtraCXXDefaultArguments(D); | ||||||||
18032 | } | ||||||||
18033 | |||||||||
18034 | return CreateParsedType(T, TInfo); | ||||||||
18035 | } | ||||||||
18036 | |||||||||
18037 | QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, | ||||||||
18038 | TypeResult ParsedType) { | ||||||||
18039 | assert(ParsedType.isUsable() && "Expect usable parsed mapper type")((ParsedType.isUsable() && "Expect usable parsed mapper type" ) ? static_cast<void> (0) : __assert_fail ("ParsedType.isUsable() && \"Expect usable parsed mapper type\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 18039, __PRETTY_FUNCTION__)); | ||||||||
18040 | |||||||||
18041 | QualType MapperType = GetTypeFromParser(ParsedType.get()); | ||||||||
18042 | assert(!MapperType.isNull() && "Expect valid mapper type")((!MapperType.isNull() && "Expect valid mapper type") ? static_cast<void> (0) : __assert_fail ("!MapperType.isNull() && \"Expect valid mapper type\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 18042, __PRETTY_FUNCTION__)); | ||||||||
18043 | |||||||||
18044 | // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions | ||||||||
18045 | // The type must be of struct, union or class type in C and C++ | ||||||||
18046 | if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { | ||||||||
18047 | Diag(TyLoc, diag::err_omp_mapper_wrong_type); | ||||||||
18048 | return QualType(); | ||||||||
18049 | } | ||||||||
18050 | return MapperType; | ||||||||
18051 | } | ||||||||
18052 | |||||||||
18053 | Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective( | ||||||||
18054 | Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, | ||||||||
18055 | SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, | ||||||||
18056 | Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) { | ||||||||
18057 | LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, | ||||||||
18058 | forRedeclarationInCurContext()); | ||||||||
18059 | // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions | ||||||||
18060 | // A mapper-identifier may not be redeclared in the current scope for the | ||||||||
18061 | // same type or for a type that is compatible according to the base language | ||||||||
18062 | // rules. | ||||||||
18063 | llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; | ||||||||
18064 | OMPDeclareMapperDecl *PrevDMD = nullptr; | ||||||||
18065 | bool InCompoundScope = true; | ||||||||
18066 | if (S != nullptr) { | ||||||||
18067 | // Find previous declaration with the same name not referenced in other | ||||||||
18068 | // declarations. | ||||||||
18069 | FunctionScopeInfo *ParentFn = getEnclosingFunction(); | ||||||||
18070 | InCompoundScope = | ||||||||
18071 | (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); | ||||||||
18072 | LookupName(Lookup, S); | ||||||||
18073 | FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, | ||||||||
18074 | /*AllowInlineNamespace=*/false); | ||||||||
18075 | llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; | ||||||||
18076 | LookupResult::Filter Filter = Lookup.makeFilter(); | ||||||||
18077 | while (Filter.hasNext()) { | ||||||||
18078 | auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); | ||||||||
18079 | if (InCompoundScope) { | ||||||||
18080 | auto I = UsedAsPrevious.find(PrevDecl); | ||||||||
18081 | if (I == UsedAsPrevious.end()) | ||||||||
18082 | UsedAsPrevious[PrevDecl] = false; | ||||||||
18083 | if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) | ||||||||
18084 | UsedAsPrevious[D] = true; | ||||||||
18085 | } | ||||||||
18086 | PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = | ||||||||
18087 | PrevDecl->getLocation(); | ||||||||
18088 | } | ||||||||
18089 | Filter.done(); | ||||||||
18090 | if (InCompoundScope) { | ||||||||
18091 | for (const auto &PrevData : UsedAsPrevious) { | ||||||||
18092 | if (!PrevData.second) { | ||||||||
18093 | PrevDMD = PrevData.first; | ||||||||
18094 | break; | ||||||||
18095 | } | ||||||||
18096 | } | ||||||||
18097 | } | ||||||||
18098 | } else if (PrevDeclInScope) { | ||||||||
18099 | auto *PrevDMDInScope = PrevDMD = | ||||||||
18100 | cast<OMPDeclareMapperDecl>(PrevDeclInScope); | ||||||||
18101 | do { | ||||||||
18102 | PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = | ||||||||
18103 | PrevDMDInScope->getLocation(); | ||||||||
18104 | PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); | ||||||||
18105 | } while (PrevDMDInScope != nullptr); | ||||||||
18106 | } | ||||||||
18107 | const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); | ||||||||
18108 | bool Invalid = false; | ||||||||
18109 | if (I != PreviousRedeclTypes.end()) { | ||||||||
18110 | Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) | ||||||||
18111 | << MapperType << Name; | ||||||||
18112 | Diag(I->second, diag::note_previous_definition); | ||||||||
18113 | Invalid = true; | ||||||||
18114 | } | ||||||||
18115 | auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, | ||||||||
18116 | MapperType, VN, Clauses, PrevDMD); | ||||||||
18117 | if (S) | ||||||||
18118 | PushOnScopeChains(DMD, S); | ||||||||
18119 | else | ||||||||
18120 | DC->addDecl(DMD); | ||||||||
18121 | DMD->setAccess(AS); | ||||||||
18122 | if (Invalid) | ||||||||
18123 | DMD->setInvalidDecl(); | ||||||||
18124 | |||||||||
18125 | auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl(); | ||||||||
18126 | VD->setDeclContext(DMD); | ||||||||
18127 | VD->setLexicalDeclContext(DMD); | ||||||||
18128 | DMD->addDecl(VD); | ||||||||
18129 | DMD->setMapperVarRef(MapperVarRef); | ||||||||
18130 | |||||||||
18131 | return DeclGroupPtrTy::make(DeclGroupRef(DMD)); | ||||||||
18132 | } | ||||||||
18133 | |||||||||
18134 | ExprResult | ||||||||
18135 | Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType, | ||||||||
18136 | SourceLocation StartLoc, | ||||||||
18137 | DeclarationName VN) { | ||||||||
18138 | TypeSourceInfo *TInfo = | ||||||||
18139 | Context.getTrivialTypeSourceInfo(MapperType, StartLoc); | ||||||||
18140 | auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(), | ||||||||
18141 | StartLoc, StartLoc, VN.getAsIdentifierInfo(), | ||||||||
18142 | MapperType, TInfo, SC_None); | ||||||||
18143 | if (S) | ||||||||
18144 | PushOnScopeChains(VD, S, /*AddToContext=*/false); | ||||||||
18145 | Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc); | ||||||||
18146 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDeclareMapperVarRef(E); | ||||||||
18147 | return E; | ||||||||
18148 | } | ||||||||
18149 | |||||||||
18150 | bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const { | ||||||||
18151 | assert(LangOpts.OpenMP && "Expected OpenMP mode.")((LangOpts.OpenMP && "Expected OpenMP mode.") ? static_cast <void> (0) : __assert_fail ("LangOpts.OpenMP && \"Expected OpenMP mode.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 18151, __PRETTY_FUNCTION__)); | ||||||||
18152 | const Expr *Ref = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDeclareMapperVarRef(); | ||||||||
18153 | if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) | ||||||||
18154 | return VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl(); | ||||||||
18155 | return true; | ||||||||
18156 | } | ||||||||
18157 | |||||||||
18158 | const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const { | ||||||||
18159 | assert(LangOpts.OpenMP && "Expected OpenMP mode.")((LangOpts.OpenMP && "Expected OpenMP mode.") ? static_cast <void> (0) : __assert_fail ("LangOpts.OpenMP && \"Expected OpenMP mode.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 18159, __PRETTY_FUNCTION__)); | ||||||||
18160 | return cast<DeclRefExpr>(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDeclareMapperVarRef())->getDecl(); | ||||||||
18161 | } | ||||||||
18162 | |||||||||
18163 | OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, | ||||||||
18164 | SourceLocation StartLoc, | ||||||||
18165 | SourceLocation LParenLoc, | ||||||||
18166 | SourceLocation EndLoc) { | ||||||||
18167 | Expr *ValExpr = NumTeams; | ||||||||
18168 | Stmt *HelperValStmt = nullptr; | ||||||||
18169 | |||||||||
18170 | // OpenMP [teams Constrcut, Restrictions] | ||||||||
18171 | // The num_teams expression must evaluate to a positive integer value. | ||||||||
18172 | if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, | ||||||||
18173 | /*StrictlyPositive=*/true)) | ||||||||
18174 | return nullptr; | ||||||||
18175 | |||||||||
18176 | OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); | ||||||||
18177 | OpenMPDirectiveKind CaptureRegion = | ||||||||
18178 | getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); | ||||||||
18179 | if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { | ||||||||
18180 | ValExpr = MakeFullExpr(ValExpr).get(); | ||||||||
18181 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; | ||||||||
18182 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); | ||||||||
18183 | HelperValStmt = buildPreInits(Context, Captures); | ||||||||
18184 | } | ||||||||
18185 | |||||||||
18186 | return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, | ||||||||
18187 | StartLoc, LParenLoc, EndLoc); | ||||||||
18188 | } | ||||||||
18189 | |||||||||
18190 | OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, | ||||||||
18191 | SourceLocation StartLoc, | ||||||||
18192 | SourceLocation LParenLoc, | ||||||||
18193 | SourceLocation EndLoc) { | ||||||||
18194 | Expr *ValExpr = ThreadLimit; | ||||||||
18195 | Stmt *HelperValStmt = nullptr; | ||||||||
18196 | |||||||||
18197 | // OpenMP [teams Constrcut, Restrictions] | ||||||||
18198 | // The thread_limit expression must evaluate to a positive integer value. | ||||||||
18199 | if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, | ||||||||
18200 | /*StrictlyPositive=*/true)) | ||||||||
18201 | return nullptr; | ||||||||
18202 | |||||||||
18203 | OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); | ||||||||
18204 | OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( | ||||||||
18205 | DKind, OMPC_thread_limit, LangOpts.OpenMP); | ||||||||
18206 | if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { | ||||||||
18207 | ValExpr = MakeFullExpr(ValExpr).get(); | ||||||||
18208 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; | ||||||||
18209 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); | ||||||||
18210 | HelperValStmt = buildPreInits(Context, Captures); | ||||||||
18211 | } | ||||||||
18212 | |||||||||
18213 | return new (Context) OMPThreadLimitClause( | ||||||||
18214 | ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); | ||||||||
18215 | } | ||||||||
18216 | |||||||||
18217 | OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, | ||||||||
18218 | SourceLocation StartLoc, | ||||||||
18219 | SourceLocation LParenLoc, | ||||||||
18220 | SourceLocation EndLoc) { | ||||||||
18221 | Expr *ValExpr = Priority; | ||||||||
18222 | Stmt *HelperValStmt = nullptr; | ||||||||
18223 | OpenMPDirectiveKind CaptureRegion = OMPD_unknown; | ||||||||
18224 | |||||||||
18225 | // OpenMP [2.9.1, task Constrcut] | ||||||||
18226 | // The priority-value is a non-negative numerical scalar expression. | ||||||||
18227 | if (!isNonNegativeIntegerValue( | ||||||||
18228 | ValExpr, *this, OMPC_priority, | ||||||||
18229 | /*StrictlyPositive=*/false, /*BuildCapture=*/true, | ||||||||
18230 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) | ||||||||
18231 | return nullptr; | ||||||||
18232 | |||||||||
18233 | return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, | ||||||||
18234 | StartLoc, LParenLoc, EndLoc); | ||||||||
18235 | } | ||||||||
18236 | |||||||||
18237 | OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, | ||||||||
18238 | SourceLocation StartLoc, | ||||||||
18239 | SourceLocation LParenLoc, | ||||||||
18240 | SourceLocation EndLoc) { | ||||||||
18241 | Expr *ValExpr = Grainsize; | ||||||||
18242 | Stmt *HelperValStmt = nullptr; | ||||||||
18243 | OpenMPDirectiveKind CaptureRegion = OMPD_unknown; | ||||||||
18244 | |||||||||
18245 | // OpenMP [2.9.2, taskloop Constrcut] | ||||||||
18246 | // The parameter of the grainsize clause must be a positive integer | ||||||||
18247 | // expression. | ||||||||
18248 | if (!isNonNegativeIntegerValue( | ||||||||
18249 | ValExpr, *this, OMPC_grainsize, | ||||||||
18250 | /*StrictlyPositive=*/true, /*BuildCapture=*/true, | ||||||||
18251 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) | ||||||||
18252 | return nullptr; | ||||||||
18253 | |||||||||
18254 | return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, | ||||||||
18255 | StartLoc, LParenLoc, EndLoc); | ||||||||
18256 | } | ||||||||
18257 | |||||||||
18258 | OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, | ||||||||
18259 | SourceLocation StartLoc, | ||||||||
18260 | SourceLocation LParenLoc, | ||||||||
18261 | SourceLocation EndLoc) { | ||||||||
18262 | Expr *ValExpr = NumTasks; | ||||||||
18263 | Stmt *HelperValStmt = nullptr; | ||||||||
18264 | OpenMPDirectiveKind CaptureRegion = OMPD_unknown; | ||||||||
18265 | |||||||||
18266 | // OpenMP [2.9.2, taskloop Constrcut] | ||||||||
18267 | // The parameter of the num_tasks clause must be a positive integer | ||||||||
18268 | // expression. | ||||||||
18269 | if (!isNonNegativeIntegerValue( | ||||||||
18270 | ValExpr, *this, OMPC_num_tasks, | ||||||||
18271 | /*StrictlyPositive=*/true, /*BuildCapture=*/true, | ||||||||
18272 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) | ||||||||
18273 | return nullptr; | ||||||||
18274 | |||||||||
18275 | return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, | ||||||||
18276 | StartLoc, LParenLoc, EndLoc); | ||||||||
18277 | } | ||||||||
18278 | |||||||||
18279 | OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, | ||||||||
18280 | SourceLocation LParenLoc, | ||||||||
18281 | SourceLocation EndLoc) { | ||||||||
18282 | // OpenMP [2.13.2, critical construct, Description] | ||||||||
18283 | // ... where hint-expression is an integer constant expression that evaluates | ||||||||
18284 | // to a valid lock hint. | ||||||||
18285 | ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); | ||||||||
18286 | if (HintExpr.isInvalid()) | ||||||||
18287 | return nullptr; | ||||||||
18288 | return new (Context) | ||||||||
18289 | OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); | ||||||||
18290 | } | ||||||||
18291 | |||||||||
18292 | /// Tries to find omp_event_handle_t type. | ||||||||
18293 | static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, | ||||||||
18294 | DSAStackTy *Stack) { | ||||||||
18295 | QualType OMPEventHandleT = Stack->getOMPEventHandleT(); | ||||||||
18296 | if (!OMPEventHandleT.isNull()) | ||||||||
18297 | return true; | ||||||||
18298 | IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t"); | ||||||||
18299 | ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); | ||||||||
18300 | if (!PT.getAsOpaquePtr() || PT.get().isNull()) { | ||||||||
18301 | S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t"; | ||||||||
18302 | return false; | ||||||||
18303 | } | ||||||||
18304 | Stack->setOMPEventHandleT(PT.get()); | ||||||||
18305 | return true; | ||||||||
18306 | } | ||||||||
18307 | |||||||||
18308 | OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, | ||||||||
18309 | SourceLocation LParenLoc, | ||||||||
18310 | SourceLocation EndLoc) { | ||||||||
18311 | if (!Evt->isValueDependent() && !Evt->isTypeDependent() && | ||||||||
18312 | !Evt->isInstantiationDependent() && | ||||||||
18313 | !Evt->containsUnexpandedParameterPack()) { | ||||||||
18314 | if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||||
18315 | return nullptr; | ||||||||
18316 | // OpenMP 5.0, 2.10.1 task Construct. | ||||||||
18317 | // event-handle is a variable of the omp_event_handle_t type. | ||||||||
18318 | auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts()); | ||||||||
18319 | if (!Ref) { | ||||||||
18320 | Diag(Evt->getExprLoc(), diag::err_omp_var_expected) | ||||||||
18321 | << "omp_event_handle_t" << 0 << Evt->getSourceRange(); | ||||||||
18322 | return nullptr; | ||||||||
18323 | } | ||||||||
18324 | auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl()); | ||||||||
18325 | if (!VD) { | ||||||||
18326 | Diag(Evt->getExprLoc(), diag::err_omp_var_expected) | ||||||||
18327 | << "omp_event_handle_t" << 0 << Evt->getSourceRange(); | ||||||||
18328 | return nullptr; | ||||||||
18329 | } | ||||||||
18330 | if (!Context.hasSameUnqualifiedType(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPEventHandleT(), | ||||||||
18331 | VD->getType()) || | ||||||||
18332 | VD->getType().isConstant(Context)) { | ||||||||
18333 | Diag(Evt->getExprLoc(), diag::err_omp_var_expected) | ||||||||
18334 | << "omp_event_handle_t" << 1 << VD->getType() | ||||||||
18335 | << Evt->getSourceRange(); | ||||||||
18336 | return nullptr; | ||||||||
18337 | } | ||||||||
18338 | // OpenMP 5.0, 2.10.1 task Construct | ||||||||
18339 | // [detach clause]... The event-handle will be considered as if it was | ||||||||
18340 | // specified on a firstprivate clause. | ||||||||
18341 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(VD, /*FromParent=*/false); | ||||||||
18342 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && | ||||||||
18343 | DVar.RefExpr) { | ||||||||
18344 | Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa) | ||||||||
18345 | << getOpenMPClauseName(DVar.CKind) | ||||||||
18346 | << getOpenMPClauseName(OMPC_firstprivate); | ||||||||
18347 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VD, DVar); | ||||||||
18348 | return nullptr; | ||||||||
18349 | } | ||||||||
18350 | } | ||||||||
18351 | |||||||||
18352 | return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc); | ||||||||
18353 | } | ||||||||
18354 | |||||||||
18355 | OMPClause *Sema::ActOnOpenMPDistScheduleClause( | ||||||||
18356 | OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, | ||||||||
18357 | SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, | ||||||||
18358 | SourceLocation EndLoc) { | ||||||||
18359 | if (Kind == OMPC_DIST_SCHEDULE_unknown) { | ||||||||
18360 | std::string Values; | ||||||||
18361 | Values += "'"; | ||||||||
18362 | Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); | ||||||||
18363 | Values += "'"; | ||||||||
18364 | Diag(KindLoc, diag::err_omp_unexpected_clause_value) | ||||||||
18365 | << Values << getOpenMPClauseName(OMPC_dist_schedule); | ||||||||
18366 | return nullptr; | ||||||||
18367 | } | ||||||||
18368 | Expr *ValExpr = ChunkSize; | ||||||||
18369 | Stmt *HelperValStmt = nullptr; | ||||||||
18370 | if (ChunkSize) { | ||||||||
18371 | if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && | ||||||||
18372 | !ChunkSize->isInstantiationDependent() && | ||||||||
18373 | !ChunkSize->containsUnexpandedParameterPack()) { | ||||||||
18374 | SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); | ||||||||
18375 | ExprResult Val = | ||||||||
18376 | PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); | ||||||||
18377 | if (Val.isInvalid()) | ||||||||
18378 | return nullptr; | ||||||||
18379 | |||||||||
18380 | ValExpr = Val.get(); | ||||||||
18381 | |||||||||
18382 | // OpenMP [2.7.1, Restrictions] | ||||||||
18383 | // chunk_size must be a loop invariant integer expression with a positive | ||||||||
18384 | // value. | ||||||||
18385 | if (Optional<llvm::APSInt> Result = | ||||||||
18386 | ValExpr->getIntegerConstantExpr(Context)) { | ||||||||
18387 | if (Result->isSigned() && !Result->isStrictlyPositive()) { | ||||||||
18388 | Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) | ||||||||
18389 | << "dist_schedule" << ChunkSize->getSourceRange(); | ||||||||
18390 | return nullptr; | ||||||||
18391 | } | ||||||||
18392 | } else if (getOpenMPCaptureRegionForClause( | ||||||||
18393 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(), OMPC_dist_schedule, | ||||||||
18394 | LangOpts.OpenMP) != OMPD_unknown && | ||||||||
18395 | !CurContext->isDependentContext()) { | ||||||||
18396 | ValExpr = MakeFullExpr(ValExpr).get(); | ||||||||
18397 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; | ||||||||
18398 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); | ||||||||
18399 | HelperValStmt = buildPreInits(Context, Captures); | ||||||||
18400 | } | ||||||||
18401 | } | ||||||||
18402 | } | ||||||||
18403 | |||||||||
18404 | return new (Context) | ||||||||
18405 | OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, | ||||||||
18406 | Kind, ValExpr, HelperValStmt); | ||||||||
18407 | } | ||||||||
18408 | |||||||||
18409 | OMPClause *Sema::ActOnOpenMPDefaultmapClause( | ||||||||
18410 | OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, | ||||||||
18411 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, | ||||||||
18412 | SourceLocation KindLoc, SourceLocation EndLoc) { | ||||||||
18413 | if (getLangOpts().OpenMP < 50) { | ||||||||
18414 | if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || | ||||||||
18415 | Kind != OMPC_DEFAULTMAP_scalar) { | ||||||||
18416 | std::string Value; | ||||||||
18417 | SourceLocation Loc; | ||||||||
18418 | Value += "'"; | ||||||||
18419 | if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { | ||||||||
18420 | Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, | ||||||||
18421 | OMPC_DEFAULTMAP_MODIFIER_tofrom); | ||||||||
18422 | Loc = MLoc; | ||||||||
18423 | } else { | ||||||||
18424 | Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, | ||||||||
18425 | OMPC_DEFAULTMAP_scalar); | ||||||||
18426 | Loc = KindLoc; | ||||||||
18427 | } | ||||||||
18428 | Value += "'"; | ||||||||
18429 | Diag(Loc, diag::err_omp_unexpected_clause_value) | ||||||||
18430 | << Value << getOpenMPClauseName(OMPC_defaultmap); | ||||||||
18431 | return nullptr; | ||||||||
18432 | } | ||||||||
18433 | } else { | ||||||||
18434 | bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); | ||||||||
18435 | bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) || | ||||||||
18436 | (LangOpts.OpenMP >= 50 && KindLoc.isInvalid()); | ||||||||
18437 | if (!isDefaultmapKind || !isDefaultmapModifier) { | ||||||||
18438 | std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', " | ||||||||
18439 | "'firstprivate', 'none', 'default'"; | ||||||||
18440 | std::string KindValue = "'scalar', 'aggregate', 'pointer'"; | ||||||||
18441 | if (!isDefaultmapKind && isDefaultmapModifier) { | ||||||||
18442 | Diag(KindLoc, diag::err_omp_unexpected_clause_value) | ||||||||
18443 | << KindValue << getOpenMPClauseName(OMPC_defaultmap); | ||||||||
18444 | } else if (isDefaultmapKind && !isDefaultmapModifier) { | ||||||||
18445 | Diag(MLoc, diag::err_omp_unexpected_clause_value) | ||||||||
18446 | << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); | ||||||||
18447 | } else { | ||||||||
18448 | Diag(MLoc, diag::err_omp_unexpected_clause_value) | ||||||||
18449 | << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); | ||||||||
18450 | Diag(KindLoc, diag::err_omp_unexpected_clause_value) | ||||||||
18451 | << KindValue << getOpenMPClauseName(OMPC_defaultmap); | ||||||||
18452 | } | ||||||||
18453 | return nullptr; | ||||||||
18454 | } | ||||||||
18455 | |||||||||
18456 | // OpenMP [5.0, 2.12.5, Restrictions, p. 174] | ||||||||
18457 | // At most one defaultmap clause for each category can appear on the | ||||||||
18458 | // directive. | ||||||||
18459 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->checkDefaultmapCategory(Kind)) { | ||||||||
18460 | Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); | ||||||||
18461 | return nullptr; | ||||||||
18462 | } | ||||||||
18463 | } | ||||||||
18464 | if (Kind == OMPC_DEFAULTMAP_unknown) { | ||||||||
18465 | // Variable category is not specified - mark all categories. | ||||||||
18466 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc); | ||||||||
18467 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc); | ||||||||
18468 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc); | ||||||||
18469 | } else { | ||||||||
18470 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setDefaultDMAAttr(M, Kind, StartLoc); | ||||||||
18471 | } | ||||||||
18472 | |||||||||
18473 | return new (Context) | ||||||||
18474 | OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); | ||||||||
18475 | } | ||||||||
18476 | |||||||||
18477 | bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { | ||||||||
18478 | DeclContext *CurLexicalContext = getCurLexicalContext(); | ||||||||
18479 | if (!CurLexicalContext->isFileContext() && | ||||||||
18480 | !CurLexicalContext->isExternCContext() && | ||||||||
18481 | !CurLexicalContext->isExternCXXContext() && | ||||||||
18482 | !isa<CXXRecordDecl>(CurLexicalContext) && | ||||||||
18483 | !isa<ClassTemplateDecl>(CurLexicalContext) && | ||||||||
18484 | !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && | ||||||||
18485 | !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { | ||||||||
18486 | Diag(Loc, diag::err_omp_region_not_file_context); | ||||||||
18487 | return false; | ||||||||
18488 | } | ||||||||
18489 | DeclareTargetNesting.push_back(Loc); | ||||||||
18490 | return true; | ||||||||
18491 | } | ||||||||
18492 | |||||||||
18493 | void Sema::ActOnFinishOpenMPDeclareTargetDirective() { | ||||||||
18494 | assert(!DeclareTargetNesting.empty() &&((!DeclareTargetNesting.empty() && "Unexpected ActOnFinishOpenMPDeclareTargetDirective" ) ? static_cast<void> (0) : __assert_fail ("!DeclareTargetNesting.empty() && \"Unexpected ActOnFinishOpenMPDeclareTargetDirective\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 18495, __PRETTY_FUNCTION__)) | ||||||||
18495 | "Unexpected ActOnFinishOpenMPDeclareTargetDirective")((!DeclareTargetNesting.empty() && "Unexpected ActOnFinishOpenMPDeclareTargetDirective" ) ? static_cast<void> (0) : __assert_fail ("!DeclareTargetNesting.empty() && \"Unexpected ActOnFinishOpenMPDeclareTargetDirective\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 18495, __PRETTY_FUNCTION__)); | ||||||||
18496 | DeclareTargetNesting.pop_back(); | ||||||||
18497 | } | ||||||||
18498 | |||||||||
18499 | NamedDecl * | ||||||||
18500 | Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, | ||||||||
18501 | const DeclarationNameInfo &Id, | ||||||||
18502 | NamedDeclSetType &SameDirectiveDecls) { | ||||||||
18503 | LookupResult Lookup(*this, Id, LookupOrdinaryName); | ||||||||
18504 | LookupParsedName(Lookup, CurScope, &ScopeSpec, true); | ||||||||
18505 | |||||||||
18506 | if (Lookup.isAmbiguous()) | ||||||||
18507 | return nullptr; | ||||||||
18508 | Lookup.suppressDiagnostics(); | ||||||||
18509 | |||||||||
18510 | if (!Lookup.isSingleResult()) { | ||||||||
18511 | VarOrFuncDeclFilterCCC CCC(*this); | ||||||||
18512 | if (TypoCorrection Corrected = | ||||||||
18513 | CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, | ||||||||
18514 | CTK_ErrorRecovery)) { | ||||||||
18515 | diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) | ||||||||
18516 | << Id.getName()); | ||||||||
18517 | checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); | ||||||||
18518 | return nullptr; | ||||||||
18519 | } | ||||||||
18520 | |||||||||
18521 | Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); | ||||||||
18522 | return nullptr; | ||||||||
18523 | } | ||||||||
18524 | |||||||||
18525 | NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); | ||||||||
18526 | if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && | ||||||||
18527 | !isa<FunctionTemplateDecl>(ND)) { | ||||||||
18528 | Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); | ||||||||
18529 | return nullptr; | ||||||||
18530 | } | ||||||||
18531 | if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) | ||||||||
18532 | Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); | ||||||||
18533 | return ND; | ||||||||
18534 | } | ||||||||
18535 | |||||||||
18536 | void Sema::ActOnOpenMPDeclareTargetName( | ||||||||
18537 | NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, | ||||||||
18538 | OMPDeclareTargetDeclAttr::DevTypeTy DT) { | ||||||||
18539 | assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||(((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa <FunctionTemplateDecl>(ND)) && "Expected variable, function or function template." ) ? static_cast<void> (0) : __assert_fail ("(isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa<FunctionTemplateDecl>(ND)) && \"Expected variable, function or function template.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 18541, __PRETTY_FUNCTION__)) | ||||||||
18540 | isa<FunctionTemplateDecl>(ND)) &&(((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa <FunctionTemplateDecl>(ND)) && "Expected variable, function or function template." ) ? static_cast<void> (0) : __assert_fail ("(isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa<FunctionTemplateDecl>(ND)) && \"Expected variable, function or function template.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 18541, __PRETTY_FUNCTION__)) | ||||||||
18541 | "Expected variable, function or function template.")(((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa <FunctionTemplateDecl>(ND)) && "Expected variable, function or function template." ) ? static_cast<void> (0) : __assert_fail ("(isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa<FunctionTemplateDecl>(ND)) && \"Expected variable, function or function template.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 18541, __PRETTY_FUNCTION__)); | ||||||||
18542 | |||||||||
18543 | // Diagnose marking after use as it may lead to incorrect diagnosis and | ||||||||
18544 | // codegen. | ||||||||
18545 | if (LangOpts.OpenMP >= 50 && | ||||||||
18546 | (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) | ||||||||
18547 | Diag(Loc, diag::warn_omp_declare_target_after_first_use); | ||||||||
18548 | |||||||||
18549 | auto *VD = cast<ValueDecl>(ND); | ||||||||
18550 | Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = | ||||||||
18551 | OMPDeclareTargetDeclAttr::getDeviceType(VD); | ||||||||
18552 | Optional<SourceLocation> AttrLoc = OMPDeclareTargetDeclAttr::getLocation(VD); | ||||||||
18553 | if (DevTy.hasValue() && *DevTy != DT && | ||||||||
18554 | (DeclareTargetNesting.empty() || | ||||||||
18555 | *AttrLoc != DeclareTargetNesting.back())) { | ||||||||
18556 | Diag(Loc, diag::err_omp_device_type_mismatch) | ||||||||
18557 | << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) | ||||||||
18558 | << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); | ||||||||
18559 | return; | ||||||||
18560 | } | ||||||||
18561 | Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = | ||||||||
18562 | OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); | ||||||||
18563 | if (!Res || (!DeclareTargetNesting.empty() && | ||||||||
18564 | *AttrLoc == DeclareTargetNesting.back())) { | ||||||||
18565 | auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( | ||||||||
18566 | Context, MT, DT, DeclareTargetNesting.size() + 1, | ||||||||
18567 | SourceRange(Loc, Loc)); | ||||||||
18568 | ND->addAttr(A); | ||||||||
18569 | if (ASTMutationListener *ML = Context.getASTMutationListener()) | ||||||||
18570 | ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); | ||||||||
18571 | checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); | ||||||||
18572 | } else if (*Res != MT) { | ||||||||
18573 | Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; | ||||||||
18574 | } | ||||||||
18575 | } | ||||||||
18576 | |||||||||
18577 | static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, | ||||||||
18578 | Sema &SemaRef, Decl *D) { | ||||||||
18579 | if (!D || !isa<VarDecl>(D)) | ||||||||
18580 | return; | ||||||||
18581 | auto *VD = cast<VarDecl>(D); | ||||||||
18582 | Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = | ||||||||
18583 | OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); | ||||||||
18584 | if (SemaRef.LangOpts.OpenMP >= 50 && | ||||||||
18585 | (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || | ||||||||
18586 | SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && | ||||||||
18587 | VD->hasGlobalStorage()) { | ||||||||
18588 | llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = | ||||||||
18589 | OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); | ||||||||
18590 | if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { | ||||||||
18591 | // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions | ||||||||
18592 | // If a lambda declaration and definition appears between a | ||||||||
18593 | // declare target directive and the matching end declare target | ||||||||
18594 | // directive, all variables that are captured by the lambda | ||||||||
18595 | // expression must also appear in a to clause. | ||||||||
18596 | SemaRef.Diag(VD->getLocation(), | ||||||||
18597 | diag::err_omp_lambda_capture_in_declare_target_not_to); | ||||||||
18598 | SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) | ||||||||
18599 | << VD << 0 << SR; | ||||||||
18600 | return; | ||||||||
18601 | } | ||||||||
18602 | } | ||||||||
18603 | if (MapTy.hasValue()) | ||||||||
18604 | return; | ||||||||
18605 | SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); | ||||||||
18606 | SemaRef.Diag(SL, diag::note_used_here) << SR; | ||||||||
18607 | } | ||||||||
18608 | |||||||||
18609 | static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, | ||||||||
18610 | Sema &SemaRef, DSAStackTy *Stack, | ||||||||
18611 | ValueDecl *VD) { | ||||||||
18612 | return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || | ||||||||
18613 | checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), | ||||||||
18614 | /*FullCheck=*/false); | ||||||||
18615 | } | ||||||||
18616 | |||||||||
18617 | void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, | ||||||||
18618 | SourceLocation IdLoc) { | ||||||||
18619 | if (!D || D->isInvalidDecl()) | ||||||||
18620 | return; | ||||||||
18621 | SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); | ||||||||
18622 | SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); | ||||||||
18623 | if (auto *VD = dyn_cast<VarDecl>(D)) { | ||||||||
18624 | // Only global variables can be marked as declare target. | ||||||||
18625 | if (!VD->isFileVarDecl() && !VD->isStaticLocal() && | ||||||||
18626 | !VD->isStaticDataMember()) | ||||||||
18627 | return; | ||||||||
18628 | // 2.10.6: threadprivate variable cannot appear in a declare target | ||||||||
18629 | // directive. | ||||||||
18630 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isThreadPrivate(VD)) { | ||||||||
18631 | Diag(SL, diag::err_omp_threadprivate_in_target); | ||||||||
18632 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VD, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(VD, false)); | ||||||||
18633 | return; | ||||||||
18634 | } | ||||||||
18635 | } | ||||||||
18636 | if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) | ||||||||
18637 | D = FTD->getTemplatedDecl(); | ||||||||
18638 | if (auto *FD = dyn_cast<FunctionDecl>(D)) { | ||||||||
18639 | llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = | ||||||||
18640 | OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); | ||||||||
18641 | if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { | ||||||||
18642 | Diag(IdLoc, diag::err_omp_function_in_link_clause); | ||||||||
18643 | Diag(FD->getLocation(), diag::note_defined_here) << FD; | ||||||||
18644 | return; | ||||||||
18645 | } | ||||||||
18646 | } | ||||||||
18647 | if (auto *VD = dyn_cast<ValueDecl>(D)) { | ||||||||
18648 | // Problem if any with var declared with incomplete type will be reported | ||||||||
18649 | // as normal, so no need to check it here. | ||||||||
18650 | if ((E || !VD->getType()->isIncompleteType()) && | ||||||||
18651 | !checkValueDeclInTarget(SL, SR, *this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VD)) | ||||||||
18652 | return; | ||||||||
18653 | if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { | ||||||||
18654 | // Checking declaration inside declare target region. | ||||||||
18655 | if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || | ||||||||
18656 | isa<FunctionTemplateDecl>(D)) { | ||||||||
18657 | auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( | ||||||||
18658 | Context, OMPDeclareTargetDeclAttr::MT_To, | ||||||||
18659 | OMPDeclareTargetDeclAttr::DT_Any, DeclareTargetNesting.size(), | ||||||||
18660 | SourceRange(DeclareTargetNesting.back(), | ||||||||
18661 | DeclareTargetNesting.back())); | ||||||||
18662 | D->addAttr(A); | ||||||||
18663 | if (ASTMutationListener *ML = Context.getASTMutationListener()) | ||||||||
18664 | ML->DeclarationMarkedOpenMPDeclareTarget(D, A); | ||||||||
18665 | } | ||||||||
18666 | return; | ||||||||
18667 | } | ||||||||
18668 | } | ||||||||
18669 | if (!E) | ||||||||
18670 | return; | ||||||||
18671 | checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); | ||||||||
18672 | } | ||||||||
18673 | |||||||||
18674 | OMPClause *Sema::ActOnOpenMPToClause( | ||||||||
18675 | ArrayRef<OpenMPMotionModifierKind> MotionModifiers, | ||||||||
18676 | ArrayRef<SourceLocation> MotionModifiersLoc, | ||||||||
18677 | CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, | ||||||||
18678 | SourceLocation ColonLoc, ArrayRef<Expr *> VarList, | ||||||||
18679 | const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { | ||||||||
18680 | OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, | ||||||||
18681 | OMPC_MOTION_MODIFIER_unknown}; | ||||||||
18682 | SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; | ||||||||
18683 | |||||||||
18684 | // Process motion-modifiers, flag errors for duplicate modifiers. | ||||||||
18685 | unsigned Count = 0; | ||||||||
18686 | for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { | ||||||||
18687 | if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && | ||||||||
18688 | llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) { | ||||||||
18689 | Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); | ||||||||
18690 | continue; | ||||||||
18691 | } | ||||||||
18692 | assert(Count < NumberOfOMPMotionModifiers &&((Count < NumberOfOMPMotionModifiers && "Modifiers exceed the allowed number of motion modifiers" ) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMotionModifiers && \"Modifiers exceed the allowed number of motion modifiers\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 18693, __PRETTY_FUNCTION__)) | ||||||||
18693 | "Modifiers exceed the allowed number of motion modifiers")((Count < NumberOfOMPMotionModifiers && "Modifiers exceed the allowed number of motion modifiers" ) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMotionModifiers && \"Modifiers exceed the allowed number of motion modifiers\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 18693, __PRETTY_FUNCTION__)); | ||||||||
18694 | Modifiers[Count] = MotionModifiers[I]; | ||||||||
18695 | ModifiersLoc[Count] = MotionModifiersLoc[I]; | ||||||||
18696 | ++Count; | ||||||||
18697 | } | ||||||||
18698 | |||||||||
18699 | MappableVarListInfo MVLI(VarList); | ||||||||
18700 | checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), OMPC_to, MVLI, Locs.StartLoc, | ||||||||
18701 | MapperIdScopeSpec, MapperId, UnresolvedMappers); | ||||||||
18702 | if (MVLI.ProcessedVarList.empty()) | ||||||||
18703 | return nullptr; | ||||||||
18704 | |||||||||
18705 | return OMPToClause::Create( | ||||||||
18706 | Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, | ||||||||
18707 | MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, | ||||||||
18708 | MapperIdScopeSpec.getWithLocInContext(Context), MapperId); | ||||||||
18709 | } | ||||||||
18710 | |||||||||
18711 | OMPClause *Sema::ActOnOpenMPFromClause( | ||||||||
18712 | ArrayRef<OpenMPMotionModifierKind> MotionModifiers, | ||||||||
18713 | ArrayRef<SourceLocation> MotionModifiersLoc, | ||||||||
18714 | CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, | ||||||||
18715 | SourceLocation ColonLoc, ArrayRef<Expr *> VarList, | ||||||||
18716 | const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { | ||||||||
18717 | OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, | ||||||||
18718 | OMPC_MOTION_MODIFIER_unknown}; | ||||||||
18719 | SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; | ||||||||
18720 | |||||||||
18721 | // Process motion-modifiers, flag errors for duplicate modifiers. | ||||||||
18722 | unsigned Count = 0; | ||||||||
18723 | for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { | ||||||||
18724 | if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && | ||||||||
18725 | llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) { | ||||||||
18726 | Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); | ||||||||
18727 | continue; | ||||||||
18728 | } | ||||||||
18729 | assert(Count < NumberOfOMPMotionModifiers &&((Count < NumberOfOMPMotionModifiers && "Modifiers exceed the allowed number of motion modifiers" ) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMotionModifiers && \"Modifiers exceed the allowed number of motion modifiers\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 18730, __PRETTY_FUNCTION__)) | ||||||||
18730 | "Modifiers exceed the allowed number of motion modifiers")((Count < NumberOfOMPMotionModifiers && "Modifiers exceed the allowed number of motion modifiers" ) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMotionModifiers && \"Modifiers exceed the allowed number of motion modifiers\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 18730, __PRETTY_FUNCTION__)); | ||||||||
18731 | Modifiers[Count] = MotionModifiers[I]; | ||||||||
18732 | ModifiersLoc[Count] = MotionModifiersLoc[I]; | ||||||||
18733 | ++Count; | ||||||||
18734 | } | ||||||||
18735 | |||||||||
18736 | MappableVarListInfo MVLI(VarList); | ||||||||
18737 | checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), OMPC_from, MVLI, Locs.StartLoc, | ||||||||
18738 | MapperIdScopeSpec, MapperId, UnresolvedMappers); | ||||||||
18739 | if (MVLI.ProcessedVarList.empty()) | ||||||||
18740 | return nullptr; | ||||||||
18741 | |||||||||
18742 | return OMPFromClause::Create( | ||||||||
18743 | Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, | ||||||||
18744 | MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, | ||||||||
18745 | MapperIdScopeSpec.getWithLocInContext(Context), MapperId); | ||||||||
18746 | } | ||||||||
18747 | |||||||||
18748 | OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, | ||||||||
18749 | const OMPVarListLocTy &Locs) { | ||||||||
18750 | MappableVarListInfo MVLI(VarList); | ||||||||
18751 | SmallVector<Expr *, 8> PrivateCopies; | ||||||||
18752 | SmallVector<Expr *, 8> Inits; | ||||||||
18753 | |||||||||
18754 | for (Expr *RefExpr : VarList) { | ||||||||
18755 | assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.")((RefExpr && "NULL expr in OpenMP use_device_ptr clause." ) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP use_device_ptr clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 18755, __PRETTY_FUNCTION__)); | ||||||||
18756 | SourceLocation ELoc; | ||||||||
18757 | SourceRange ERange; | ||||||||
18758 | Expr *SimpleRefExpr = RefExpr; | ||||||||
18759 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||||||
18760 | if (Res.second) { | ||||||||
18761 | // It will be analyzed later. | ||||||||
18762 | MVLI.ProcessedVarList.push_back(RefExpr); | ||||||||
18763 | PrivateCopies.push_back(nullptr); | ||||||||
18764 | Inits.push_back(nullptr); | ||||||||
18765 | } | ||||||||
18766 | ValueDecl *D = Res.first; | ||||||||
18767 | if (!D) | ||||||||
18768 | continue; | ||||||||
18769 | |||||||||
18770 | QualType Type = D->getType(); | ||||||||
18771 | Type = Type.getNonReferenceType().getUnqualifiedType(); | ||||||||
18772 | |||||||||
18773 | auto *VD = dyn_cast<VarDecl>(D); | ||||||||
18774 | |||||||||
18775 | // Item should be a pointer or reference to pointer. | ||||||||
18776 | if (!Type->isPointerType()) { | ||||||||
18777 | Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) | ||||||||
18778 | << 0 << RefExpr->getSourceRange(); | ||||||||
18779 | continue; | ||||||||
18780 | } | ||||||||
18781 | |||||||||
18782 | // Build the private variable and the expression that refers to it. | ||||||||
18783 | auto VDPrivate = | ||||||||
18784 | buildVarDecl(*this, ELoc, Type, D->getName(), | ||||||||
18785 | D->hasAttrs() ? &D->getAttrs() : nullptr, | ||||||||
18786 | VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); | ||||||||
18787 | if (VDPrivate->isInvalidDecl()) | ||||||||
18788 | continue; | ||||||||
18789 | |||||||||
18790 | CurContext->addDecl(VDPrivate); | ||||||||
18791 | DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( | ||||||||
18792 | *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); | ||||||||
18793 | |||||||||
18794 | // Add temporary variable to initialize the private copy of the pointer. | ||||||||
18795 | VarDecl *VDInit = | ||||||||
18796 | buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); | ||||||||
18797 | DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( | ||||||||
18798 | *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); | ||||||||
18799 | AddInitializerToDecl(VDPrivate, | ||||||||
18800 | DefaultLvalueConversion(VDInitRefExpr).get(), | ||||||||
18801 | /*DirectInit=*/false); | ||||||||
18802 | |||||||||
18803 | // If required, build a capture to implement the privatization initialized | ||||||||
18804 | // with the current list item value. | ||||||||
18805 | DeclRefExpr *Ref = nullptr; | ||||||||
18806 | if (!VD) | ||||||||
18807 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); | ||||||||
18808 | MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); | ||||||||
18809 | PrivateCopies.push_back(VDPrivateRefExpr); | ||||||||
18810 | Inits.push_back(VDInitRefExpr); | ||||||||
18811 | |||||||||
18812 | // We need to add a data sharing attribute for this variable to make sure it | ||||||||
18813 | // is correctly captured. A variable that shows up in a use_device_ptr has | ||||||||
18814 | // similar properties of a first private variable. | ||||||||
18815 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); | ||||||||
18816 | |||||||||
18817 | // Create a mappable component for the list item. List items in this clause | ||||||||
18818 | // only need a component. | ||||||||
18819 | MVLI.VarBaseDeclarations.push_back(D); | ||||||||
18820 | MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); | ||||||||
18821 | MVLI.VarComponents.back().push_back( | ||||||||
18822 | OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); | ||||||||
18823 | } | ||||||||
18824 | |||||||||
18825 | if (MVLI.ProcessedVarList.empty()) | ||||||||
18826 | return nullptr; | ||||||||
18827 | |||||||||
18828 | return OMPUseDevicePtrClause::Create( | ||||||||
18829 | Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, | ||||||||
18830 | MVLI.VarBaseDeclarations, MVLI.VarComponents); | ||||||||
18831 | } | ||||||||
18832 | |||||||||
18833 | OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList, | ||||||||
18834 | const OMPVarListLocTy &Locs) { | ||||||||
18835 | MappableVarListInfo MVLI(VarList); | ||||||||
18836 | |||||||||
18837 | for (Expr *RefExpr : VarList) { | ||||||||
18838 | assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.")((RefExpr && "NULL expr in OpenMP use_device_addr clause." ) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP use_device_addr clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 18838, __PRETTY_FUNCTION__)); | ||||||||
18839 | SourceLocation ELoc; | ||||||||
18840 | SourceRange ERange; | ||||||||
18841 | Expr *SimpleRefExpr = RefExpr; | ||||||||
18842 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, | ||||||||
18843 | /*AllowArraySection=*/true); | ||||||||
18844 | if (Res.second) { | ||||||||
18845 | // It will be analyzed later. | ||||||||
18846 | MVLI.ProcessedVarList.push_back(RefExpr); | ||||||||
18847 | } | ||||||||
18848 | ValueDecl *D = Res.first; | ||||||||
18849 | if (!D) | ||||||||
18850 | continue; | ||||||||
18851 | auto *VD = dyn_cast<VarDecl>(D); | ||||||||
18852 | |||||||||
18853 | // If required, build a capture to implement the privatization initialized | ||||||||
18854 | // with the current list item value. | ||||||||
18855 | DeclRefExpr *Ref = nullptr; | ||||||||
18856 | if (!VD) | ||||||||
18857 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); | ||||||||
18858 | MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); | ||||||||
18859 | |||||||||
18860 | // We need to add a data sharing attribute for this variable to make sure it | ||||||||
18861 | // is correctly captured. A variable that shows up in a use_device_addr has | ||||||||
18862 | // similar properties of a first private variable. | ||||||||
18863 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); | ||||||||
18864 | |||||||||
18865 | // Create a mappable component for the list item. List items in this clause | ||||||||
18866 | // only need a component. | ||||||||
18867 | MVLI.VarBaseDeclarations.push_back(D); | ||||||||
18868 | MVLI.VarComponents.emplace_back(); | ||||||||
18869 | Expr *Component = SimpleRefExpr; | ||||||||
18870 | if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) || | ||||||||
18871 | isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts()))) | ||||||||
18872 | Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get(); | ||||||||
18873 | MVLI.VarComponents.back().push_back( | ||||||||
18874 | OMPClauseMappableExprCommon::MappableComponent(Component, D)); | ||||||||
18875 | } | ||||||||
18876 | |||||||||
18877 | if (MVLI.ProcessedVarList.empty()) | ||||||||
18878 | return nullptr; | ||||||||
18879 | |||||||||
18880 | return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList, | ||||||||
18881 | MVLI.VarBaseDeclarations, | ||||||||
18882 | MVLI.VarComponents); | ||||||||
18883 | } | ||||||||
18884 | |||||||||
18885 | OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, | ||||||||
18886 | const OMPVarListLocTy &Locs) { | ||||||||
18887 | MappableVarListInfo MVLI(VarList); | ||||||||
18888 | for (Expr *RefExpr : VarList) { | ||||||||
18889 | assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.")((RefExpr && "NULL expr in OpenMP is_device_ptr clause." ) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP is_device_ptr clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 18889, __PRETTY_FUNCTION__)); | ||||||||
18890 | SourceLocation ELoc; | ||||||||
18891 | SourceRange ERange; | ||||||||
18892 | Expr *SimpleRefExpr = RefExpr; | ||||||||
18893 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||||||
18894 | if (Res.second) { | ||||||||
18895 | // It will be analyzed later. | ||||||||
18896 | MVLI.ProcessedVarList.push_back(RefExpr); | ||||||||
18897 | } | ||||||||
18898 | ValueDecl *D = Res.first; | ||||||||
18899 | if (!D) | ||||||||
18900 | continue; | ||||||||
18901 | |||||||||
18902 | QualType Type = D->getType(); | ||||||||
18903 | // item should be a pointer or array or reference to pointer or array | ||||||||
18904 | if (!Type.getNonReferenceType()->isPointerType() && | ||||||||
18905 | !Type.getNonReferenceType()->isArrayType()) { | ||||||||
18906 | Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) | ||||||||
18907 | << 0 << RefExpr->getSourceRange(); | ||||||||
18908 | continue; | ||||||||
18909 | } | ||||||||
18910 | |||||||||
18911 | // Check if the declaration in the clause does not show up in any data | ||||||||
18912 | // sharing attribute. | ||||||||
18913 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); | ||||||||
18914 | if (isOpenMPPrivate(DVar.CKind)) { | ||||||||
18915 | Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) | ||||||||
18916 | << getOpenMPClauseName(DVar.CKind) | ||||||||
18917 | << getOpenMPClauseName(OMPC_is_device_ptr) | ||||||||
18918 | << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()); | ||||||||
18919 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||||
18920 | continue; | ||||||||
18921 | } | ||||||||
18922 | |||||||||
18923 | const Expr *ConflictExpr; | ||||||||
18924 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->checkMappableExprComponentListsForDecl( | ||||||||
18925 | D, /*CurrentRegionOnly=*/true, | ||||||||
18926 | [&ConflictExpr]( | ||||||||
18927 | OMPClauseMappableExprCommon::MappableExprComponentListRef R, | ||||||||
18928 | OpenMPClauseKind) -> bool { | ||||||||
18929 | ConflictExpr = R.front().getAssociatedExpression(); | ||||||||
18930 | return true; | ||||||||
18931 | })) { | ||||||||
18932 | Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); | ||||||||
18933 | Diag(ConflictExpr->getExprLoc(), diag::note_used_here) | ||||||||
18934 | << ConflictExpr->getSourceRange(); | ||||||||
18935 | continue; | ||||||||
18936 | } | ||||||||
18937 | |||||||||
18938 | // Store the components in the stack so that they can be used to check | ||||||||
18939 | // against other clauses later on. | ||||||||
18940 | OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); | ||||||||
18941 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addMappableExpressionComponents( | ||||||||
18942 | D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); | ||||||||
18943 | |||||||||
18944 | // Record the expression we've just processed. | ||||||||
18945 | MVLI.ProcessedVarList.push_back(SimpleRefExpr); | ||||||||
18946 | |||||||||
18947 | // Create a mappable component for the list item. List items in this clause | ||||||||
18948 | // only need a component. We use a null declaration to signal fields in | ||||||||
18949 | // 'this'. | ||||||||
18950 | assert((isa<DeclRefExpr>(SimpleRefExpr) ||(((isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr >(cast<MemberExpr>(SimpleRefExpr)->getBase())) && "Unexpected device pointer expression!") ? static_cast<void > (0) : __assert_fail ("(isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 18952, __PRETTY_FUNCTION__)) | ||||||||
18951 | isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&(((isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr >(cast<MemberExpr>(SimpleRefExpr)->getBase())) && "Unexpected device pointer expression!") ? static_cast<void > (0) : __assert_fail ("(isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 18952, __PRETTY_FUNCTION__)) | ||||||||
18952 | "Unexpected device pointer expression!")(((isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr >(cast<MemberExpr>(SimpleRefExpr)->getBase())) && "Unexpected device pointer expression!") ? static_cast<void > (0) : __assert_fail ("(isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 18952, __PRETTY_FUNCTION__)); | ||||||||
18953 | MVLI.VarBaseDeclarations.push_back( | ||||||||
18954 | isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); | ||||||||
18955 | MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); | ||||||||
18956 | MVLI.VarComponents.back().push_back(MC); | ||||||||
18957 | } | ||||||||
18958 | |||||||||
18959 | if (MVLI.ProcessedVarList.empty()) | ||||||||
18960 | return nullptr; | ||||||||
18961 | |||||||||
18962 | return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, | ||||||||
18963 | MVLI.VarBaseDeclarations, | ||||||||
18964 | MVLI.VarComponents); | ||||||||
18965 | } | ||||||||
18966 | |||||||||
18967 | OMPClause *Sema::ActOnOpenMPAllocateClause( | ||||||||
18968 | Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, | ||||||||
18969 | SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { | ||||||||
18970 | if (Allocator) { | ||||||||
18971 | // OpenMP [2.11.4 allocate Clause, Description] | ||||||||
18972 | // allocator is an expression of omp_allocator_handle_t type. | ||||||||
18973 | if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||||
18974 | return nullptr; | ||||||||
18975 | |||||||||
18976 | ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); | ||||||||
18977 | if (AllocatorRes.isInvalid()) | ||||||||
18978 | return nullptr; | ||||||||
18979 | AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), | ||||||||
18980 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPAllocatorHandleT(), | ||||||||
18981 | Sema::AA_Initializing, | ||||||||
18982 | /*AllowExplicit=*/true); | ||||||||
18983 | if (AllocatorRes.isInvalid()) | ||||||||
18984 | return nullptr; | ||||||||
18985 | Allocator = AllocatorRes.get(); | ||||||||
18986 | } else { | ||||||||
18987 | // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. | ||||||||
18988 | // allocate clauses that appear on a target construct or on constructs in a | ||||||||
18989 | // target region must specify an allocator expression unless a requires | ||||||||
18990 | // directive with the dynamic_allocators clause is present in the same | ||||||||
18991 | // compilation unit. | ||||||||
18992 | if (LangOpts.OpenMPIsDevice && | ||||||||
18993 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) | ||||||||
18994 | targetDiag(StartLoc, diag::err_expected_allocator_expression); | ||||||||
18995 | } | ||||||||
18996 | // Analyze and build list of variables. | ||||||||
18997 | SmallVector<Expr *, 8> Vars; | ||||||||
18998 | for (Expr *RefExpr : VarList) { | ||||||||
18999 | 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.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 18999, __PRETTY_FUNCTION__)); | ||||||||
19000 | SourceLocation ELoc; | ||||||||
19001 | SourceRange ERange; | ||||||||
19002 | Expr *SimpleRefExpr = RefExpr; | ||||||||
19003 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||||||
19004 | if (Res.second) { | ||||||||
19005 | // It will be analyzed later. | ||||||||
19006 | Vars.push_back(RefExpr); | ||||||||
19007 | } | ||||||||
19008 | ValueDecl *D = Res.first; | ||||||||
19009 | if (!D) | ||||||||
19010 | continue; | ||||||||
19011 | |||||||||
19012 | auto *VD = dyn_cast<VarDecl>(D); | ||||||||
19013 | DeclRefExpr *Ref = nullptr; | ||||||||
19014 | if (!VD && !CurContext->isDependentContext()) | ||||||||
19015 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); | ||||||||
19016 | Vars.push_back((VD || CurContext->isDependentContext()) | ||||||||
19017 | ? RefExpr->IgnoreParens() | ||||||||
19018 | : Ref); | ||||||||
19019 | } | ||||||||
19020 | |||||||||
19021 | if (Vars.empty()) | ||||||||
19022 | return nullptr; | ||||||||
19023 | |||||||||
19024 | if (Allocator) | ||||||||
19025 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addInnerAllocatorExpr(Allocator); | ||||||||
19026 | return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, | ||||||||
19027 | ColonLoc, EndLoc, Vars); | ||||||||
19028 | } | ||||||||
19029 | |||||||||
19030 | OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, | ||||||||
19031 | SourceLocation StartLoc, | ||||||||
19032 | SourceLocation LParenLoc, | ||||||||
19033 | SourceLocation EndLoc) { | ||||||||
19034 | SmallVector<Expr *, 8> Vars; | ||||||||
19035 | for (Expr *RefExpr : VarList) { | ||||||||
19036 | assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")((RefExpr && "NULL expr in OpenMP nontemporal clause." ) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP nontemporal clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 19036, __PRETTY_FUNCTION__)); | ||||||||
19037 | SourceLocation ELoc; | ||||||||
19038 | SourceRange ERange; | ||||||||
19039 | Expr *SimpleRefExpr = RefExpr; | ||||||||
19040 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||||||
19041 | if (Res.second) | ||||||||
19042 | // It will be analyzed later. | ||||||||
19043 | Vars.push_back(RefExpr); | ||||||||
19044 | ValueDecl *D = Res.first; | ||||||||
19045 | if (!D) | ||||||||
19046 | continue; | ||||||||
19047 | |||||||||
19048 | // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. | ||||||||
19049 | // A list-item cannot appear in more than one nontemporal clause. | ||||||||
19050 | if (const Expr *PrevRef = | ||||||||
19051 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addUniqueNontemporal(D, SimpleRefExpr)) { | ||||||||
19052 | Diag(ELoc, diag::err_omp_used_in_clause_twice) | ||||||||
19053 | << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; | ||||||||
19054 | Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) | ||||||||
19055 | << getOpenMPClauseName(OMPC_nontemporal); | ||||||||
19056 | continue; | ||||||||
19057 | } | ||||||||
19058 | |||||||||
19059 | Vars.push_back(RefExpr); | ||||||||
19060 | } | ||||||||
19061 | |||||||||
19062 | if (Vars.empty()) | ||||||||
19063 | return nullptr; | ||||||||
19064 | |||||||||
19065 | return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, | ||||||||
19066 | Vars); | ||||||||
19067 | } | ||||||||
19068 | |||||||||
19069 | OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, | ||||||||
19070 | SourceLocation StartLoc, | ||||||||
19071 | SourceLocation LParenLoc, | ||||||||
19072 | SourceLocation EndLoc) { | ||||||||
19073 | SmallVector<Expr *, 8> Vars; | ||||||||
19074 | for (Expr *RefExpr : VarList) { | ||||||||
19075 | assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")((RefExpr && "NULL expr in OpenMP nontemporal clause." ) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP nontemporal clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 19075, __PRETTY_FUNCTION__)); | ||||||||
19076 | SourceLocation ELoc; | ||||||||
19077 | SourceRange ERange; | ||||||||
19078 | Expr *SimpleRefExpr = RefExpr; | ||||||||
19079 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, | ||||||||
19080 | /*AllowArraySection=*/true); | ||||||||
19081 | if (Res.second) | ||||||||
19082 | // It will be analyzed later. | ||||||||
19083 | Vars.push_back(RefExpr); | ||||||||
19084 | ValueDecl *D = Res.first; | ||||||||
19085 | if (!D) | ||||||||
19086 | continue; | ||||||||
19087 | |||||||||
19088 | const DSAStackTy::DSAVarData DVar = | ||||||||
19089 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/true); | ||||||||
19090 | // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. | ||||||||
19091 | // A list item that appears in the inclusive or exclusive clause must appear | ||||||||
19092 | // in a reduction clause with the inscan modifier on the enclosing | ||||||||
19093 | // worksharing-loop, worksharing-loop SIMD, or simd construct. | ||||||||
19094 | if (DVar.CKind != OMPC_reduction || | ||||||||
19095 | DVar.Modifier != OMPC_REDUCTION_inscan) | ||||||||
19096 | Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) | ||||||||
19097 | << RefExpr->getSourceRange(); | ||||||||
19098 | |||||||||
19099 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentDirective() != OMPD_unknown) | ||||||||
19100 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->markDeclAsUsedInScanDirective(D); | ||||||||
19101 | Vars.push_back(RefExpr); | ||||||||
19102 | } | ||||||||
19103 | |||||||||
19104 | if (Vars.empty()) | ||||||||
19105 | return nullptr; | ||||||||
19106 | |||||||||
19107 | return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); | ||||||||
19108 | } | ||||||||
19109 | |||||||||
19110 | OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList, | ||||||||
19111 | SourceLocation StartLoc, | ||||||||
19112 | SourceLocation LParenLoc, | ||||||||
19113 | SourceLocation EndLoc) { | ||||||||
19114 | SmallVector<Expr *, 8> Vars; | ||||||||
19115 | for (Expr *RefExpr : VarList) { | ||||||||
19116 | assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")((RefExpr && "NULL expr in OpenMP nontemporal clause." ) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP nontemporal clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 19116, __PRETTY_FUNCTION__)); | ||||||||
19117 | SourceLocation ELoc; | ||||||||
19118 | SourceRange ERange; | ||||||||
19119 | Expr *SimpleRefExpr = RefExpr; | ||||||||
19120 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, | ||||||||
19121 | /*AllowArraySection=*/true); | ||||||||
19122 | if (Res.second) | ||||||||
19123 | // It will be analyzed later. | ||||||||
19124 | Vars.push_back(RefExpr); | ||||||||
19125 | ValueDecl *D = Res.first; | ||||||||
19126 | if (!D) | ||||||||
19127 | continue; | ||||||||
19128 | |||||||||
19129 | OpenMPDirectiveKind ParentDirective = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentDirective(); | ||||||||
19130 | DSAStackTy::DSAVarData DVar; | ||||||||
19131 | if (ParentDirective != OMPD_unknown) | ||||||||
19132 | DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/true); | ||||||||
19133 | // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. | ||||||||
19134 | // A list item that appears in the inclusive or exclusive clause must appear | ||||||||
19135 | // in a reduction clause with the inscan modifier on the enclosing | ||||||||
19136 | // worksharing-loop, worksharing-loop SIMD, or simd construct. | ||||||||
19137 | if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction || | ||||||||
19138 | DVar.Modifier != OMPC_REDUCTION_inscan) { | ||||||||
19139 | Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) | ||||||||
19140 | << RefExpr->getSourceRange(); | ||||||||
19141 | } else { | ||||||||
19142 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->markDeclAsUsedInScanDirective(D); | ||||||||
19143 | } | ||||||||
19144 | Vars.push_back(RefExpr); | ||||||||
19145 | } | ||||||||
19146 | |||||||||
19147 | if (Vars.empty()) | ||||||||
19148 | return nullptr; | ||||||||
19149 | |||||||||
19150 | return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); | ||||||||
19151 | } | ||||||||
19152 | |||||||||
19153 | /// Tries to find omp_alloctrait_t type. | ||||||||
19154 | static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) { | ||||||||
19155 | QualType OMPAlloctraitT = Stack->getOMPAlloctraitT(); | ||||||||
19156 | if (!OMPAlloctraitT.isNull()) | ||||||||
19157 | return true; | ||||||||
19158 | IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t"); | ||||||||
19159 | ParsedType PT = S.getTypeName(II, Loc, S.getCurScope()); | ||||||||
19160 | if (!PT.getAsOpaquePtr() || PT.get().isNull()) { | ||||||||
19161 | S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t"; | ||||||||
19162 | return false; | ||||||||
19163 | } | ||||||||
19164 | Stack->setOMPAlloctraitT(PT.get()); | ||||||||
19165 | return true; | ||||||||
19166 | } | ||||||||
19167 | |||||||||
19168 | OMPClause *Sema::ActOnOpenMPUsesAllocatorClause( | ||||||||
19169 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, | ||||||||
19170 | ArrayRef<UsesAllocatorsData> Data) { | ||||||||
19171 | // OpenMP [2.12.5, target Construct] | ||||||||
19172 | // allocator is an identifier of omp_allocator_handle_t type. | ||||||||
19173 | if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||||
19174 | return nullptr; | ||||||||
19175 | // OpenMP [2.12.5, target Construct] | ||||||||
19176 | // allocator-traits-array is an identifier of const omp_alloctrait_t * type. | ||||||||
19177 | if (llvm::any_of( | ||||||||
19178 | Data, | ||||||||
19179 | [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) && | ||||||||
19180 | !findOMPAlloctraitT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||||
19181 | return nullptr; | ||||||||
19182 | llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators; | ||||||||
19183 | for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { | ||||||||
19184 | auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); | ||||||||
19185 | StringRef Allocator = | ||||||||
19186 | OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); | ||||||||
19187 | DeclarationName AllocatorName = &Context.Idents.get(Allocator); | ||||||||
19188 | PredefinedAllocators.insert(LookupSingleName( | ||||||||
19189 | TUScope, AllocatorName, StartLoc, Sema::LookupAnyName)); | ||||||||
19190 | } | ||||||||
19191 | |||||||||
19192 | SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData; | ||||||||
19193 | for (const UsesAllocatorsData &D : Data) { | ||||||||
19194 | Expr *AllocatorExpr = nullptr; | ||||||||
19195 | // Check allocator expression. | ||||||||
19196 | if (D.Allocator->isTypeDependent()) { | ||||||||
19197 | AllocatorExpr = D.Allocator; | ||||||||
19198 | } else { | ||||||||
19199 | // Traits were specified - need to assign new allocator to the specified | ||||||||
19200 | // allocator, so it must be an lvalue. | ||||||||
19201 | AllocatorExpr = D.Allocator->IgnoreParenImpCasts(); | ||||||||
19202 | auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr); | ||||||||
19203 | bool IsPredefinedAllocator = false; | ||||||||
19204 | if (DRE) | ||||||||
19205 | IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl()); | ||||||||
19206 | if (!DRE || | ||||||||
19207 | !(Context.hasSameUnqualifiedType( | ||||||||
19208 | AllocatorExpr->getType(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPAllocatorHandleT()) || | ||||||||
19209 | Context.typesAreCompatible(AllocatorExpr->getType(), | ||||||||
19210 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPAllocatorHandleT(), | ||||||||
19211 | /*CompareUnqualified=*/true)) || | ||||||||
19212 | (!IsPredefinedAllocator && | ||||||||
19213 | (AllocatorExpr->getType().isConstant(Context) || | ||||||||
19214 | !AllocatorExpr->isLValue()))) { | ||||||||
19215 | Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected) | ||||||||
19216 | << "omp_allocator_handle_t" << (DRE ? 1 : 0) | ||||||||
19217 | << AllocatorExpr->getType() << D.Allocator->getSourceRange(); | ||||||||
19218 | continue; | ||||||||
19219 | } | ||||||||
19220 | // OpenMP [2.12.5, target Construct] | ||||||||
19221 | // Predefined allocators appearing in a uses_allocators clause cannot have | ||||||||
19222 | // traits specified. | ||||||||
19223 | if (IsPredefinedAllocator && D.AllocatorTraits) { | ||||||||
19224 | Diag(D.AllocatorTraits->getExprLoc(), | ||||||||
19225 | diag::err_omp_predefined_allocator_with_traits) | ||||||||
19226 | << D.AllocatorTraits->getSourceRange(); | ||||||||
19227 | Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator) | ||||||||
19228 | << cast<NamedDecl>(DRE->getDecl())->getName() | ||||||||
19229 | << D.Allocator->getSourceRange(); | ||||||||
19230 | continue; | ||||||||
19231 | } | ||||||||
19232 | // OpenMP [2.12.5, target Construct] | ||||||||
19233 | // Non-predefined allocators appearing in a uses_allocators clause must | ||||||||
19234 | // have traits specified. | ||||||||
19235 | if (!IsPredefinedAllocator && !D.AllocatorTraits) { | ||||||||
19236 | Diag(D.Allocator->getExprLoc(), | ||||||||
19237 | diag::err_omp_nonpredefined_allocator_without_traits); | ||||||||
19238 | continue; | ||||||||
19239 | } | ||||||||
19240 | // No allocator traits - just convert it to rvalue. | ||||||||
19241 | if (!D.AllocatorTraits) | ||||||||
19242 | AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get(); | ||||||||
19243 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addUsesAllocatorsDecl( | ||||||||
19244 | DRE->getDecl(), | ||||||||
19245 | IsPredefinedAllocator | ||||||||
19246 | ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator | ||||||||
19247 | : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator); | ||||||||
19248 | } | ||||||||
19249 | Expr *AllocatorTraitsExpr = nullptr; | ||||||||
19250 | if (D.AllocatorTraits) { | ||||||||
19251 | if (D.AllocatorTraits->isTypeDependent()) { | ||||||||
19252 | AllocatorTraitsExpr = D.AllocatorTraits; | ||||||||
19253 | } else { | ||||||||
19254 | // OpenMP [2.12.5, target Construct] | ||||||||
19255 | // Arrays that contain allocator traits that appear in a uses_allocators | ||||||||
19256 | // clause must be constant arrays, have constant values and be defined | ||||||||
19257 | // in the same scope as the construct in which the clause appears. | ||||||||
19258 | AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts(); | ||||||||
19259 | // Check that traits expr is a constant array. | ||||||||
19260 | QualType TraitTy; | ||||||||
19261 | if (const ArrayType *Ty = | ||||||||
19262 | AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe()) | ||||||||
19263 | if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty)) | ||||||||
19264 | TraitTy = ConstArrayTy->getElementType(); | ||||||||
19265 | if (TraitTy.isNull() || | ||||||||
19266 | !(Context.hasSameUnqualifiedType(TraitTy, | ||||||||
19267 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPAlloctraitT()) || | ||||||||
19268 | Context.typesAreCompatible(TraitTy, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPAlloctraitT(), | ||||||||
19269 | /*CompareUnqualified=*/true))) { | ||||||||
19270 | Diag(D.AllocatorTraits->getExprLoc(), | ||||||||
19271 | diag::err_omp_expected_array_alloctraits) | ||||||||
19272 | << AllocatorTraitsExpr->getType(); | ||||||||
19273 | continue; | ||||||||
19274 | } | ||||||||
19275 | // Do not map by default allocator traits if it is a standalone | ||||||||
19276 | // variable. | ||||||||
19277 | if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr)) | ||||||||
19278 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addUsesAllocatorsDecl( | ||||||||
19279 | DRE->getDecl(), | ||||||||
19280 | DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait); | ||||||||
19281 | } | ||||||||
19282 | } | ||||||||
19283 | OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back(); | ||||||||
19284 | NewD.Allocator = AllocatorExpr; | ||||||||
19285 | NewD.AllocatorTraits = AllocatorTraitsExpr; | ||||||||
19286 | NewD.LParenLoc = D.LParenLoc; | ||||||||
19287 | NewD.RParenLoc = D.RParenLoc; | ||||||||
19288 | } | ||||||||
19289 | return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc, | ||||||||
19290 | NewData); | ||||||||
19291 | } | ||||||||
19292 | |||||||||
19293 | OMPClause *Sema::ActOnOpenMPAffinityClause( | ||||||||
19294 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, | ||||||||
19295 | SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) { | ||||||||
19296 | SmallVector<Expr *, 8> Vars; | ||||||||
19297 | for (Expr *RefExpr : Locators) { | ||||||||
19298 | 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.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp" , 19298, __PRETTY_FUNCTION__)); | ||||||||
19299 | if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) { | ||||||||
19300 | // It will be analyzed later. | ||||||||
19301 | Vars.push_back(RefExpr); | ||||||||
19302 | continue; | ||||||||
19303 | } | ||||||||
19304 | |||||||||
19305 | SourceLocation ELoc = RefExpr->getExprLoc(); | ||||||||
19306 | Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts(); | ||||||||
19307 | |||||||||
19308 | if (!SimpleExpr->isLValue()) { | ||||||||
19309 | Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) | ||||||||
19310 | << 1 << 0 << RefExpr->getSourceRange(); | ||||||||
19311 | continue; | ||||||||
19312 | } | ||||||||
19313 | |||||||||
19314 | ExprResult Res; | ||||||||
19315 | { | ||||||||
19316 | Sema::TentativeAnalysisScope Trap(*this); | ||||||||
19317 | Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr); | ||||||||
19318 | } | ||||||||
19319 | if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && | ||||||||
19320 | !isa<OMPArrayShapingExpr>(SimpleExpr)) { | ||||||||
19321 | Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) | ||||||||
19322 | << 1 << 0 << RefExpr->getSourceRange(); | ||||||||
19323 | continue; | ||||||||
19324 | } | ||||||||
19325 | Vars.push_back(SimpleExpr); | ||||||||
19326 | } | ||||||||
19327 | |||||||||
19328 | return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc, | ||||||||
19329 | EndLoc, Modifier, Vars); | ||||||||
19330 | } |
1 | //===- Decl.h - Classes for representing declarations -----------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file defines the Decl subclasses. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #ifndef LLVM_CLANG_AST_DECL_H |
14 | #define LLVM_CLANG_AST_DECL_H |
15 | |
16 | #include "clang/AST/APValue.h" |
17 | #include "clang/AST/ASTContextAllocate.h" |
18 | #include "clang/AST/DeclAccessPair.h" |
19 | #include "clang/AST/DeclBase.h" |
20 | #include "clang/AST/DeclarationName.h" |
21 | #include "clang/AST/ExternalASTSource.h" |
22 | #include "clang/AST/NestedNameSpecifier.h" |
23 | #include "clang/AST/Redeclarable.h" |
24 | #include "clang/AST/Type.h" |
25 | #include "clang/Basic/AddressSpaces.h" |
26 | #include "clang/Basic/Diagnostic.h" |
27 | #include "clang/Basic/IdentifierTable.h" |
28 | #include "clang/Basic/LLVM.h" |
29 | #include "clang/Basic/Linkage.h" |
30 | #include "clang/Basic/OperatorKinds.h" |
31 | #include "clang/Basic/PartialDiagnostic.h" |
32 | #include "clang/Basic/PragmaKinds.h" |
33 | #include "clang/Basic/SourceLocation.h" |
34 | #include "clang/Basic/Specifiers.h" |
35 | #include "clang/Basic/Visibility.h" |
36 | #include "llvm/ADT/APSInt.h" |
37 | #include "llvm/ADT/ArrayRef.h" |
38 | #include "llvm/ADT/Optional.h" |
39 | #include "llvm/ADT/PointerIntPair.h" |
40 | #include "llvm/ADT/PointerUnion.h" |
41 | #include "llvm/ADT/StringRef.h" |
42 | #include "llvm/ADT/iterator_range.h" |
43 | #include "llvm/Support/Casting.h" |
44 | #include "llvm/Support/Compiler.h" |
45 | #include "llvm/Support/TrailingObjects.h" |
46 | #include <cassert> |
47 | #include <cstddef> |
48 | #include <cstdint> |
49 | #include <string> |
50 | #include <utility> |
51 | |
52 | namespace clang { |
53 | |
54 | class ASTContext; |
55 | struct ASTTemplateArgumentListInfo; |
56 | class Attr; |
57 | class CompoundStmt; |
58 | class DependentFunctionTemplateSpecializationInfo; |
59 | class EnumDecl; |
60 | class Expr; |
61 | class FunctionTemplateDecl; |
62 | class FunctionTemplateSpecializationInfo; |
63 | class FunctionTypeLoc; |
64 | class LabelStmt; |
65 | class MemberSpecializationInfo; |
66 | class Module; |
67 | class NamespaceDecl; |
68 | class ParmVarDecl; |
69 | class RecordDecl; |
70 | class Stmt; |
71 | class StringLiteral; |
72 | class TagDecl; |
73 | class TemplateArgumentList; |
74 | class TemplateArgumentListInfo; |
75 | class TemplateParameterList; |
76 | class TypeAliasTemplateDecl; |
77 | class TypeLoc; |
78 | class UnresolvedSetImpl; |
79 | class VarTemplateDecl; |
80 | |
81 | /// The top declaration context. |
82 | class TranslationUnitDecl : public Decl, public DeclContext { |
83 | ASTContext &Ctx; |
84 | |
85 | /// The (most recently entered) anonymous namespace for this |
86 | /// translation unit, if one has been created. |
87 | NamespaceDecl *AnonymousNamespace = nullptr; |
88 | |
89 | explicit TranslationUnitDecl(ASTContext &ctx); |
90 | |
91 | virtual void anchor(); |
92 | |
93 | public: |
94 | ASTContext &getASTContext() const { return Ctx; } |
95 | |
96 | NamespaceDecl *getAnonymousNamespace() const { return AnonymousNamespace; } |
97 | void setAnonymousNamespace(NamespaceDecl *D) { AnonymousNamespace = D; } |
98 | |
99 | static TranslationUnitDecl *Create(ASTContext &C); |
100 | |
101 | // Implement isa/cast/dyncast/etc. |
102 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
103 | static bool classofKind(Kind K) { return K == TranslationUnit; } |
104 | static DeclContext *castToDeclContext(const TranslationUnitDecl *D) { |
105 | return static_cast<DeclContext *>(const_cast<TranslationUnitDecl*>(D)); |
106 | } |
107 | static TranslationUnitDecl *castFromDeclContext(const DeclContext *DC) { |
108 | return static_cast<TranslationUnitDecl *>(const_cast<DeclContext*>(DC)); |
109 | } |
110 | }; |
111 | |
112 | /// Represents a `#pragma comment` line. Always a child of |
113 | /// TranslationUnitDecl. |
114 | class PragmaCommentDecl final |
115 | : public Decl, |
116 | private llvm::TrailingObjects<PragmaCommentDecl, char> { |
117 | friend class ASTDeclReader; |
118 | friend class ASTDeclWriter; |
119 | friend TrailingObjects; |
120 | |
121 | PragmaMSCommentKind CommentKind; |
122 | |
123 | PragmaCommentDecl(TranslationUnitDecl *TU, SourceLocation CommentLoc, |
124 | PragmaMSCommentKind CommentKind) |
125 | : Decl(PragmaComment, TU, CommentLoc), CommentKind(CommentKind) {} |
126 | |
127 | virtual void anchor(); |
128 | |
129 | public: |
130 | static PragmaCommentDecl *Create(const ASTContext &C, TranslationUnitDecl *DC, |
131 | SourceLocation CommentLoc, |
132 | PragmaMSCommentKind CommentKind, |
133 | StringRef Arg); |
134 | static PragmaCommentDecl *CreateDeserialized(ASTContext &C, unsigned ID, |
135 | unsigned ArgSize); |
136 | |
137 | PragmaMSCommentKind getCommentKind() const { return CommentKind; } |
138 | |
139 | StringRef getArg() const { return getTrailingObjects<char>(); } |
140 | |
141 | // Implement isa/cast/dyncast/etc. |
142 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
143 | static bool classofKind(Kind K) { return K == PragmaComment; } |
144 | }; |
145 | |
146 | /// Represents a `#pragma detect_mismatch` line. Always a child of |
147 | /// TranslationUnitDecl. |
148 | class PragmaDetectMismatchDecl final |
149 | : public Decl, |
150 | private llvm::TrailingObjects<PragmaDetectMismatchDecl, char> { |
151 | friend class ASTDeclReader; |
152 | friend class ASTDeclWriter; |
153 | friend TrailingObjects; |
154 | |
155 | size_t ValueStart; |
156 | |
157 | PragmaDetectMismatchDecl(TranslationUnitDecl *TU, SourceLocation Loc, |
158 | size_t ValueStart) |
159 | : Decl(PragmaDetectMismatch, TU, Loc), ValueStart(ValueStart) {} |
160 | |
161 | virtual void anchor(); |
162 | |
163 | public: |
164 | static PragmaDetectMismatchDecl *Create(const ASTContext &C, |
165 | TranslationUnitDecl *DC, |
166 | SourceLocation Loc, StringRef Name, |
167 | StringRef Value); |
168 | static PragmaDetectMismatchDecl * |
169 | CreateDeserialized(ASTContext &C, unsigned ID, unsigned NameValueSize); |
170 | |
171 | StringRef getName() const { return getTrailingObjects<char>(); } |
172 | StringRef getValue() const { return getTrailingObjects<char>() + ValueStart; } |
173 | |
174 | // Implement isa/cast/dyncast/etc. |
175 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
176 | static bool classofKind(Kind K) { return K == PragmaDetectMismatch; } |
177 | }; |
178 | |
179 | /// Declaration context for names declared as extern "C" in C++. This |
180 | /// is neither the semantic nor lexical context for such declarations, but is |
181 | /// used to check for conflicts with other extern "C" declarations. Example: |
182 | /// |
183 | /// \code |
184 | /// namespace N { extern "C" void f(); } // #1 |
185 | /// void N::f() {} // #2 |
186 | /// namespace M { extern "C" void f(); } // #3 |
187 | /// \endcode |
188 | /// |
189 | /// The semantic context of #1 is namespace N and its lexical context is the |
190 | /// LinkageSpecDecl; the semantic context of #2 is namespace N and its lexical |
191 | /// context is the TU. However, both declarations are also visible in the |
192 | /// extern "C" context. |
193 | /// |
194 | /// The declaration at #3 finds it is a redeclaration of \c N::f through |
195 | /// lookup in the extern "C" context. |
196 | class ExternCContextDecl : public Decl, public DeclContext { |
197 | explicit ExternCContextDecl(TranslationUnitDecl *TU) |
198 | : Decl(ExternCContext, TU, SourceLocation()), |
199 | DeclContext(ExternCContext) {} |
200 | |
201 | virtual void anchor(); |
202 | |
203 | public: |
204 | static ExternCContextDecl *Create(const ASTContext &C, |
205 | TranslationUnitDecl *TU); |
206 | |
207 | // Implement isa/cast/dyncast/etc. |
208 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
209 | static bool classofKind(Kind K) { return K == ExternCContext; } |
210 | static DeclContext *castToDeclContext(const ExternCContextDecl *D) { |
211 | return static_cast<DeclContext *>(const_cast<ExternCContextDecl*>(D)); |
212 | } |
213 | static ExternCContextDecl *castFromDeclContext(const DeclContext *DC) { |
214 | return static_cast<ExternCContextDecl *>(const_cast<DeclContext*>(DC)); |
215 | } |
216 | }; |
217 | |
218 | /// This represents a decl that may have a name. Many decls have names such |
219 | /// as ObjCMethodDecl, but not \@class, etc. |
220 | /// |
221 | /// Note that not every NamedDecl is actually named (e.g., a struct might |
222 | /// be anonymous), and not every name is an identifier. |
223 | class NamedDecl : public Decl { |
224 | /// The name of this declaration, which is typically a normal |
225 | /// identifier but may also be a special kind of name (C++ |
226 | /// constructor, Objective-C selector, etc.) |
227 | DeclarationName Name; |
228 | |
229 | virtual void anchor(); |
230 | |
231 | private: |
232 | NamedDecl *getUnderlyingDeclImpl() LLVM_READONLY__attribute__((__pure__)); |
233 | |
234 | protected: |
235 | NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N) |
236 | : Decl(DK, DC, L), Name(N) {} |
237 | |
238 | public: |
239 | /// Get the identifier that names this declaration, if there is one. |
240 | /// |
241 | /// This will return NULL if this declaration has no name (e.g., for |
242 | /// an unnamed class) or if the name is a special name (C++ constructor, |
243 | /// Objective-C selector, etc.). |
244 | IdentifierInfo *getIdentifier() const { return Name.getAsIdentifierInfo(); } |
245 | |
246 | /// Get the name of identifier for this declaration as a StringRef. |
247 | /// |
248 | /// This requires that the declaration have a name and that it be a simple |
249 | /// identifier. |
250 | StringRef getName() const { |
251 | assert(Name.isIdentifier() && "Name is not a simple identifier")((Name.isIdentifier() && "Name is not a simple identifier" ) ? static_cast<void> (0) : __assert_fail ("Name.isIdentifier() && \"Name is not a simple identifier\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 251, __PRETTY_FUNCTION__)); |
252 | return getIdentifier() ? getIdentifier()->getName() : ""; |
253 | } |
254 | |
255 | /// Get a human-readable name for the declaration, even if it is one of the |
256 | /// special kinds of names (C++ constructor, Objective-C selector, etc). |
257 | /// |
258 | /// Creating this name requires expensive string manipulation, so it should |
259 | /// be called only when performance doesn't matter. For simple declarations, |
260 | /// getNameAsCString() should suffice. |
261 | // |
262 | // FIXME: This function should be renamed to indicate that it is not just an |
263 | // alternate form of getName(), and clients should move as appropriate. |
264 | // |
265 | // FIXME: Deprecated, move clients to getName(). |
266 | std::string getNameAsString() const { return Name.getAsString(); } |
267 | |
268 | /// Pretty-print the unqualified name of this declaration. Can be overloaded |
269 | /// by derived classes to provide a more user-friendly name when appropriate. |
270 | virtual void printName(raw_ostream &os) const; |
271 | |
272 | /// Get the actual, stored name of the declaration, which may be a special |
273 | /// name. |
274 | /// |
275 | /// Note that generally in diagnostics, the non-null \p NamedDecl* itself |
276 | /// should be sent into the diagnostic instead of using the result of |
277 | /// \p getDeclName(). |
278 | /// |
279 | /// A \p DeclarationName in a diagnostic will just be streamed to the output, |
280 | /// which will directly result in a call to \p DeclarationName::print. |
281 | /// |
282 | /// A \p NamedDecl* in a diagnostic will also ultimately result in a call to |
283 | /// \p DeclarationName::print, but with two customisation points along the |
284 | /// way (\p getNameForDiagnostic and \p printName). These are used to print |
285 | /// the template arguments if any, and to provide a user-friendly name for |
286 | /// some entities (such as unnamed variables and anonymous records). |
287 | DeclarationName getDeclName() const { return Name; } |
288 | |
289 | /// Set the name of this declaration. |
290 | void setDeclName(DeclarationName N) { Name = N; } |
291 | |
292 | /// Returns a human-readable qualified name for this declaration, like |
293 | /// A::B::i, for i being member of namespace A::B. |
294 | /// |
295 | /// If the declaration is not a member of context which can be named (record, |
296 | /// namespace), it will return the same result as printName(). |
297 | /// |
298 | /// Creating this name is expensive, so it should be called only when |
299 | /// performance doesn't matter. |
300 | void printQualifiedName(raw_ostream &OS) const; |
301 | void printQualifiedName(raw_ostream &OS, const PrintingPolicy &Policy) const; |
302 | |
303 | /// Print only the nested name specifier part of a fully-qualified name, |
304 | /// including the '::' at the end. E.g. |
305 | /// when `printQualifiedName(D)` prints "A::B::i", |
306 | /// this function prints "A::B::". |
307 | void printNestedNameSpecifier(raw_ostream &OS) const; |
308 | void printNestedNameSpecifier(raw_ostream &OS, |
309 | const PrintingPolicy &Policy) const; |
310 | |
311 | // FIXME: Remove string version. |
312 | std::string getQualifiedNameAsString() const; |
313 | |
314 | /// Appends a human-readable name for this declaration into the given stream. |
315 | /// |
316 | /// This is the method invoked by Sema when displaying a NamedDecl |
317 | /// in a diagnostic. It does not necessarily produce the same |
318 | /// result as printName(); for example, class template |
319 | /// specializations are printed with their template arguments. |
320 | virtual void getNameForDiagnostic(raw_ostream &OS, |
321 | const PrintingPolicy &Policy, |
322 | bool Qualified) const; |
323 | |
324 | /// Determine whether this declaration, if known to be well-formed within |
325 | /// its context, will replace the declaration OldD if introduced into scope. |
326 | /// |
327 | /// A declaration will replace another declaration if, for example, it is |
328 | /// a redeclaration of the same variable or function, but not if it is a |
329 | /// declaration of a different kind (function vs. class) or an overloaded |
330 | /// function. |
331 | /// |
332 | /// \param IsKnownNewer \c true if this declaration is known to be newer |
333 | /// than \p OldD (for instance, if this declaration is newly-created). |
334 | bool declarationReplaces(NamedDecl *OldD, bool IsKnownNewer = true) const; |
335 | |
336 | /// Determine whether this declaration has linkage. |
337 | bool hasLinkage() const; |
338 | |
339 | using Decl::isModulePrivate; |
340 | using Decl::setModulePrivate; |
341 | |
342 | /// Determine whether this declaration is a C++ class member. |
343 | bool isCXXClassMember() const { |
344 | const DeclContext *DC = getDeclContext(); |
345 | |
346 | // C++0x [class.mem]p1: |
347 | // The enumerators of an unscoped enumeration defined in |
348 | // the class are members of the class. |
349 | if (isa<EnumDecl>(DC)) |
350 | DC = DC->getRedeclContext(); |
351 | |
352 | return DC->isRecord(); |
353 | } |
354 | |
355 | /// Determine whether the given declaration is an instance member of |
356 | /// a C++ class. |
357 | bool isCXXInstanceMember() const; |
358 | |
359 | /// Determine what kind of linkage this entity has. |
360 | /// |
361 | /// This is not the linkage as defined by the standard or the codegen notion |
362 | /// of linkage. It is just an implementation detail that is used to compute |
363 | /// those. |
364 | Linkage getLinkageInternal() const; |
365 | |
366 | /// Get the linkage from a semantic point of view. Entities in |
367 | /// anonymous namespaces are external (in c++98). |
368 | Linkage getFormalLinkage() const { |
369 | return clang::getFormalLinkage(getLinkageInternal()); |
370 | } |
371 | |
372 | /// True if this decl has external linkage. |
373 | bool hasExternalFormalLinkage() const { |
374 | return isExternalFormalLinkage(getLinkageInternal()); |
375 | } |
376 | |
377 | bool isExternallyVisible() const { |
378 | return clang::isExternallyVisible(getLinkageInternal()); |
379 | } |
380 | |
381 | /// Determine whether this declaration can be redeclared in a |
382 | /// different translation unit. |
383 | bool isExternallyDeclarable() const { |
384 | return isExternallyVisible() && !getOwningModuleForLinkage(); |
385 | } |
386 | |
387 | /// Determines the visibility of this entity. |
388 | Visibility getVisibility() const { |
389 | return getLinkageAndVisibility().getVisibility(); |
390 | } |
391 | |
392 | /// Determines the linkage and visibility of this entity. |
393 | LinkageInfo getLinkageAndVisibility() const; |
394 | |
395 | /// Kinds of explicit visibility. |
396 | enum ExplicitVisibilityKind { |
397 | /// Do an LV computation for, ultimately, a type. |
398 | /// Visibility may be restricted by type visibility settings and |
399 | /// the visibility of template arguments. |
400 | VisibilityForType, |
401 | |
402 | /// Do an LV computation for, ultimately, a non-type declaration. |
403 | /// Visibility may be restricted by value visibility settings and |
404 | /// the visibility of template arguments. |
405 | VisibilityForValue |
406 | }; |
407 | |
408 | /// If visibility was explicitly specified for this |
409 | /// declaration, return that visibility. |
410 | Optional<Visibility> |
411 | getExplicitVisibility(ExplicitVisibilityKind kind) const; |
412 | |
413 | /// True if the computed linkage is valid. Used for consistency |
414 | /// checking. Should always return true. |
415 | bool isLinkageValid() const; |
416 | |
417 | /// True if something has required us to compute the linkage |
418 | /// of this declaration. |
419 | /// |
420 | /// Language features which can retroactively change linkage (like a |
421 | /// typedef name for linkage purposes) may need to consider this, |
422 | /// but hopefully only in transitory ways during parsing. |
423 | bool hasLinkageBeenComputed() const { |
424 | return hasCachedLinkage(); |
425 | } |
426 | |
427 | /// Looks through UsingDecls and ObjCCompatibleAliasDecls for |
428 | /// the underlying named decl. |
429 | NamedDecl *getUnderlyingDecl() { |
430 | // Fast-path the common case. |
431 | if (this->getKind() != UsingShadow && |
432 | this->getKind() != ConstructorUsingShadow && |
433 | this->getKind() != ObjCCompatibleAlias && |
434 | this->getKind() != NamespaceAlias) |
435 | return this; |
436 | |
437 | return getUnderlyingDeclImpl(); |
438 | } |
439 | const NamedDecl *getUnderlyingDecl() const { |
440 | return const_cast<NamedDecl*>(this)->getUnderlyingDecl(); |
441 | } |
442 | |
443 | NamedDecl *getMostRecentDecl() { |
444 | return cast<NamedDecl>(static_cast<Decl *>(this)->getMostRecentDecl()); |
445 | } |
446 | const NamedDecl *getMostRecentDecl() const { |
447 | return const_cast<NamedDecl*>(this)->getMostRecentDecl(); |
448 | } |
449 | |
450 | ObjCStringFormatFamily getObjCFStringFormattingFamily() const; |
451 | |
452 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
453 | static bool classofKind(Kind K) { return K >= firstNamed && K <= lastNamed; } |
454 | }; |
455 | |
456 | inline raw_ostream &operator<<(raw_ostream &OS, const NamedDecl &ND) { |
457 | ND.printName(OS); |
458 | return OS; |
459 | } |
460 | |
461 | /// Represents the declaration of a label. Labels also have a |
462 | /// corresponding LabelStmt, which indicates the position that the label was |
463 | /// defined at. For normal labels, the location of the decl is the same as the |
464 | /// location of the statement. For GNU local labels (__label__), the decl |
465 | /// location is where the __label__ is. |
466 | class LabelDecl : public NamedDecl { |
467 | LabelStmt *TheStmt; |
468 | StringRef MSAsmName; |
469 | bool MSAsmNameResolved = false; |
470 | |
471 | /// For normal labels, this is the same as the main declaration |
472 | /// label, i.e., the location of the identifier; for GNU local labels, |
473 | /// this is the location of the __label__ keyword. |
474 | SourceLocation LocStart; |
475 | |
476 | LabelDecl(DeclContext *DC, SourceLocation IdentL, IdentifierInfo *II, |
477 | LabelStmt *S, SourceLocation StartL) |
478 | : NamedDecl(Label, DC, IdentL, II), TheStmt(S), LocStart(StartL) {} |
479 | |
480 | void anchor() override; |
481 | |
482 | public: |
483 | static LabelDecl *Create(ASTContext &C, DeclContext *DC, |
484 | SourceLocation IdentL, IdentifierInfo *II); |
485 | static LabelDecl *Create(ASTContext &C, DeclContext *DC, |
486 | SourceLocation IdentL, IdentifierInfo *II, |
487 | SourceLocation GnuLabelL); |
488 | static LabelDecl *CreateDeserialized(ASTContext &C, unsigned ID); |
489 | |
490 | LabelStmt *getStmt() const { return TheStmt; } |
491 | void setStmt(LabelStmt *T) { TheStmt = T; } |
492 | |
493 | bool isGnuLocal() const { return LocStart != getLocation(); } |
494 | void setLocStart(SourceLocation L) { LocStart = L; } |
495 | |
496 | SourceRange getSourceRange() const override LLVM_READONLY__attribute__((__pure__)) { |
497 | return SourceRange(LocStart, getLocation()); |
498 | } |
499 | |
500 | bool isMSAsmLabel() const { return !MSAsmName.empty(); } |
501 | bool isResolvedMSAsmLabel() const { return isMSAsmLabel() && MSAsmNameResolved; } |
502 | void setMSAsmLabel(StringRef Name); |
503 | StringRef getMSAsmLabel() const { return MSAsmName; } |
504 | void setMSAsmLabelResolved() { MSAsmNameResolved = true; } |
505 | |
506 | // Implement isa/cast/dyncast/etc. |
507 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
508 | static bool classofKind(Kind K) { return K == Label; } |
509 | }; |
510 | |
511 | /// Represent a C++ namespace. |
512 | class NamespaceDecl : public NamedDecl, public DeclContext, |
513 | public Redeclarable<NamespaceDecl> |
514 | { |
515 | /// The starting location of the source range, pointing |
516 | /// to either the namespace or the inline keyword. |
517 | SourceLocation LocStart; |
518 | |
519 | /// The ending location of the source range. |
520 | SourceLocation RBraceLoc; |
521 | |
522 | /// A pointer to either the anonymous namespace that lives just inside |
523 | /// this namespace or to the first namespace in the chain (the latter case |
524 | /// only when this is not the first in the chain), along with a |
525 | /// boolean value indicating whether this is an inline namespace. |
526 | llvm::PointerIntPair<NamespaceDecl *, 1, bool> AnonOrFirstNamespaceAndInline; |
527 | |
528 | NamespaceDecl(ASTContext &C, DeclContext *DC, bool Inline, |
529 | SourceLocation StartLoc, SourceLocation IdLoc, |
530 | IdentifierInfo *Id, NamespaceDecl *PrevDecl); |
531 | |
532 | using redeclarable_base = Redeclarable<NamespaceDecl>; |
533 | |
534 | NamespaceDecl *getNextRedeclarationImpl() override; |
535 | NamespaceDecl *getPreviousDeclImpl() override; |
536 | NamespaceDecl *getMostRecentDeclImpl() override; |
537 | |
538 | public: |
539 | friend class ASTDeclReader; |
540 | friend class ASTDeclWriter; |
541 | |
542 | static NamespaceDecl *Create(ASTContext &C, DeclContext *DC, |
543 | bool Inline, SourceLocation StartLoc, |
544 | SourceLocation IdLoc, IdentifierInfo *Id, |
545 | NamespaceDecl *PrevDecl); |
546 | |
547 | static NamespaceDecl *CreateDeserialized(ASTContext &C, unsigned ID); |
548 | |
549 | using redecl_range = redeclarable_base::redecl_range; |
550 | using redecl_iterator = redeclarable_base::redecl_iterator; |
551 | |
552 | using redeclarable_base::redecls_begin; |
553 | using redeclarable_base::redecls_end; |
554 | using redeclarable_base::redecls; |
555 | using redeclarable_base::getPreviousDecl; |
556 | using redeclarable_base::getMostRecentDecl; |
557 | using redeclarable_base::isFirstDecl; |
558 | |
559 | /// Returns true if this is an anonymous namespace declaration. |
560 | /// |
561 | /// For example: |
562 | /// \code |
563 | /// namespace { |
564 | /// ... |
565 | /// }; |
566 | /// \endcode |
567 | /// q.v. C++ [namespace.unnamed] |
568 | bool isAnonymousNamespace() const { |
569 | return !getIdentifier(); |
570 | } |
571 | |
572 | /// Returns true if this is an inline namespace declaration. |
573 | bool isInline() const { |
574 | return AnonOrFirstNamespaceAndInline.getInt(); |
575 | } |
576 | |
577 | /// Set whether this is an inline namespace declaration. |
578 | void setInline(bool Inline) { |
579 | AnonOrFirstNamespaceAndInline.setInt(Inline); |
580 | } |
581 | |
582 | /// Get the original (first) namespace declaration. |
583 | NamespaceDecl *getOriginalNamespace(); |
584 | |
585 | /// Get the original (first) namespace declaration. |
586 | const NamespaceDecl *getOriginalNamespace() const; |
587 | |
588 | /// Return true if this declaration is an original (first) declaration |
589 | /// of the namespace. This is false for non-original (subsequent) namespace |
590 | /// declarations and anonymous namespaces. |
591 | bool isOriginalNamespace() const; |
592 | |
593 | /// Retrieve the anonymous namespace nested inside this namespace, |
594 | /// if any. |
595 | NamespaceDecl *getAnonymousNamespace() const { |
596 | return getOriginalNamespace()->AnonOrFirstNamespaceAndInline.getPointer(); |
597 | } |
598 | |
599 | void setAnonymousNamespace(NamespaceDecl *D) { |
600 | getOriginalNamespace()->AnonOrFirstNamespaceAndInline.setPointer(D); |
601 | } |
602 | |
603 | /// Retrieves the canonical declaration of this namespace. |
604 | NamespaceDecl *getCanonicalDecl() override { |
605 | return getOriginalNamespace(); |
606 | } |
607 | const NamespaceDecl *getCanonicalDecl() const { |
608 | return getOriginalNamespace(); |
609 | } |
610 | |
611 | SourceRange getSourceRange() const override LLVM_READONLY__attribute__((__pure__)) { |
612 | return SourceRange(LocStart, RBraceLoc); |
613 | } |
614 | |
615 | SourceLocation getBeginLoc() const LLVM_READONLY__attribute__((__pure__)) { return LocStart; } |
616 | SourceLocation getRBraceLoc() const { return RBraceLoc; } |
617 | void setLocStart(SourceLocation L) { LocStart = L; } |
618 | void setRBraceLoc(SourceLocation L) { RBraceLoc = L; } |
619 | |
620 | // Implement isa/cast/dyncast/etc. |
621 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
622 | static bool classofKind(Kind K) { return K == Namespace; } |
623 | static DeclContext *castToDeclContext(const NamespaceDecl *D) { |
624 | return static_cast<DeclContext *>(const_cast<NamespaceDecl*>(D)); |
625 | } |
626 | static NamespaceDecl *castFromDeclContext(const DeclContext *DC) { |
627 | return static_cast<NamespaceDecl *>(const_cast<DeclContext*>(DC)); |
628 | } |
629 | }; |
630 | |
631 | /// Represent the declaration of a variable (in which case it is |
632 | /// an lvalue) a function (in which case it is a function designator) or |
633 | /// an enum constant. |
634 | class ValueDecl : public NamedDecl { |
635 | QualType DeclType; |
636 | |
637 | void anchor() override; |
638 | |
639 | protected: |
640 | ValueDecl(Kind DK, DeclContext *DC, SourceLocation L, |
641 | DeclarationName N, QualType T) |
642 | : NamedDecl(DK, DC, L, N), DeclType(T) {} |
643 | |
644 | public: |
645 | QualType getType() const { return DeclType; } |
646 | void setType(QualType newType) { DeclType = newType; } |
647 | |
648 | /// Determine whether this symbol is weakly-imported, |
649 | /// or declared with the weak or weak-ref attr. |
650 | bool isWeak() const; |
651 | |
652 | // Implement isa/cast/dyncast/etc. |
653 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
654 | static bool classofKind(Kind K) { return K >= firstValue && K <= lastValue; } |
655 | }; |
656 | |
657 | /// A struct with extended info about a syntactic |
658 | /// name qualifier, to be used for the case of out-of-line declarations. |
659 | struct QualifierInfo { |
660 | NestedNameSpecifierLoc QualifierLoc; |
661 | |
662 | /// The number of "outer" template parameter lists. |
663 | /// The count includes all of the template parameter lists that were matched |
664 | /// against the template-ids occurring into the NNS and possibly (in the |
665 | /// case of an explicit specialization) a final "template <>". |
666 | unsigned NumTemplParamLists = 0; |
667 | |
668 | /// A new-allocated array of size NumTemplParamLists, |
669 | /// containing pointers to the "outer" template parameter lists. |
670 | /// It includes all of the template parameter lists that were matched |
671 | /// against the template-ids occurring into the NNS and possibly (in the |
672 | /// case of an explicit specialization) a final "template <>". |
673 | TemplateParameterList** TemplParamLists = nullptr; |
674 | |
675 | QualifierInfo() = default; |
676 | QualifierInfo(const QualifierInfo &) = delete; |
677 | QualifierInfo& operator=(const QualifierInfo &) = delete; |
678 | |
679 | /// Sets info about "outer" template parameter lists. |
680 | void setTemplateParameterListsInfo(ASTContext &Context, |
681 | ArrayRef<TemplateParameterList *> TPLists); |
682 | }; |
683 | |
684 | /// Represents a ValueDecl that came out of a declarator. |
685 | /// Contains type source information through TypeSourceInfo. |
686 | class DeclaratorDecl : public ValueDecl { |
687 | // A struct representing a TInfo, a trailing requires-clause and a syntactic |
688 | // qualifier, to be used for the (uncommon) case of out-of-line declarations |
689 | // and constrained function decls. |
690 | struct ExtInfo : public QualifierInfo { |
691 | TypeSourceInfo *TInfo; |
692 | Expr *TrailingRequiresClause = nullptr; |
693 | }; |
694 | |
695 | llvm::PointerUnion<TypeSourceInfo *, ExtInfo *> DeclInfo; |
696 | |
697 | /// The start of the source range for this declaration, |
698 | /// ignoring outer template declarations. |
699 | SourceLocation InnerLocStart; |
700 | |
701 | bool hasExtInfo() const { return DeclInfo.is<ExtInfo*>(); } |
702 | ExtInfo *getExtInfo() { return DeclInfo.get<ExtInfo*>(); } |
703 | const ExtInfo *getExtInfo() const { return DeclInfo.get<ExtInfo*>(); } |
704 | |
705 | protected: |
706 | DeclaratorDecl(Kind DK, DeclContext *DC, SourceLocation L, |
707 | DeclarationName N, QualType T, TypeSourceInfo *TInfo, |
708 | SourceLocation StartL) |
709 | : ValueDecl(DK, DC, L, N, T), DeclInfo(TInfo), InnerLocStart(StartL) {} |
710 | |
711 | public: |
712 | friend class ASTDeclReader; |
713 | friend class ASTDeclWriter; |
714 | |
715 | TypeSourceInfo *getTypeSourceInfo() const { |
716 | return hasExtInfo() |
717 | ? getExtInfo()->TInfo |
718 | : DeclInfo.get<TypeSourceInfo*>(); |
719 | } |
720 | |
721 | void setTypeSourceInfo(TypeSourceInfo *TI) { |
722 | if (hasExtInfo()) |
723 | getExtInfo()->TInfo = TI; |
724 | else |
725 | DeclInfo = TI; |
726 | } |
727 | |
728 | /// Return start of source range ignoring outer template declarations. |
729 | SourceLocation getInnerLocStart() const { return InnerLocStart; } |
730 | void setInnerLocStart(SourceLocation L) { InnerLocStart = L; } |
731 | |
732 | /// Return start of source range taking into account any outer template |
733 | /// declarations. |
734 | SourceLocation getOuterLocStart() const; |
735 | |
736 | SourceRange getSourceRange() const override LLVM_READONLY__attribute__((__pure__)); |
737 | |
738 | SourceLocation getBeginLoc() const LLVM_READONLY__attribute__((__pure__)) { |
739 | return getOuterLocStart(); |
740 | } |
741 | |
742 | /// Retrieve the nested-name-specifier that qualifies the name of this |
743 | /// declaration, if it was present in the source. |
744 | NestedNameSpecifier *getQualifier() const { |
745 | return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier() |
746 | : nullptr; |
747 | } |
748 | |
749 | /// Retrieve the nested-name-specifier (with source-location |
750 | /// information) that qualifies the name of this declaration, if it was |
751 | /// present in the source. |
752 | NestedNameSpecifierLoc getQualifierLoc() const { |
753 | return hasExtInfo() ? getExtInfo()->QualifierLoc |
754 | : NestedNameSpecifierLoc(); |
755 | } |
756 | |
757 | void setQualifierInfo(NestedNameSpecifierLoc QualifierLoc); |
758 | |
759 | /// \brief Get the constraint-expression introduced by the trailing |
760 | /// requires-clause in the function/member declaration, or null if no |
761 | /// requires-clause was provided. |
762 | Expr *getTrailingRequiresClause() { |
763 | return hasExtInfo() ? getExtInfo()->TrailingRequiresClause |
764 | : nullptr; |
765 | } |
766 | |
767 | const Expr *getTrailingRequiresClause() const { |
768 | return hasExtInfo() ? getExtInfo()->TrailingRequiresClause |
769 | : nullptr; |
770 | } |
771 | |
772 | void setTrailingRequiresClause(Expr *TrailingRequiresClause); |
773 | |
774 | unsigned getNumTemplateParameterLists() const { |
775 | return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0; |
776 | } |
777 | |
778 | TemplateParameterList *getTemplateParameterList(unsigned index) const { |
779 | assert(index < getNumTemplateParameterLists())((index < getNumTemplateParameterLists()) ? static_cast< void> (0) : __assert_fail ("index < getNumTemplateParameterLists()" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 779, __PRETTY_FUNCTION__)); |
780 | return getExtInfo()->TemplParamLists[index]; |
781 | } |
782 | |
783 | void setTemplateParameterListsInfo(ASTContext &Context, |
784 | ArrayRef<TemplateParameterList *> TPLists); |
785 | |
786 | SourceLocation getTypeSpecStartLoc() const; |
787 | SourceLocation getTypeSpecEndLoc() const; |
788 | |
789 | // Implement isa/cast/dyncast/etc. |
790 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
791 | static bool classofKind(Kind K) { |
792 | return K >= firstDeclarator && K <= lastDeclarator; |
793 | } |
794 | }; |
795 | |
796 | /// Structure used to store a statement, the constant value to |
797 | /// which it was evaluated (if any), and whether or not the statement |
798 | /// is an integral constant expression (if known). |
799 | struct EvaluatedStmt { |
800 | /// Whether this statement was already evaluated. |
801 | bool WasEvaluated : 1; |
802 | |
803 | /// Whether this statement is being evaluated. |
804 | bool IsEvaluating : 1; |
805 | |
806 | /// Whether we already checked whether this statement was an |
807 | /// integral constant expression. |
808 | bool CheckedICE : 1; |
809 | |
810 | /// Whether we are checking whether this statement is an |
811 | /// integral constant expression. |
812 | bool CheckingICE : 1; |
813 | |
814 | /// Whether this statement is an integral constant expression, |
815 | /// or in C++11, whether the statement is a constant expression. Only |
816 | /// valid if CheckedICE is true. |
817 | bool IsICE : 1; |
818 | |
819 | /// Whether this variable is known to have constant destruction. That is, |
820 | /// whether running the destructor on the initial value is a side-effect |
821 | /// (and doesn't inspect any state that might have changed during program |
822 | /// execution). This is currently only computed if the destructor is |
823 | /// non-trivial. |
824 | bool HasConstantDestruction : 1; |
825 | |
826 | Stmt *Value; |
827 | APValue Evaluated; |
828 | |
829 | EvaluatedStmt() |
830 | : WasEvaluated(false), IsEvaluating(false), CheckedICE(false), |
831 | CheckingICE(false), IsICE(false), HasConstantDestruction(false) {} |
832 | }; |
833 | |
834 | /// Represents a variable declaration or definition. |
835 | class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> { |
836 | public: |
837 | /// Initialization styles. |
838 | enum InitializationStyle { |
839 | /// C-style initialization with assignment |
840 | CInit, |
841 | |
842 | /// Call-style initialization (C++98) |
843 | CallInit, |
844 | |
845 | /// Direct list-initialization (C++11) |
846 | ListInit |
847 | }; |
848 | |
849 | /// Kinds of thread-local storage. |
850 | enum TLSKind { |
851 | /// Not a TLS variable. |
852 | TLS_None, |
853 | |
854 | /// TLS with a known-constant initializer. |
855 | TLS_Static, |
856 | |
857 | /// TLS with a dynamic initializer. |
858 | TLS_Dynamic |
859 | }; |
860 | |
861 | /// Return the string used to specify the storage class \p SC. |
862 | /// |
863 | /// It is illegal to call this function with SC == None. |
864 | static const char *getStorageClassSpecifierString(StorageClass SC); |
865 | |
866 | protected: |
867 | // A pointer union of Stmt * and EvaluatedStmt *. When an EvaluatedStmt, we |
868 | // have allocated the auxiliary struct of information there. |
869 | // |
870 | // TODO: It is a bit unfortunate to use a PointerUnion inside the VarDecl for |
871 | // this as *many* VarDecls are ParmVarDecls that don't have default |
872 | // arguments. We could save some space by moving this pointer union to be |
873 | // allocated in trailing space when necessary. |
874 | using InitType = llvm::PointerUnion<Stmt *, EvaluatedStmt *>; |
875 | |
876 | /// The initializer for this variable or, for a ParmVarDecl, the |
877 | /// C++ default argument. |
878 | mutable InitType Init; |
879 | |
880 | private: |
881 | friend class ASTDeclReader; |
882 | friend class ASTNodeImporter; |
883 | friend class StmtIteratorBase; |
884 | |
885 | class VarDeclBitfields { |
886 | friend class ASTDeclReader; |
887 | friend class VarDecl; |
888 | |
889 | unsigned SClass : 3; |
890 | unsigned TSCSpec : 2; |
891 | unsigned InitStyle : 2; |
892 | |
893 | /// Whether this variable is an ARC pseudo-__strong variable; see |
894 | /// isARCPseudoStrong() for details. |
895 | unsigned ARCPseudoStrong : 1; |
896 | }; |
897 | enum { NumVarDeclBits = 8 }; |
898 | |
899 | protected: |
900 | enum { NumParameterIndexBits = 8 }; |
901 | |
902 | enum DefaultArgKind { |
903 | DAK_None, |
904 | DAK_Unparsed, |
905 | DAK_Uninstantiated, |
906 | DAK_Normal |
907 | }; |
908 | |
909 | enum { NumScopeDepthOrObjCQualsBits = 7 }; |
910 | |
911 | class ParmVarDeclBitfields { |
912 | friend class ASTDeclReader; |
913 | friend class ParmVarDecl; |
914 | |
915 | unsigned : NumVarDeclBits; |
916 | |
917 | /// Whether this parameter inherits a default argument from a |
918 | /// prior declaration. |
919 | unsigned HasInheritedDefaultArg : 1; |
920 | |
921 | /// Describes the kind of default argument for this parameter. By default |
922 | /// this is none. If this is normal, then the default argument is stored in |
923 | /// the \c VarDecl initializer expression unless we were unable to parse |
924 | /// (even an invalid) expression for the default argument. |
925 | unsigned DefaultArgKind : 2; |
926 | |
927 | /// Whether this parameter undergoes K&R argument promotion. |
928 | unsigned IsKNRPromoted : 1; |
929 | |
930 | /// Whether this parameter is an ObjC method parameter or not. |
931 | unsigned IsObjCMethodParam : 1; |
932 | |
933 | /// If IsObjCMethodParam, a Decl::ObjCDeclQualifier. |
934 | /// Otherwise, the number of function parameter scopes enclosing |
935 | /// the function parameter scope in which this parameter was |
936 | /// declared. |
937 | unsigned ScopeDepthOrObjCQuals : NumScopeDepthOrObjCQualsBits; |
938 | |
939 | /// The number of parameters preceding this parameter in the |
940 | /// function parameter scope in which it was declared. |
941 | unsigned ParameterIndex : NumParameterIndexBits; |
942 | }; |
943 | |
944 | class NonParmVarDeclBitfields { |
945 | friend class ASTDeclReader; |
946 | friend class ImplicitParamDecl; |
947 | friend class VarDecl; |
948 | |
949 | unsigned : NumVarDeclBits; |
950 | |
951 | // FIXME: We need something similar to CXXRecordDecl::DefinitionData. |
952 | /// Whether this variable is a definition which was demoted due to |
953 | /// module merge. |
954 | unsigned IsThisDeclarationADemotedDefinition : 1; |
955 | |
956 | /// Whether this variable is the exception variable in a C++ catch |
957 | /// or an Objective-C @catch statement. |
958 | unsigned ExceptionVar : 1; |
959 | |
960 | /// Whether this local variable could be allocated in the return |
961 | /// slot of its function, enabling the named return value optimization |
962 | /// (NRVO). |
963 | unsigned NRVOVariable : 1; |
964 | |
965 | /// Whether this variable is the for-range-declaration in a C++0x |
966 | /// for-range statement. |
967 | unsigned CXXForRangeDecl : 1; |
968 | |
969 | /// Whether this variable is the for-in loop declaration in Objective-C. |
970 | unsigned ObjCForDecl : 1; |
971 | |
972 | /// Whether this variable is (C++1z) inline. |
973 | unsigned IsInline : 1; |
974 | |
975 | /// Whether this variable has (C++1z) inline explicitly specified. |
976 | unsigned IsInlineSpecified : 1; |
977 | |
978 | /// Whether this variable is (C++0x) constexpr. |
979 | unsigned IsConstexpr : 1; |
980 | |
981 | /// Whether this variable is the implicit variable for a lambda |
982 | /// init-capture. |
983 | unsigned IsInitCapture : 1; |
984 | |
985 | /// Whether this local extern variable's previous declaration was |
986 | /// declared in the same block scope. This controls whether we should merge |
987 | /// the type of this declaration with its previous declaration. |
988 | unsigned PreviousDeclInSameBlockScope : 1; |
989 | |
990 | /// Defines kind of the ImplicitParamDecl: 'this', 'self', 'vtt', '_cmd' or |
991 | /// something else. |
992 | unsigned ImplicitParamKind : 3; |
993 | |
994 | unsigned EscapingByref : 1; |
995 | }; |
996 | |
997 | union { |
998 | unsigned AllBits; |
999 | VarDeclBitfields VarDeclBits; |
1000 | ParmVarDeclBitfields ParmVarDeclBits; |
1001 | NonParmVarDeclBitfields NonParmVarDeclBits; |
1002 | }; |
1003 | |
1004 | VarDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc, |
1005 | SourceLocation IdLoc, IdentifierInfo *Id, QualType T, |
1006 | TypeSourceInfo *TInfo, StorageClass SC); |
1007 | |
1008 | using redeclarable_base = Redeclarable<VarDecl>; |
1009 | |
1010 | VarDecl *getNextRedeclarationImpl() override { |
1011 | return getNextRedeclaration(); |
1012 | } |
1013 | |
1014 | VarDecl *getPreviousDeclImpl() override { |
1015 | return getPreviousDecl(); |
1016 | } |
1017 | |
1018 | VarDecl *getMostRecentDeclImpl() override { |
1019 | return getMostRecentDecl(); |
1020 | } |
1021 | |
1022 | public: |
1023 | using redecl_range = redeclarable_base::redecl_range; |
1024 | using redecl_iterator = redeclarable_base::redecl_iterator; |
1025 | |
1026 | using redeclarable_base::redecls_begin; |
1027 | using redeclarable_base::redecls_end; |
1028 | using redeclarable_base::redecls; |
1029 | using redeclarable_base::getPreviousDecl; |
1030 | using redeclarable_base::getMostRecentDecl; |
1031 | using redeclarable_base::isFirstDecl; |
1032 | |
1033 | static VarDecl *Create(ASTContext &C, DeclContext *DC, |
1034 | SourceLocation StartLoc, SourceLocation IdLoc, |
1035 | IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, |
1036 | StorageClass S); |
1037 | |
1038 | static VarDecl *CreateDeserialized(ASTContext &C, unsigned ID); |
1039 | |
1040 | SourceRange getSourceRange() const override LLVM_READONLY__attribute__((__pure__)); |
1041 | |
1042 | /// Returns the storage class as written in the source. For the |
1043 | /// computed linkage of symbol, see getLinkage. |
1044 | StorageClass getStorageClass() const { |
1045 | return (StorageClass) VarDeclBits.SClass; |
1046 | } |
1047 | void setStorageClass(StorageClass SC); |
1048 | |
1049 | void setTSCSpec(ThreadStorageClassSpecifier TSC) { |
1050 | VarDeclBits.TSCSpec = TSC; |
1051 | assert(VarDeclBits.TSCSpec == TSC && "truncation")((VarDeclBits.TSCSpec == TSC && "truncation") ? static_cast <void> (0) : __assert_fail ("VarDeclBits.TSCSpec == TSC && \"truncation\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 1051, __PRETTY_FUNCTION__)); |
1052 | } |
1053 | ThreadStorageClassSpecifier getTSCSpec() const { |
1054 | return static_cast<ThreadStorageClassSpecifier>(VarDeclBits.TSCSpec); |
1055 | } |
1056 | TLSKind getTLSKind() const; |
1057 | |
1058 | /// Returns true if a variable with function scope is a non-static local |
1059 | /// variable. |
1060 | bool hasLocalStorage() const { |
1061 | if (getStorageClass() == SC_None) { |
1062 | // OpenCL v1.2 s6.5.3: The __constant or constant address space name is |
1063 | // used to describe variables allocated in global memory and which are |
1064 | // accessed inside a kernel(s) as read-only variables. As such, variables |
1065 | // in constant address space cannot have local storage. |
1066 | if (getType().getAddressSpace() == LangAS::opencl_constant) |
1067 | return false; |
1068 | // Second check is for C++11 [dcl.stc]p4. |
1069 | return !isFileVarDecl() && getTSCSpec() == TSCS_unspecified; |
1070 | } |
1071 | |
1072 | // Global Named Register (GNU extension) |
1073 | if (getStorageClass() == SC_Register && !isLocalVarDeclOrParm()) |
1074 | return false; |
1075 | |
1076 | // Return true for: Auto, Register. |
1077 | // Return false for: Extern, Static, PrivateExtern, OpenCLWorkGroupLocal. |
1078 | |
1079 | return getStorageClass() >= SC_Auto; |
1080 | } |
1081 | |
1082 | /// Returns true if a variable with function scope is a static local |
1083 | /// variable. |
1084 | bool isStaticLocal() const { |
1085 | return (getStorageClass() == SC_Static || |
1086 | // C++11 [dcl.stc]p4 |
1087 | (getStorageClass() == SC_None && getTSCSpec() == TSCS_thread_local)) |
1088 | && !isFileVarDecl(); |
1089 | } |
1090 | |
1091 | /// Returns true if a variable has extern or __private_extern__ |
1092 | /// storage. |
1093 | bool hasExternalStorage() const { |
1094 | return getStorageClass() == SC_Extern || |
1095 | getStorageClass() == SC_PrivateExtern; |
1096 | } |
1097 | |
1098 | /// Returns true for all variables that do not have local storage. |
1099 | /// |
1100 | /// This includes all global variables as well as static variables declared |
1101 | /// within a function. |
1102 | bool hasGlobalStorage() const { return !hasLocalStorage(); } |
1103 | |
1104 | /// Get the storage duration of this variable, per C++ [basic.stc]. |
1105 | StorageDuration getStorageDuration() const { |
1106 | return hasLocalStorage() ? SD_Automatic : |
1107 | getTSCSpec() ? SD_Thread : SD_Static; |
1108 | } |
1109 | |
1110 | /// Compute the language linkage. |
1111 | LanguageLinkage getLanguageLinkage() const; |
1112 | |
1113 | /// Determines whether this variable is a variable with external, C linkage. |
1114 | bool isExternC() const; |
1115 | |
1116 | /// Determines whether this variable's context is, or is nested within, |
1117 | /// a C++ extern "C" linkage spec. |
1118 | bool isInExternCContext() const; |
1119 | |
1120 | /// Determines whether this variable's context is, or is nested within, |
1121 | /// a C++ extern "C++" linkage spec. |
1122 | bool isInExternCXXContext() const; |
1123 | |
1124 | /// Returns true for local variable declarations other than parameters. |
1125 | /// Note that this includes static variables inside of functions. It also |
1126 | /// includes variables inside blocks. |
1127 | /// |
1128 | /// void foo() { int x; static int y; extern int z; } |
1129 | bool isLocalVarDecl() const { |
1130 | if (getKind() != Decl::Var && getKind() != Decl::Decomposition) |
1131 | return false; |
1132 | if (const DeclContext *DC = getLexicalDeclContext()) |
1133 | return DC->getRedeclContext()->isFunctionOrMethod(); |
1134 | return false; |
1135 | } |
1136 | |
1137 | /// Similar to isLocalVarDecl but also includes parameters. |
1138 | bool isLocalVarDeclOrParm() const { |
1139 | return isLocalVarDecl() || getKind() == Decl::ParmVar; |
1140 | } |
1141 | |
1142 | /// Similar to isLocalVarDecl, but excludes variables declared in blocks. |
1143 | bool isFunctionOrMethodVarDecl() const { |
1144 | if (getKind() != Decl::Var && getKind() != Decl::Decomposition) |
1145 | return false; |
1146 | const DeclContext *DC = getLexicalDeclContext()->getRedeclContext(); |
1147 | return DC->isFunctionOrMethod() && DC->getDeclKind() != Decl::Block; |
1148 | } |
1149 | |
1150 | /// Determines whether this is a static data member. |
1151 | /// |
1152 | /// This will only be true in C++, and applies to, e.g., the |
1153 | /// variable 'x' in: |
1154 | /// \code |
1155 | /// struct S { |
1156 | /// static int x; |
1157 | /// }; |
1158 | /// \endcode |
1159 | bool isStaticDataMember() const { |
1160 | // If it wasn't static, it would be a FieldDecl. |
1161 | return getKind() != Decl::ParmVar && getDeclContext()->isRecord(); |
1162 | } |
1163 | |
1164 | VarDecl *getCanonicalDecl() override; |
1165 | const VarDecl *getCanonicalDecl() const { |
1166 | return const_cast<VarDecl*>(this)->getCanonicalDecl(); |
1167 | } |
1168 | |
1169 | enum DefinitionKind { |
1170 | /// This declaration is only a declaration. |
1171 | DeclarationOnly, |
1172 | |
1173 | /// This declaration is a tentative definition. |
1174 | TentativeDefinition, |
1175 | |
1176 | /// This declaration is definitely a definition. |
1177 | Definition |
1178 | }; |
1179 | |
1180 | /// Check whether this declaration is a definition. If this could be |
1181 | /// a tentative definition (in C), don't check whether there's an overriding |
1182 | /// definition. |
1183 | DefinitionKind isThisDeclarationADefinition(ASTContext &) const; |
1184 | DefinitionKind isThisDeclarationADefinition() const { |
1185 | return isThisDeclarationADefinition(getASTContext()); |
1186 | } |
1187 | |
1188 | /// Check whether this variable is defined in this translation unit. |
1189 | DefinitionKind hasDefinition(ASTContext &) const; |
1190 | DefinitionKind hasDefinition() const { |
1191 | return hasDefinition(getASTContext()); |
1192 | } |
1193 | |
1194 | /// Get the tentative definition that acts as the real definition in a TU. |
1195 | /// Returns null if there is a proper definition available. |
1196 | VarDecl *getActingDefinition(); |
1197 | const VarDecl *getActingDefinition() const { |
1198 | return const_cast<VarDecl*>(this)->getActingDefinition(); |
1199 | } |
1200 | |
1201 | /// Get the real (not just tentative) definition for this declaration. |
1202 | VarDecl *getDefinition(ASTContext &); |
1203 | const VarDecl *getDefinition(ASTContext &C) const { |
1204 | return const_cast<VarDecl*>(this)->getDefinition(C); |
1205 | } |
1206 | VarDecl *getDefinition() { |
1207 | return getDefinition(getASTContext()); |
1208 | } |
1209 | const VarDecl *getDefinition() const { |
1210 | return const_cast<VarDecl*>(this)->getDefinition(); |
1211 | } |
1212 | |
1213 | /// Determine whether this is or was instantiated from an out-of-line |
1214 | /// definition of a static data member. |
1215 | bool isOutOfLine() const override; |
1216 | |
1217 | /// Returns true for file scoped variable declaration. |
1218 | bool isFileVarDecl() const { |
1219 | Kind K = getKind(); |
1220 | if (K == ParmVar || K == ImplicitParam) |
1221 | return false; |
1222 | |
1223 | if (getLexicalDeclContext()->getRedeclContext()->isFileContext()) |
1224 | return true; |
1225 | |
1226 | if (isStaticDataMember()) |
1227 | return true; |
1228 | |
1229 | return false; |
1230 | } |
1231 | |
1232 | /// Get the initializer for this variable, no matter which |
1233 | /// declaration it is attached to. |
1234 | const Expr *getAnyInitializer() const { |
1235 | const VarDecl *D; |
1236 | return getAnyInitializer(D); |
1237 | } |
1238 | |
1239 | /// Get the initializer for this variable, no matter which |
1240 | /// declaration it is attached to. Also get that declaration. |
1241 | const Expr *getAnyInitializer(const VarDecl *&D) const; |
1242 | |
1243 | bool hasInit() const; |
1244 | const Expr *getInit() const { |
1245 | return const_cast<VarDecl *>(this)->getInit(); |
1246 | } |
1247 | Expr *getInit(); |
1248 | |
1249 | /// Retrieve the address of the initializer expression. |
1250 | Stmt **getInitAddress(); |
1251 | |
1252 | void setInit(Expr *I); |
1253 | |
1254 | /// Get the initializing declaration of this variable, if any. This is |
1255 | /// usually the definition, except that for a static data member it can be |
1256 | /// the in-class declaration. |
1257 | VarDecl *getInitializingDeclaration(); |
1258 | const VarDecl *getInitializingDeclaration() const { |
1259 | return const_cast<VarDecl *>(this)->getInitializingDeclaration(); |
1260 | } |
1261 | |
1262 | /// Determine whether this variable's value might be usable in a |
1263 | /// constant expression, according to the relevant language standard. |
1264 | /// This only checks properties of the declaration, and does not check |
1265 | /// whether the initializer is in fact a constant expression. |
1266 | bool mightBeUsableInConstantExpressions(ASTContext &C) const; |
1267 | |
1268 | /// Determine whether this variable's value can be used in a |
1269 | /// constant expression, according to the relevant language standard, |
1270 | /// including checking whether it was initialized by a constant expression. |
1271 | bool isUsableInConstantExpressions(ASTContext &C) const; |
1272 | |
1273 | EvaluatedStmt *ensureEvaluatedStmt() const; |
1274 | |
1275 | /// Attempt to evaluate the value of the initializer attached to this |
1276 | /// declaration, and produce notes explaining why it cannot be evaluated or is |
1277 | /// not a constant expression. Returns a pointer to the value if evaluation |
1278 | /// succeeded, 0 otherwise. |
1279 | APValue *evaluateValue() const; |
1280 | APValue *evaluateValue(SmallVectorImpl<PartialDiagnosticAt> &Notes) const; |
1281 | |
1282 | /// Return the already-evaluated value of this variable's |
1283 | /// initializer, or NULL if the value is not yet known. Returns pointer |
1284 | /// to untyped APValue if the value could not be evaluated. |
1285 | APValue *getEvaluatedValue() const; |
1286 | |
1287 | /// Evaluate the destruction of this variable to determine if it constitutes |
1288 | /// constant destruction. |
1289 | /// |
1290 | /// \pre isInitICE() |
1291 | /// \return \c true if this variable has constant destruction, \c false if |
1292 | /// not. |
1293 | bool evaluateDestruction(SmallVectorImpl<PartialDiagnosticAt> &Notes) const; |
1294 | |
1295 | /// Determines whether it is already known whether the |
1296 | /// initializer is an integral constant expression or not. |
1297 | bool isInitKnownICE() const; |
1298 | |
1299 | /// Determines whether the initializer is an integral constant |
1300 | /// expression, or in C++11, whether the initializer is a constant |
1301 | /// expression. |
1302 | /// |
1303 | /// \pre isInitKnownICE() |
1304 | bool isInitICE() const; |
1305 | |
1306 | /// Determine whether the value of the initializer attached to this |
1307 | /// declaration is an integral constant expression. |
1308 | bool checkInitIsICE() const; |
1309 | |
1310 | void setInitStyle(InitializationStyle Style) { |
1311 | VarDeclBits.InitStyle = Style; |
1312 | } |
1313 | |
1314 | /// The style of initialization for this declaration. |
1315 | /// |
1316 | /// C-style initialization is "int x = 1;". Call-style initialization is |
1317 | /// a C++98 direct-initializer, e.g. "int x(1);". The Init expression will be |
1318 | /// the expression inside the parens or a "ClassType(a,b,c)" class constructor |
1319 | /// expression for class types. List-style initialization is C++11 syntax, |
1320 | /// e.g. "int x{1};". Clients can distinguish between different forms of |
1321 | /// initialization by checking this value. In particular, "int x = {1};" is |
1322 | /// C-style, "int x({1})" is call-style, and "int x{1};" is list-style; the |
1323 | /// Init expression in all three cases is an InitListExpr. |
1324 | InitializationStyle getInitStyle() const { |
1325 | return static_cast<InitializationStyle>(VarDeclBits.InitStyle); |
1326 | } |
1327 | |
1328 | /// Whether the initializer is a direct-initializer (list or call). |
1329 | bool isDirectInit() const { |
1330 | return getInitStyle() != CInit; |
1331 | } |
1332 | |
1333 | /// If this definition should pretend to be a declaration. |
1334 | bool isThisDeclarationADemotedDefinition() const { |
1335 | return isa<ParmVarDecl>(this) ? false : |
1336 | NonParmVarDeclBits.IsThisDeclarationADemotedDefinition; |
1337 | } |
1338 | |
1339 | /// This is a definition which should be demoted to a declaration. |
1340 | /// |
1341 | /// In some cases (mostly module merging) we can end up with two visible |
1342 | /// definitions one of which needs to be demoted to a declaration to keep |
1343 | /// the AST invariants. |
1344 | void demoteThisDefinitionToDeclaration() { |
1345 | assert(isThisDeclarationADefinition() && "Not a definition!")((isThisDeclarationADefinition() && "Not a definition!" ) ? static_cast<void> (0) : __assert_fail ("isThisDeclarationADefinition() && \"Not a definition!\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 1345, __PRETTY_FUNCTION__)); |
1346 | assert(!isa<ParmVarDecl>(this) && "Cannot demote ParmVarDecls!")((!isa<ParmVarDecl>(this) && "Cannot demote ParmVarDecls!" ) ? static_cast<void> (0) : __assert_fail ("!isa<ParmVarDecl>(this) && \"Cannot demote ParmVarDecls!\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 1346, __PRETTY_FUNCTION__)); |
1347 | NonParmVarDeclBits.IsThisDeclarationADemotedDefinition = 1; |
1348 | } |
1349 | |
1350 | /// Determine whether this variable is the exception variable in a |
1351 | /// C++ catch statememt or an Objective-C \@catch statement. |
1352 | bool isExceptionVariable() const { |
1353 | return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.ExceptionVar; |
1354 | } |
1355 | void setExceptionVariable(bool EV) { |
1356 | assert(!isa<ParmVarDecl>(this))((!isa<ParmVarDecl>(this)) ? static_cast<void> (0 ) : __assert_fail ("!isa<ParmVarDecl>(this)", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 1356, __PRETTY_FUNCTION__)); |
1357 | NonParmVarDeclBits.ExceptionVar = EV; |
1358 | } |
1359 | |
1360 | /// Determine whether this local variable can be used with the named |
1361 | /// return value optimization (NRVO). |
1362 | /// |
1363 | /// The named return value optimization (NRVO) works by marking certain |
1364 | /// non-volatile local variables of class type as NRVO objects. These |
1365 | /// locals can be allocated within the return slot of their containing |
1366 | /// function, in which case there is no need to copy the object to the |
1367 | /// return slot when returning from the function. Within the function body, |
1368 | /// each return that returns the NRVO object will have this variable as its |
1369 | /// NRVO candidate. |
1370 | bool isNRVOVariable() const { |
1371 | return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.NRVOVariable; |
1372 | } |
1373 | void setNRVOVariable(bool NRVO) { |
1374 | assert(!isa<ParmVarDecl>(this))((!isa<ParmVarDecl>(this)) ? static_cast<void> (0 ) : __assert_fail ("!isa<ParmVarDecl>(this)", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 1374, __PRETTY_FUNCTION__)); |
1375 | NonParmVarDeclBits.NRVOVariable = NRVO; |
1376 | } |
1377 | |
1378 | /// Determine whether this variable is the for-range-declaration in |
1379 | /// a C++0x for-range statement. |
1380 | bool isCXXForRangeDecl() const { |
1381 | return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.CXXForRangeDecl; |
1382 | } |
1383 | void setCXXForRangeDecl(bool FRD) { |
1384 | assert(!isa<ParmVarDecl>(this))((!isa<ParmVarDecl>(this)) ? static_cast<void> (0 ) : __assert_fail ("!isa<ParmVarDecl>(this)", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 1384, __PRETTY_FUNCTION__)); |
1385 | NonParmVarDeclBits.CXXForRangeDecl = FRD; |
1386 | } |
1387 | |
1388 | /// Determine whether this variable is a for-loop declaration for a |
1389 | /// for-in statement in Objective-C. |
1390 | bool isObjCForDecl() const { |
1391 | return NonParmVarDeclBits.ObjCForDecl; |
1392 | } |
1393 | |
1394 | void setObjCForDecl(bool FRD) { |
1395 | NonParmVarDeclBits.ObjCForDecl = FRD; |
1396 | } |
1397 | |
1398 | /// Determine whether this variable is an ARC pseudo-__strong variable. A |
1399 | /// pseudo-__strong variable has a __strong-qualified type but does not |
1400 | /// actually retain the object written into it. Generally such variables are |
1401 | /// also 'const' for safety. There are 3 cases where this will be set, 1) if |
1402 | /// the variable is annotated with the objc_externally_retained attribute, 2) |
1403 | /// if its 'self' in a non-init method, or 3) if its the variable in an for-in |
1404 | /// loop. |
1405 | bool isARCPseudoStrong() const { return VarDeclBits.ARCPseudoStrong; } |
1406 | void setARCPseudoStrong(bool PS) { VarDeclBits.ARCPseudoStrong = PS; } |
1407 | |
1408 | /// Whether this variable is (C++1z) inline. |
1409 | bool isInline() const { |
1410 | return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsInline; |
1411 | } |
1412 | bool isInlineSpecified() const { |
1413 | return isa<ParmVarDecl>(this) ? false |
1414 | : NonParmVarDeclBits.IsInlineSpecified; |
1415 | } |
1416 | void setInlineSpecified() { |
1417 | assert(!isa<ParmVarDecl>(this))((!isa<ParmVarDecl>(this)) ? static_cast<void> (0 ) : __assert_fail ("!isa<ParmVarDecl>(this)", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 1417, __PRETTY_FUNCTION__)); |
1418 | NonParmVarDeclBits.IsInline = true; |
1419 | NonParmVarDeclBits.IsInlineSpecified = true; |
1420 | } |
1421 | void setImplicitlyInline() { |
1422 | assert(!isa<ParmVarDecl>(this))((!isa<ParmVarDecl>(this)) ? static_cast<void> (0 ) : __assert_fail ("!isa<ParmVarDecl>(this)", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 1422, __PRETTY_FUNCTION__)); |
1423 | NonParmVarDeclBits.IsInline = true; |
1424 | } |
1425 | |
1426 | /// Whether this variable is (C++11) constexpr. |
1427 | bool isConstexpr() const { |
1428 | return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsConstexpr; |
1429 | } |
1430 | void setConstexpr(bool IC) { |
1431 | assert(!isa<ParmVarDecl>(this))((!isa<ParmVarDecl>(this)) ? static_cast<void> (0 ) : __assert_fail ("!isa<ParmVarDecl>(this)", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 1431, __PRETTY_FUNCTION__)); |
1432 | NonParmVarDeclBits.IsConstexpr = IC; |
1433 | } |
1434 | |
1435 | /// Whether this variable is the implicit variable for a lambda init-capture. |
1436 | bool isInitCapture() const { |
1437 | return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsInitCapture; |
1438 | } |
1439 | void setInitCapture(bool IC) { |
1440 | assert(!isa<ParmVarDecl>(this))((!isa<ParmVarDecl>(this)) ? static_cast<void> (0 ) : __assert_fail ("!isa<ParmVarDecl>(this)", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 1440, __PRETTY_FUNCTION__)); |
1441 | NonParmVarDeclBits.IsInitCapture = IC; |
1442 | } |
1443 | |
1444 | /// Determine whether this variable is actually a function parameter pack or |
1445 | /// init-capture pack. |
1446 | bool isParameterPack() const; |
1447 | |
1448 | /// Whether this local extern variable declaration's previous declaration |
1449 | /// was declared in the same block scope. Only correct in C++. |
1450 | bool isPreviousDeclInSameBlockScope() const { |
1451 | return isa<ParmVarDecl>(this) |
1452 | ? false |
1453 | : NonParmVarDeclBits.PreviousDeclInSameBlockScope; |
1454 | } |
1455 | void setPreviousDeclInSameBlockScope(bool Same) { |
1456 | assert(!isa<ParmVarDecl>(this))((!isa<ParmVarDecl>(this)) ? static_cast<void> (0 ) : __assert_fail ("!isa<ParmVarDecl>(this)", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 1456, __PRETTY_FUNCTION__)); |
1457 | NonParmVarDeclBits.PreviousDeclInSameBlockScope = Same; |
1458 | } |
1459 | |
1460 | /// Indicates the capture is a __block variable that is captured by a block |
1461 | /// that can potentially escape (a block for which BlockDecl::doesNotEscape |
1462 | /// returns false). |
1463 | bool isEscapingByref() const; |
1464 | |
1465 | /// Indicates the capture is a __block variable that is never captured by an |
1466 | /// escaping block. |
1467 | bool isNonEscapingByref() const; |
1468 | |
1469 | void setEscapingByref() { |
1470 | NonParmVarDeclBits.EscapingByref = true; |
1471 | } |
1472 | |
1473 | /// Retrieve the variable declaration from which this variable could |
1474 | /// be instantiated, if it is an instantiation (rather than a non-template). |
1475 | VarDecl *getTemplateInstantiationPattern() const; |
1476 | |
1477 | /// If this variable is an instantiated static data member of a |
1478 | /// class template specialization, returns the templated static data member |
1479 | /// from which it was instantiated. |
1480 | VarDecl *getInstantiatedFromStaticDataMember() const; |
1481 | |
1482 | /// If this variable is an instantiation of a variable template or a |
1483 | /// static data member of a class template, determine what kind of |
1484 | /// template specialization or instantiation this is. |
1485 | TemplateSpecializationKind getTemplateSpecializationKind() const; |
1486 | |
1487 | /// Get the template specialization kind of this variable for the purposes of |
1488 | /// template instantiation. This differs from getTemplateSpecializationKind() |
1489 | /// for an instantiation of a class-scope explicit specialization. |
1490 | TemplateSpecializationKind |
1491 | getTemplateSpecializationKindForInstantiation() const; |
1492 | |
1493 | /// If this variable is an instantiation of a variable template or a |
1494 | /// static data member of a class template, determine its point of |
1495 | /// instantiation. |
1496 | SourceLocation getPointOfInstantiation() const; |
1497 | |
1498 | /// If this variable is an instantiation of a static data member of a |
1499 | /// class template specialization, retrieves the member specialization |
1500 | /// information. |
1501 | MemberSpecializationInfo *getMemberSpecializationInfo() const; |
1502 | |
1503 | /// For a static data member that was instantiated from a static |
1504 | /// data member of a class template, set the template specialiation kind. |
1505 | void setTemplateSpecializationKind(TemplateSpecializationKind TSK, |
1506 | SourceLocation PointOfInstantiation = SourceLocation()); |
1507 | |
1508 | /// Specify that this variable is an instantiation of the |
1509 | /// static data member VD. |
1510 | void setInstantiationOfStaticDataMember(VarDecl *VD, |
1511 | TemplateSpecializationKind TSK); |
1512 | |
1513 | /// Retrieves the variable template that is described by this |
1514 | /// variable declaration. |
1515 | /// |
1516 | /// Every variable template is represented as a VarTemplateDecl and a |
1517 | /// VarDecl. The former contains template properties (such as |
1518 | /// the template parameter lists) while the latter contains the |
1519 | /// actual description of the template's |
1520 | /// contents. VarTemplateDecl::getTemplatedDecl() retrieves the |
1521 | /// VarDecl that from a VarTemplateDecl, while |
1522 | /// getDescribedVarTemplate() retrieves the VarTemplateDecl from |
1523 | /// a VarDecl. |
1524 | VarTemplateDecl *getDescribedVarTemplate() const; |
1525 | |
1526 | void setDescribedVarTemplate(VarTemplateDecl *Template); |
1527 | |
1528 | // Is this variable known to have a definition somewhere in the complete |
1529 | // program? This may be true even if the declaration has internal linkage and |
1530 | // has no definition within this source file. |
1531 | bool isKnownToBeDefined() const; |
1532 | |
1533 | /// Is destruction of this variable entirely suppressed? If so, the variable |
1534 | /// need not have a usable destructor at all. |
1535 | bool isNoDestroy(const ASTContext &) const; |
1536 | |
1537 | /// Would the destruction of this variable have any effect, and if so, what |
1538 | /// kind? |
1539 | QualType::DestructionKind needsDestruction(const ASTContext &Ctx) const; |
1540 | |
1541 | // Implement isa/cast/dyncast/etc. |
1542 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
1543 | static bool classofKind(Kind K) { return K >= firstVar && K <= lastVar; } |
1544 | }; |
1545 | |
1546 | class ImplicitParamDecl : public VarDecl { |
1547 | void anchor() override; |
1548 | |
1549 | public: |
1550 | /// Defines the kind of the implicit parameter: is this an implicit parameter |
1551 | /// with pointer to 'this', 'self', '_cmd', virtual table pointers, captured |
1552 | /// context or something else. |
1553 | enum ImplicitParamKind : unsigned { |
1554 | /// Parameter for Objective-C 'self' argument |
1555 | ObjCSelf, |
1556 | |
1557 | /// Parameter for Objective-C '_cmd' argument |
1558 | ObjCCmd, |
1559 | |
1560 | /// Parameter for C++ 'this' argument |
1561 | CXXThis, |
1562 | |
1563 | /// Parameter for C++ virtual table pointers |
1564 | CXXVTT, |
1565 | |
1566 | /// Parameter for captured context |
1567 | CapturedContext, |
1568 | |
1569 | /// Other implicit parameter |
1570 | Other, |
1571 | }; |
1572 | |
1573 | /// Create implicit parameter. |
1574 | static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC, |
1575 | SourceLocation IdLoc, IdentifierInfo *Id, |
1576 | QualType T, ImplicitParamKind ParamKind); |
1577 | static ImplicitParamDecl *Create(ASTContext &C, QualType T, |
1578 | ImplicitParamKind ParamKind); |
1579 | |
1580 | static ImplicitParamDecl *CreateDeserialized(ASTContext &C, unsigned ID); |
1581 | |
1582 | ImplicitParamDecl(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, |
1583 | IdentifierInfo *Id, QualType Type, |
1584 | ImplicitParamKind ParamKind) |
1585 | : VarDecl(ImplicitParam, C, DC, IdLoc, IdLoc, Id, Type, |
1586 | /*TInfo=*/nullptr, SC_None) { |
1587 | NonParmVarDeclBits.ImplicitParamKind = ParamKind; |
1588 | setImplicit(); |
1589 | } |
1590 | |
1591 | ImplicitParamDecl(ASTContext &C, QualType Type, ImplicitParamKind ParamKind) |
1592 | : VarDecl(ImplicitParam, C, /*DC=*/nullptr, SourceLocation(), |
1593 | SourceLocation(), /*Id=*/nullptr, Type, |
1594 | /*TInfo=*/nullptr, SC_None) { |
1595 | NonParmVarDeclBits.ImplicitParamKind = ParamKind; |
1596 | setImplicit(); |
1597 | } |
1598 | |
1599 | /// Returns the implicit parameter kind. |
1600 | ImplicitParamKind getParameterKind() const { |
1601 | return static_cast<ImplicitParamKind>(NonParmVarDeclBits.ImplicitParamKind); |
1602 | } |
1603 | |
1604 | // Implement isa/cast/dyncast/etc. |
1605 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
1606 | static bool classofKind(Kind K) { return K == ImplicitParam; } |
1607 | }; |
1608 | |
1609 | /// Represents a parameter to a function. |
1610 | class ParmVarDecl : public VarDecl { |
1611 | public: |
1612 | enum { MaxFunctionScopeDepth = 255 }; |
1613 | enum { MaxFunctionScopeIndex = 255 }; |
1614 | |
1615 | protected: |
1616 | ParmVarDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc, |
1617 | SourceLocation IdLoc, IdentifierInfo *Id, QualType T, |
1618 | TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg) |
1619 | : VarDecl(DK, C, DC, StartLoc, IdLoc, Id, T, TInfo, S) { |
1620 | assert(ParmVarDeclBits.HasInheritedDefaultArg == false)((ParmVarDeclBits.HasInheritedDefaultArg == false) ? static_cast <void> (0) : __assert_fail ("ParmVarDeclBits.HasInheritedDefaultArg == false" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 1620, __PRETTY_FUNCTION__)); |
1621 | assert(ParmVarDeclBits.DefaultArgKind == DAK_None)((ParmVarDeclBits.DefaultArgKind == DAK_None) ? static_cast< void> (0) : __assert_fail ("ParmVarDeclBits.DefaultArgKind == DAK_None" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 1621, __PRETTY_FUNCTION__)); |
1622 | assert(ParmVarDeclBits.IsKNRPromoted == false)((ParmVarDeclBits.IsKNRPromoted == false) ? static_cast<void > (0) : __assert_fail ("ParmVarDeclBits.IsKNRPromoted == false" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 1622, __PRETTY_FUNCTION__)); |
1623 | assert(ParmVarDeclBits.IsObjCMethodParam == false)((ParmVarDeclBits.IsObjCMethodParam == false) ? static_cast< void> (0) : __assert_fail ("ParmVarDeclBits.IsObjCMethodParam == false" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 1623, __PRETTY_FUNCTION__)); |
1624 | setDefaultArg(DefArg); |
1625 | } |
1626 | |
1627 | public: |
1628 | static ParmVarDecl *Create(ASTContext &C, DeclContext *DC, |
1629 | SourceLocation StartLoc, |
1630 | SourceLocation IdLoc, IdentifierInfo *Id, |
1631 | QualType T, TypeSourceInfo *TInfo, |
1632 | StorageClass S, Expr *DefArg); |
1633 | |
1634 | static ParmVarDecl *CreateDeserialized(ASTContext &C, unsigned ID); |
1635 | |
1636 | SourceRange getSourceRange() const override LLVM_READONLY__attribute__((__pure__)); |
1637 | |
1638 | void setObjCMethodScopeInfo(unsigned parameterIndex) { |
1639 | ParmVarDeclBits.IsObjCMethodParam = true; |
1640 | setParameterIndex(parameterIndex); |
1641 | } |
1642 | |
1643 | void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex) { |
1644 | assert(!ParmVarDeclBits.IsObjCMethodParam)((!ParmVarDeclBits.IsObjCMethodParam) ? static_cast<void> (0) : __assert_fail ("!ParmVarDeclBits.IsObjCMethodParam", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 1644, __PRETTY_FUNCTION__)); |
1645 | |
1646 | ParmVarDeclBits.ScopeDepthOrObjCQuals = scopeDepth; |
1647 | assert(ParmVarDeclBits.ScopeDepthOrObjCQuals == scopeDepth((ParmVarDeclBits.ScopeDepthOrObjCQuals == scopeDepth && "truncation!") ? static_cast<void> (0) : __assert_fail ("ParmVarDeclBits.ScopeDepthOrObjCQuals == scopeDepth && \"truncation!\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 1648, __PRETTY_FUNCTION__)) |
1648 | && "truncation!")((ParmVarDeclBits.ScopeDepthOrObjCQuals == scopeDepth && "truncation!") ? static_cast<void> (0) : __assert_fail ("ParmVarDeclBits.ScopeDepthOrObjCQuals == scopeDepth && \"truncation!\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 1648, __PRETTY_FUNCTION__)); |
1649 | |
1650 | setParameterIndex(parameterIndex); |
1651 | } |
1652 | |
1653 | bool isObjCMethodParameter() const { |
1654 | return ParmVarDeclBits.IsObjCMethodParam; |
1655 | } |
1656 | |
1657 | unsigned getFunctionScopeDepth() const { |
1658 | if (ParmVarDeclBits.IsObjCMethodParam) return 0; |
1659 | return ParmVarDeclBits.ScopeDepthOrObjCQuals; |
1660 | } |
1661 | |
1662 | static constexpr unsigned getMaxFunctionScopeDepth() { |
1663 | return (1u << NumScopeDepthOrObjCQualsBits) - 1; |
1664 | } |
1665 | |
1666 | /// Returns the index of this parameter in its prototype or method scope. |
1667 | unsigned getFunctionScopeIndex() const { |
1668 | return getParameterIndex(); |
1669 | } |
1670 | |
1671 | ObjCDeclQualifier getObjCDeclQualifier() const { |
1672 | if (!ParmVarDeclBits.IsObjCMethodParam) return OBJC_TQ_None; |
1673 | return ObjCDeclQualifier(ParmVarDeclBits.ScopeDepthOrObjCQuals); |
1674 | } |
1675 | void setObjCDeclQualifier(ObjCDeclQualifier QTVal) { |
1676 | assert(ParmVarDeclBits.IsObjCMethodParam)((ParmVarDeclBits.IsObjCMethodParam) ? static_cast<void> (0) : __assert_fail ("ParmVarDeclBits.IsObjCMethodParam", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 1676, __PRETTY_FUNCTION__)); |
1677 | ParmVarDeclBits.ScopeDepthOrObjCQuals = QTVal; |
1678 | } |
1679 | |
1680 | /// True if the value passed to this parameter must undergo |
1681 | /// K&R-style default argument promotion: |
1682 | /// |
1683 | /// C99 6.5.2.2. |
1684 | /// If the expression that denotes the called function has a type |
1685 | /// that does not include a prototype, the integer promotions are |
1686 | /// performed on each argument, and arguments that have type float |
1687 | /// are promoted to double. |
1688 | bool isKNRPromoted() const { |
1689 | return ParmVarDeclBits.IsKNRPromoted; |
1690 | } |
1691 | void setKNRPromoted(bool promoted) { |
1692 | ParmVarDeclBits.IsKNRPromoted = promoted; |
1693 | } |
1694 | |
1695 | Expr *getDefaultArg(); |
1696 | const Expr *getDefaultArg() const { |
1697 | return const_cast<ParmVarDecl *>(this)->getDefaultArg(); |
1698 | } |
1699 | |
1700 | void setDefaultArg(Expr *defarg); |
1701 | |
1702 | /// Retrieve the source range that covers the entire default |
1703 | /// argument. |
1704 | SourceRange getDefaultArgRange() const; |
1705 | void setUninstantiatedDefaultArg(Expr *arg); |
1706 | Expr *getUninstantiatedDefaultArg(); |
1707 | const Expr *getUninstantiatedDefaultArg() const { |
1708 | return const_cast<ParmVarDecl *>(this)->getUninstantiatedDefaultArg(); |
1709 | } |
1710 | |
1711 | /// Determines whether this parameter has a default argument, |
1712 | /// either parsed or not. |
1713 | bool hasDefaultArg() const; |
1714 | |
1715 | /// Determines whether this parameter has a default argument that has not |
1716 | /// yet been parsed. This will occur during the processing of a C++ class |
1717 | /// whose member functions have default arguments, e.g., |
1718 | /// @code |
1719 | /// class X { |
1720 | /// public: |
1721 | /// void f(int x = 17); // x has an unparsed default argument now |
1722 | /// }; // x has a regular default argument now |
1723 | /// @endcode |
1724 | bool hasUnparsedDefaultArg() const { |
1725 | return ParmVarDeclBits.DefaultArgKind == DAK_Unparsed; |
1726 | } |
1727 | |
1728 | bool hasUninstantiatedDefaultArg() const { |
1729 | return ParmVarDeclBits.DefaultArgKind == DAK_Uninstantiated; |
1730 | } |
1731 | |
1732 | /// Specify that this parameter has an unparsed default argument. |
1733 | /// The argument will be replaced with a real default argument via |
1734 | /// setDefaultArg when the class definition enclosing the function |
1735 | /// declaration that owns this default argument is completed. |
1736 | void setUnparsedDefaultArg() { |
1737 | ParmVarDeclBits.DefaultArgKind = DAK_Unparsed; |
1738 | } |
1739 | |
1740 | bool hasInheritedDefaultArg() const { |
1741 | return ParmVarDeclBits.HasInheritedDefaultArg; |
1742 | } |
1743 | |
1744 | void setHasInheritedDefaultArg(bool I = true) { |
1745 | ParmVarDeclBits.HasInheritedDefaultArg = I; |
1746 | } |
1747 | |
1748 | QualType getOriginalType() const; |
1749 | |
1750 | /// Sets the function declaration that owns this |
1751 | /// ParmVarDecl. Since ParmVarDecls are often created before the |
1752 | /// FunctionDecls that own them, this routine is required to update |
1753 | /// the DeclContext appropriately. |
1754 | void setOwningFunction(DeclContext *FD) { setDeclContext(FD); } |
1755 | |
1756 | // Implement isa/cast/dyncast/etc. |
1757 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
1758 | static bool classofKind(Kind K) { return K == ParmVar; } |
1759 | |
1760 | private: |
1761 | enum { ParameterIndexSentinel = (1 << NumParameterIndexBits) - 1 }; |
1762 | |
1763 | void setParameterIndex(unsigned parameterIndex) { |
1764 | if (parameterIndex >= ParameterIndexSentinel) { |
1765 | setParameterIndexLarge(parameterIndex); |
1766 | return; |
1767 | } |
1768 | |
1769 | ParmVarDeclBits.ParameterIndex = parameterIndex; |
1770 | assert(ParmVarDeclBits.ParameterIndex == parameterIndex && "truncation!")((ParmVarDeclBits.ParameterIndex == parameterIndex && "truncation!") ? static_cast<void> (0) : __assert_fail ("ParmVarDeclBits.ParameterIndex == parameterIndex && \"truncation!\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 1770, __PRETTY_FUNCTION__)); |
1771 | } |
1772 | unsigned getParameterIndex() const { |
1773 | unsigned d = ParmVarDeclBits.ParameterIndex; |
1774 | return d == ParameterIndexSentinel ? getParameterIndexLarge() : d; |
1775 | } |
1776 | |
1777 | void setParameterIndexLarge(unsigned parameterIndex); |
1778 | unsigned getParameterIndexLarge() const; |
1779 | }; |
1780 | |
1781 | enum class MultiVersionKind { |
1782 | None, |
1783 | Target, |
1784 | CPUSpecific, |
1785 | CPUDispatch |
1786 | }; |
1787 | |
1788 | /// Represents a function declaration or definition. |
1789 | /// |
1790 | /// Since a given function can be declared several times in a program, |
1791 | /// there may be several FunctionDecls that correspond to that |
1792 | /// function. Only one of those FunctionDecls will be found when |
1793 | /// traversing the list of declarations in the context of the |
1794 | /// FunctionDecl (e.g., the translation unit); this FunctionDecl |
1795 | /// contains all of the information known about the function. Other, |
1796 | /// previous declarations of the function are available via the |
1797 | /// getPreviousDecl() chain. |
1798 | class FunctionDecl : public DeclaratorDecl, |
1799 | public DeclContext, |
1800 | public Redeclarable<FunctionDecl> { |
1801 | // This class stores some data in DeclContext::FunctionDeclBits |
1802 | // to save some space. Use the provided accessors to access it. |
1803 | public: |
1804 | /// The kind of templated function a FunctionDecl can be. |
1805 | enum TemplatedKind { |
1806 | // Not templated. |
1807 | TK_NonTemplate, |
1808 | // The pattern in a function template declaration. |
1809 | TK_FunctionTemplate, |
1810 | // A non-template function that is an instantiation or explicit |
1811 | // specialization of a member of a templated class. |
1812 | TK_MemberSpecialization, |
1813 | // An instantiation or explicit specialization of a function template. |
1814 | // Note: this might have been instantiated from a templated class if it |
1815 | // is a class-scope explicit specialization. |
1816 | TK_FunctionTemplateSpecialization, |
1817 | // A function template specialization that hasn't yet been resolved to a |
1818 | // particular specialized function template. |
1819 | TK_DependentFunctionTemplateSpecialization |
1820 | }; |
1821 | |
1822 | /// Stashed information about a defaulted function definition whose body has |
1823 | /// not yet been lazily generated. |
1824 | class DefaultedFunctionInfo final |
1825 | : llvm::TrailingObjects<DefaultedFunctionInfo, DeclAccessPair> { |
1826 | friend TrailingObjects; |
1827 | unsigned NumLookups; |
1828 | |
1829 | public: |
1830 | static DefaultedFunctionInfo *Create(ASTContext &Context, |
1831 | ArrayRef<DeclAccessPair> Lookups); |
1832 | /// Get the unqualified lookup results that should be used in this |
1833 | /// defaulted function definition. |
1834 | ArrayRef<DeclAccessPair> getUnqualifiedLookups() const { |
1835 | return {getTrailingObjects<DeclAccessPair>(), NumLookups}; |
1836 | } |
1837 | }; |
1838 | |
1839 | private: |
1840 | /// A new[]'d array of pointers to VarDecls for the formal |
1841 | /// parameters of this function. This is null if a prototype or if there are |
1842 | /// no formals. |
1843 | ParmVarDecl **ParamInfo = nullptr; |
1844 | |
1845 | /// The active member of this union is determined by |
1846 | /// FunctionDeclBits.HasDefaultedFunctionInfo. |
1847 | union { |
1848 | /// The body of the function. |
1849 | LazyDeclStmtPtr Body; |
1850 | /// Information about a future defaulted function definition. |
1851 | DefaultedFunctionInfo *DefaultedInfo; |
1852 | }; |
1853 | |
1854 | unsigned ODRHash; |
1855 | |
1856 | /// End part of this FunctionDecl's source range. |
1857 | /// |
1858 | /// We could compute the full range in getSourceRange(). However, when we're |
1859 | /// dealing with a function definition deserialized from a PCH/AST file, |
1860 | /// we can only compute the full range once the function body has been |
1861 | /// de-serialized, so it's far better to have the (sometimes-redundant) |
1862 | /// EndRangeLoc. |
1863 | SourceLocation EndRangeLoc; |
1864 | |
1865 | /// The template or declaration that this declaration |
1866 | /// describes or was instantiated from, respectively. |
1867 | /// |
1868 | /// For non-templates, this value will be NULL. For function |
1869 | /// declarations that describe a function template, this will be a |
1870 | /// pointer to a FunctionTemplateDecl. For member functions |
1871 | /// of class template specializations, this will be a MemberSpecializationInfo |
1872 | /// pointer containing information about the specialization. |
1873 | /// For function template specializations, this will be a |
1874 | /// FunctionTemplateSpecializationInfo, which contains information about |
1875 | /// the template being specialized and the template arguments involved in |
1876 | /// that specialization. |
1877 | llvm::PointerUnion<FunctionTemplateDecl *, |
1878 | MemberSpecializationInfo *, |
1879 | FunctionTemplateSpecializationInfo *, |
1880 | DependentFunctionTemplateSpecializationInfo *> |
1881 | TemplateOrSpecialization; |
1882 | |
1883 | /// Provides source/type location info for the declaration name embedded in |
1884 | /// the DeclaratorDecl base class. |
1885 | DeclarationNameLoc DNLoc; |
1886 | |
1887 | /// Specify that this function declaration is actually a function |
1888 | /// template specialization. |
1889 | /// |
1890 | /// \param C the ASTContext. |
1891 | /// |
1892 | /// \param Template the function template that this function template |
1893 | /// specialization specializes. |
1894 | /// |
1895 | /// \param TemplateArgs the template arguments that produced this |
1896 | /// function template specialization from the template. |
1897 | /// |
1898 | /// \param InsertPos If non-NULL, the position in the function template |
1899 | /// specialization set where the function template specialization data will |
1900 | /// be inserted. |
1901 | /// |
1902 | /// \param TSK the kind of template specialization this is. |
1903 | /// |
1904 | /// \param TemplateArgsAsWritten location info of template arguments. |
1905 | /// |
1906 | /// \param PointOfInstantiation point at which the function template |
1907 | /// specialization was first instantiated. |
1908 | void setFunctionTemplateSpecialization(ASTContext &C, |
1909 | FunctionTemplateDecl *Template, |
1910 | const TemplateArgumentList *TemplateArgs, |
1911 | void *InsertPos, |
1912 | TemplateSpecializationKind TSK, |
1913 | const TemplateArgumentListInfo *TemplateArgsAsWritten, |
1914 | SourceLocation PointOfInstantiation); |
1915 | |
1916 | /// Specify that this record is an instantiation of the |
1917 | /// member function FD. |
1918 | void setInstantiationOfMemberFunction(ASTContext &C, FunctionDecl *FD, |
1919 | TemplateSpecializationKind TSK); |
1920 | |
1921 | void setParams(ASTContext &C, ArrayRef<ParmVarDecl *> NewParamInfo); |
1922 | |
1923 | // This is unfortunately needed because ASTDeclWriter::VisitFunctionDecl |
1924 | // need to access this bit but we want to avoid making ASTDeclWriter |
1925 | // a friend of FunctionDeclBitfields just for this. |
1926 | bool isDeletedBit() const { return FunctionDeclBits.IsDeleted; } |
1927 | |
1928 | /// Whether an ODRHash has been stored. |
1929 | bool hasODRHash() const { return FunctionDeclBits.HasODRHash; } |
1930 | |
1931 | /// State that an ODRHash has been stored. |
1932 | void setHasODRHash(bool B = true) { FunctionDeclBits.HasODRHash = B; } |
1933 | |
1934 | protected: |
1935 | FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc, |
1936 | const DeclarationNameInfo &NameInfo, QualType T, |
1937 | TypeSourceInfo *TInfo, StorageClass S, bool isInlineSpecified, |
1938 | ConstexprSpecKind ConstexprKind, |
1939 | Expr *TrailingRequiresClause = nullptr); |
1940 | |
1941 | using redeclarable_base = Redeclarable<FunctionDecl>; |
1942 | |
1943 | FunctionDecl *getNextRedeclarationImpl() override { |
1944 | return getNextRedeclaration(); |
1945 | } |
1946 | |
1947 | FunctionDecl *getPreviousDeclImpl() override { |
1948 | return getPreviousDecl(); |
1949 | } |
1950 | |
1951 | FunctionDecl *getMostRecentDeclImpl() override { |
1952 | return getMostRecentDecl(); |
1953 | } |
1954 | |
1955 | public: |
1956 | friend class ASTDeclReader; |
1957 | friend class ASTDeclWriter; |
1958 | |
1959 | using redecl_range = redeclarable_base::redecl_range; |
1960 | using redecl_iterator = redeclarable_base::redecl_iterator; |
1961 | |
1962 | using redeclarable_base::redecls_begin; |
1963 | using redeclarable_base::redecls_end; |
1964 | using redeclarable_base::redecls; |
1965 | using redeclarable_base::getPreviousDecl; |
1966 | using redeclarable_base::getMostRecentDecl; |
1967 | using redeclarable_base::isFirstDecl; |
1968 | |
1969 | static FunctionDecl * |
1970 | Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, |
1971 | SourceLocation NLoc, DeclarationName N, QualType T, |
1972 | TypeSourceInfo *TInfo, StorageClass SC, bool isInlineSpecified = false, |
1973 | bool hasWrittenPrototype = true, |
1974 | ConstexprSpecKind ConstexprKind = CSK_unspecified, |
1975 | Expr *TrailingRequiresClause = nullptr) { |
1976 | DeclarationNameInfo NameInfo(N, NLoc); |
1977 | return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo, SC, |
1978 | isInlineSpecified, hasWrittenPrototype, |
1979 | ConstexprKind, TrailingRequiresClause); |
1980 | } |
1981 | |
1982 | static FunctionDecl *Create(ASTContext &C, DeclContext *DC, |
1983 | SourceLocation StartLoc, |
1984 | const DeclarationNameInfo &NameInfo, QualType T, |
1985 | TypeSourceInfo *TInfo, StorageClass SC, |
1986 | bool isInlineSpecified, bool hasWrittenPrototype, |
1987 | ConstexprSpecKind ConstexprKind, |
1988 | Expr *TrailingRequiresClause); |
1989 | |
1990 | static FunctionDecl *CreateDeserialized(ASTContext &C, unsigned ID); |
1991 | |
1992 | DeclarationNameInfo getNameInfo() const { |
1993 | return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc); |
1994 | } |
1995 | |
1996 | void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, |
1997 | bool Qualified) const override; |
1998 | |
1999 | void setRangeEnd(SourceLocation E) { EndRangeLoc = E; } |
2000 | |
2001 | /// Returns the location of the ellipsis of a variadic function. |
2002 | SourceLocation getEllipsisLoc() const { |
2003 | const auto *FPT = getType()->getAs<FunctionProtoType>(); |
2004 | if (FPT && FPT->isVariadic()) |
2005 | return FPT->getEllipsisLoc(); |
2006 | return SourceLocation(); |
2007 | } |
2008 | |
2009 | SourceRange getSourceRange() const override LLVM_READONLY__attribute__((__pure__)); |
2010 | |
2011 | // Function definitions. |
2012 | // |
2013 | // A function declaration may be: |
2014 | // - a non defining declaration, |
2015 | // - a definition. A function may be defined because: |
2016 | // - it has a body, or will have it in the case of late parsing. |
2017 | // - it has an uninstantiated body. The body does not exist because the |
2018 | // function is not used yet, but the declaration is considered a |
2019 | // definition and does not allow other definition of this function. |
2020 | // - it does not have a user specified body, but it does not allow |
2021 | // redefinition, because it is deleted/defaulted or is defined through |
2022 | // some other mechanism (alias, ifunc). |
2023 | |
2024 | /// Returns true if the function has a body. |
2025 | /// |
2026 | /// The function body might be in any of the (re-)declarations of this |
2027 | /// function. The variant that accepts a FunctionDecl pointer will set that |
2028 | /// function declaration to the actual declaration containing the body (if |
2029 | /// there is one). |
2030 | bool hasBody(const FunctionDecl *&Definition) const; |
2031 | |
2032 | bool hasBody() const override { |
2033 | const FunctionDecl* Definition; |
2034 | return hasBody(Definition); |
2035 | } |
2036 | |
2037 | /// Returns whether the function has a trivial body that does not require any |
2038 | /// specific codegen. |
2039 | bool hasTrivialBody() const; |
2040 | |
2041 | /// Returns true if the function has a definition that does not need to be |
2042 | /// instantiated. |
2043 | /// |
2044 | /// The variant that accepts a FunctionDecl pointer will set that function |
2045 | /// declaration to the declaration that is a definition (if there is one). |
2046 | bool isDefined(const FunctionDecl *&Definition) const; |
2047 | |
2048 | bool isDefined() const { |
2049 | const FunctionDecl* Definition; |
2050 | return isDefined(Definition); |
2051 | } |
2052 | |
2053 | /// Get the definition for this declaration. |
2054 | FunctionDecl *getDefinition() { |
2055 | const FunctionDecl *Definition; |
2056 | if (isDefined(Definition)) |
2057 | return const_cast<FunctionDecl *>(Definition); |
2058 | return nullptr; |
2059 | } |
2060 | const FunctionDecl *getDefinition() const { |
2061 | return const_cast<FunctionDecl *>(this)->getDefinition(); |
2062 | } |
2063 | |
2064 | /// Retrieve the body (definition) of the function. The function body might be |
2065 | /// in any of the (re-)declarations of this function. The variant that accepts |
2066 | /// a FunctionDecl pointer will set that function declaration to the actual |
2067 | /// declaration containing the body (if there is one). |
2068 | /// NOTE: For checking if there is a body, use hasBody() instead, to avoid |
2069 | /// unnecessary AST de-serialization of the body. |
2070 | Stmt *getBody(const FunctionDecl *&Definition) const; |
2071 | |
2072 | Stmt *getBody() const override { |
2073 | const FunctionDecl* Definition; |
2074 | return getBody(Definition); |
2075 | } |
2076 | |
2077 | /// Returns whether this specific declaration of the function is also a |
2078 | /// definition that does not contain uninstantiated body. |
2079 | /// |
2080 | /// This does not determine whether the function has been defined (e.g., in a |
2081 | /// previous definition); for that information, use isDefined. |
2082 | /// |
2083 | /// Note: the function declaration does not become a definition until the |
2084 | /// parser reaches the definition, if called before, this function will return |
2085 | /// `false`. |
2086 | bool isThisDeclarationADefinition() const { |
2087 | return isDeletedAsWritten() || isDefaulted() || |
2088 | doesThisDeclarationHaveABody() || hasSkippedBody() || |
2089 | willHaveBody() || hasDefiningAttr(); |
2090 | } |
2091 | |
2092 | /// Returns whether this specific declaration of the function has a body. |
2093 | bool doesThisDeclarationHaveABody() const { |
2094 | return (!FunctionDeclBits.HasDefaultedFunctionInfo && Body) || |
2095 | isLateTemplateParsed(); |
2096 | } |
2097 | |
2098 | void setBody(Stmt *B); |
2099 | void setLazyBody(uint64_t Offset) { |
2100 | FunctionDeclBits.HasDefaultedFunctionInfo = false; |
2101 | Body = LazyDeclStmtPtr(Offset); |
2102 | } |
2103 | |
2104 | void setDefaultedFunctionInfo(DefaultedFunctionInfo *Info); |
2105 | DefaultedFunctionInfo *getDefaultedFunctionInfo() const; |
2106 | |
2107 | /// Whether this function is variadic. |
2108 | bool isVariadic() const; |
2109 | |
2110 | /// Whether this function is marked as virtual explicitly. |
2111 | bool isVirtualAsWritten() const { |
2112 | return FunctionDeclBits.IsVirtualAsWritten; |
2113 | } |
2114 | |
2115 | /// State that this function is marked as virtual explicitly. |
2116 | void setVirtualAsWritten(bool V) { FunctionDeclBits.IsVirtualAsWritten = V; } |
2117 | |
2118 | /// Whether this virtual function is pure, i.e. makes the containing class |
2119 | /// abstract. |
2120 | bool isPure() const { return FunctionDeclBits.IsPure; } |
2121 | void setPure(bool P = true); |
2122 | |
2123 | /// Whether this templated function will be late parsed. |
2124 | bool isLateTemplateParsed() const { |
2125 | return FunctionDeclBits.IsLateTemplateParsed; |
2126 | } |
2127 | |
2128 | /// State that this templated function will be late parsed. |
2129 | void setLateTemplateParsed(bool ILT = true) { |
2130 | FunctionDeclBits.IsLateTemplateParsed = ILT; |
2131 | } |
2132 | |
2133 | /// Whether this function is "trivial" in some specialized C++ senses. |
2134 | /// Can only be true for default constructors, copy constructors, |
2135 | /// copy assignment operators, and destructors. Not meaningful until |
2136 | /// the class has been fully built by Sema. |
2137 | bool isTrivial() const { return FunctionDeclBits.IsTrivial; } |
2138 | void setTrivial(bool IT) { FunctionDeclBits.IsTrivial = IT; } |
2139 | |
2140 | bool isTrivialForCall() const { return FunctionDeclBits.IsTrivialForCall; } |
2141 | void setTrivialForCall(bool IT) { FunctionDeclBits.IsTrivialForCall = IT; } |
2142 | |
2143 | /// Whether this function is defaulted. Valid for e.g. |
2144 | /// special member functions, defaulted comparisions (not methods!). |
2145 | bool isDefaulted() const { return FunctionDeclBits.IsDefaulted; } |
2146 | void setDefaulted(bool D = true) { FunctionDeclBits.IsDefaulted = D; } |
2147 | |
2148 | /// Whether this function is explicitly defaulted. |
2149 | bool isExplicitlyDefaulted() const { |
2150 | return FunctionDeclBits.IsExplicitlyDefaulted; |
2151 | } |
2152 | |
2153 | /// State that this function is explicitly defaulted. |
2154 | void setExplicitlyDefaulted(bool ED = true) { |
2155 | FunctionDeclBits.IsExplicitlyDefaulted = ED; |
2156 | } |
2157 | |
2158 | /// True if this method is user-declared and was not |
2159 | /// deleted or defaulted on its first declaration. |
2160 | bool isUserProvided() const { |
2161 | auto *DeclAsWritten = this; |
2162 | if (FunctionDecl *Pattern = getTemplateInstantiationPattern()) |
2163 | DeclAsWritten = Pattern; |
2164 | return !(DeclAsWritten->isDeleted() || |
2165 | DeclAsWritten->getCanonicalDecl()->isDefaulted()); |
2166 | } |
2167 | |
2168 | /// Whether falling off this function implicitly returns null/zero. |
2169 | /// If a more specific implicit return value is required, front-ends |
2170 | /// should synthesize the appropriate return statements. |
2171 | bool hasImplicitReturnZero() const { |
2172 | return FunctionDeclBits.HasImplicitReturnZero; |
2173 | } |
2174 | |
2175 | /// State that falling off this function implicitly returns null/zero. |
2176 | /// If a more specific implicit return value is required, front-ends |
2177 | /// should synthesize the appropriate return statements. |
2178 | void setHasImplicitReturnZero(bool IRZ) { |
2179 | FunctionDeclBits.HasImplicitReturnZero = IRZ; |
2180 | } |
2181 | |
2182 | /// Whether this function has a prototype, either because one |
2183 | /// was explicitly written or because it was "inherited" by merging |
2184 | /// a declaration without a prototype with a declaration that has a |
2185 | /// prototype. |
2186 | bool hasPrototype() const { |
2187 | return hasWrittenPrototype() || hasInheritedPrototype(); |
2188 | } |
2189 | |
2190 | /// Whether this function has a written prototype. |
2191 | bool hasWrittenPrototype() const { |
2192 | return FunctionDeclBits.HasWrittenPrototype; |
2193 | } |
2194 | |
2195 | /// State that this function has a written prototype. |
2196 | void setHasWrittenPrototype(bool P = true) { |
2197 | FunctionDeclBits.HasWrittenPrototype = P; |
2198 | } |
2199 | |
2200 | /// Whether this function inherited its prototype from a |
2201 | /// previous declaration. |
2202 | bool hasInheritedPrototype() const { |
2203 | return FunctionDeclBits.HasInheritedPrototype; |
2204 | } |
2205 | |
2206 | /// State that this function inherited its prototype from a |
2207 | /// previous declaration. |
2208 | void setHasInheritedPrototype(bool P = true) { |
2209 | FunctionDeclBits.HasInheritedPrototype = P; |
2210 | } |
2211 | |
2212 | /// Whether this is a (C++11) constexpr function or constexpr constructor. |
2213 | bool isConstexpr() const { |
2214 | return FunctionDeclBits.ConstexprKind != CSK_unspecified; |
2215 | } |
2216 | void setConstexprKind(ConstexprSpecKind CSK) { |
2217 | FunctionDeclBits.ConstexprKind = CSK; |
2218 | } |
2219 | ConstexprSpecKind getConstexprKind() const { |
2220 | return static_cast<ConstexprSpecKind>(FunctionDeclBits.ConstexprKind); |
2221 | } |
2222 | bool isConstexprSpecified() const { |
2223 | return FunctionDeclBits.ConstexprKind == CSK_constexpr; |
2224 | } |
2225 | bool isConsteval() const { |
2226 | return FunctionDeclBits.ConstexprKind == CSK_consteval; |
2227 | } |
2228 | |
2229 | /// Whether the instantiation of this function is pending. |
2230 | /// This bit is set when the decision to instantiate this function is made |
2231 | /// and unset if and when the function body is created. That leaves out |
2232 | /// cases where instantiation did not happen because the template definition |
2233 | /// was not seen in this TU. This bit remains set in those cases, under the |
2234 | /// assumption that the instantiation will happen in some other TU. |
2235 | bool instantiationIsPending() const { |
2236 | return FunctionDeclBits.InstantiationIsPending; |
2237 | } |
2238 | |
2239 | /// State that the instantiation of this function is pending. |
2240 | /// (see instantiationIsPending) |
2241 | void setInstantiationIsPending(bool IC) { |
2242 | FunctionDeclBits.InstantiationIsPending = IC; |
2243 | } |
2244 | |
2245 | /// Indicates the function uses __try. |
2246 | bool usesSEHTry() const { return FunctionDeclBits.UsesSEHTry; } |
2247 | void setUsesSEHTry(bool UST) { FunctionDeclBits.UsesSEHTry = UST; } |
2248 | |
2249 | /// Indicates the function uses Floating Point constrained intrinsics |
2250 | bool usesFPIntrin() const { return FunctionDeclBits.UsesFPIntrin; } |
2251 | void setUsesFPIntrin(bool Val) { FunctionDeclBits.UsesFPIntrin = Val; } |
2252 | |
2253 | /// Whether this function has been deleted. |
2254 | /// |
2255 | /// A function that is "deleted" (via the C++0x "= delete" syntax) |
2256 | /// acts like a normal function, except that it cannot actually be |
2257 | /// called or have its address taken. Deleted functions are |
2258 | /// typically used in C++ overload resolution to attract arguments |
2259 | /// whose type or lvalue/rvalue-ness would permit the use of a |
2260 | /// different overload that would behave incorrectly. For example, |
2261 | /// one might use deleted functions to ban implicit conversion from |
2262 | /// a floating-point number to an Integer type: |
2263 | /// |
2264 | /// @code |
2265 | /// struct Integer { |
2266 | /// Integer(long); // construct from a long |
2267 | /// Integer(double) = delete; // no construction from float or double |
2268 | /// Integer(long double) = delete; // no construction from long double |
2269 | /// }; |
2270 | /// @endcode |
2271 | // If a function is deleted, its first declaration must be. |
2272 | bool isDeleted() const { |
2273 | return getCanonicalDecl()->FunctionDeclBits.IsDeleted; |
2274 | } |
2275 | |
2276 | bool isDeletedAsWritten() const { |
2277 | return FunctionDeclBits.IsDeleted && !isDefaulted(); |
2278 | } |
2279 | |
2280 | void setDeletedAsWritten(bool D = true) { FunctionDeclBits.IsDeleted = D; } |
2281 | |
2282 | /// Determines whether this function is "main", which is the |
2283 | /// entry point into an executable program. |
2284 | bool isMain() const; |
2285 | |
2286 | /// Determines whether this function is a MSVCRT user defined entry |
2287 | /// point. |
2288 | bool isMSVCRTEntryPoint() const; |
2289 | |
2290 | /// Determines whether this operator new or delete is one |
2291 | /// of the reserved global placement operators: |
2292 | /// void *operator new(size_t, void *); |
2293 | /// void *operator new[](size_t, void *); |
2294 | /// void operator delete(void *, void *); |
2295 | /// void operator delete[](void *, void *); |
2296 | /// These functions have special behavior under [new.delete.placement]: |
2297 | /// These functions are reserved, a C++ program may not define |
2298 | /// functions that displace the versions in the Standard C++ library. |
2299 | /// The provisions of [basic.stc.dynamic] do not apply to these |
2300 | /// reserved placement forms of operator new and operator delete. |
2301 | /// |
2302 | /// This function must be an allocation or deallocation function. |
2303 | bool isReservedGlobalPlacementOperator() const; |
2304 | |
2305 | /// Determines whether this function is one of the replaceable |
2306 | /// global allocation functions: |
2307 | /// void *operator new(size_t); |
2308 | /// void *operator new(size_t, const std::nothrow_t &) noexcept; |
2309 | /// void *operator new[](size_t); |
2310 | /// void *operator new[](size_t, const std::nothrow_t &) noexcept; |
2311 | /// void operator delete(void *) noexcept; |
2312 | /// void operator delete(void *, std::size_t) noexcept; [C++1y] |
2313 | /// void operator delete(void *, const std::nothrow_t &) noexcept; |
2314 | /// void operator delete[](void *) noexcept; |
2315 | /// void operator delete[](void *, std::size_t) noexcept; [C++1y] |
2316 | /// void operator delete[](void *, const std::nothrow_t &) noexcept; |
2317 | /// These functions have special behavior under C++1y [expr.new]: |
2318 | /// An implementation is allowed to omit a call to a replaceable global |
2319 | /// allocation function. [...] |
2320 | /// |
2321 | /// If this function is an aligned allocation/deallocation function, return |
2322 | /// the parameter number of the requested alignment through AlignmentParam. |
2323 | /// |
2324 | /// If this function is an allocation/deallocation function that takes |
2325 | /// the `std::nothrow_t` tag, return true through IsNothrow, |
2326 | bool isReplaceableGlobalAllocationFunction( |
2327 | Optional<unsigned> *AlignmentParam = nullptr, |
2328 | bool *IsNothrow = nullptr) const; |
2329 | |
2330 | /// Determine if this function provides an inline implementation of a builtin. |
2331 | bool isInlineBuiltinDeclaration() const; |
2332 | |
2333 | /// Determine whether this is a destroying operator delete. |
2334 | bool isDestroyingOperatorDelete() const; |
2335 | |
2336 | /// Compute the language linkage. |
2337 | LanguageLinkage getLanguageLinkage() const; |
2338 | |
2339 | /// Determines whether this function is a function with |
2340 | /// external, C linkage. |
2341 | bool isExternC() const; |
2342 | |
2343 | /// Determines whether this function's context is, or is nested within, |
2344 | /// a C++ extern "C" linkage spec. |
2345 | bool isInExternCContext() const; |
2346 | |
2347 | /// Determines whether this function's context is, or is nested within, |
2348 | /// a C++ extern "C++" linkage spec. |
2349 | bool isInExternCXXContext() const; |
2350 | |
2351 | /// Determines whether this is a global function. |
2352 | bool isGlobal() const; |
2353 | |
2354 | /// Determines whether this function is known to be 'noreturn', through |
2355 | /// an attribute on its declaration or its type. |
2356 | bool isNoReturn() const; |
2357 | |
2358 | /// True if the function was a definition but its body was skipped. |
2359 | bool hasSkippedBody() const { return FunctionDeclBits.HasSkippedBody; } |
2360 | void setHasSkippedBody(bool Skipped = true) { |
2361 | FunctionDeclBits.HasSkippedBody = Skipped; |
2362 | } |
2363 | |
2364 | /// True if this function will eventually have a body, once it's fully parsed. |
2365 | bool willHaveBody() const { return FunctionDeclBits.WillHaveBody; } |
2366 | void setWillHaveBody(bool V = true) { FunctionDeclBits.WillHaveBody = V; } |
2367 | |
2368 | /// True if this function is considered a multiversioned function. |
2369 | bool isMultiVersion() const { |
2370 | return getCanonicalDecl()->FunctionDeclBits.IsMultiVersion; |
2371 | } |
2372 | |
2373 | /// Sets the multiversion state for this declaration and all of its |
2374 | /// redeclarations. |
2375 | void setIsMultiVersion(bool V = true) { |
2376 | getCanonicalDecl()->FunctionDeclBits.IsMultiVersion = V; |
2377 | } |
2378 | |
2379 | /// Gets the kind of multiversioning attribute this declaration has. Note that |
2380 | /// this can return a value even if the function is not multiversion, such as |
2381 | /// the case of 'target'. |
2382 | MultiVersionKind getMultiVersionKind() const; |
2383 | |
2384 | |
2385 | /// True if this function is a multiversioned dispatch function as a part of |
2386 | /// the cpu_specific/cpu_dispatch functionality. |
2387 | bool isCPUDispatchMultiVersion() const; |
2388 | /// True if this function is a multiversioned processor specific function as a |
2389 | /// part of the cpu_specific/cpu_dispatch functionality. |
2390 | bool isCPUSpecificMultiVersion() const; |
2391 | |
2392 | /// True if this function is a multiversioned dispatch function as a part of |
2393 | /// the target functionality. |
2394 | bool isTargetMultiVersion() const; |
2395 | |
2396 | /// \brief Get the associated-constraints of this function declaration. |
2397 | /// Currently, this will either be a vector of size 1 containing the |
2398 | /// trailing-requires-clause or an empty vector. |
2399 | /// |
2400 | /// Use this instead of getTrailingRequiresClause for concepts APIs that |
2401 | /// accept an ArrayRef of constraint expressions. |
2402 | void getAssociatedConstraints(SmallVectorImpl<const Expr *> &AC) const { |
2403 | if (auto *TRC = getTrailingRequiresClause()) |
2404 | AC.push_back(TRC); |
2405 | } |
2406 | |
2407 | void setPreviousDeclaration(FunctionDecl * PrevDecl); |
2408 | |
2409 | FunctionDecl *getCanonicalDecl() override; |
2410 | const FunctionDecl *getCanonicalDecl() const { |
2411 | return const_cast<FunctionDecl*>(this)->getCanonicalDecl(); |
2412 | } |
2413 | |
2414 | unsigned getBuiltinID(bool ConsiderWrapperFunctions = false) const; |
2415 | |
2416 | // ArrayRef interface to parameters. |
2417 | ArrayRef<ParmVarDecl *> parameters() const { |
2418 | return {ParamInfo, getNumParams()}; |
2419 | } |
2420 | MutableArrayRef<ParmVarDecl *> parameters() { |
2421 | return {ParamInfo, getNumParams()}; |
2422 | } |
2423 | |
2424 | // Iterator access to formal parameters. |
2425 | using param_iterator = MutableArrayRef<ParmVarDecl *>::iterator; |
2426 | using param_const_iterator = ArrayRef<ParmVarDecl *>::const_iterator; |
2427 | |
2428 | bool param_empty() const { return parameters().empty(); } |
2429 | param_iterator param_begin() { return parameters().begin(); } |
2430 | param_iterator param_end() { return parameters().end(); } |
2431 | param_const_iterator param_begin() const { return parameters().begin(); } |
2432 | param_const_iterator param_end() const { return parameters().end(); } |
2433 | size_t param_size() const { return parameters().size(); } |
2434 | |
2435 | /// Return the number of parameters this function must have based on its |
2436 | /// FunctionType. This is the length of the ParamInfo array after it has been |
2437 | /// created. |
2438 | unsigned getNumParams() const; |
2439 | |
2440 | const ParmVarDecl *getParamDecl(unsigned i) const { |
2441 | assert(i < getNumParams() && "Illegal param #")((i < getNumParams() && "Illegal param #") ? static_cast <void> (0) : __assert_fail ("i < getNumParams() && \"Illegal param #\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 2441, __PRETTY_FUNCTION__)); |
2442 | return ParamInfo[i]; |
2443 | } |
2444 | ParmVarDecl *getParamDecl(unsigned i) { |
2445 | assert(i < getNumParams() && "Illegal param #")((i < getNumParams() && "Illegal param #") ? static_cast <void> (0) : __assert_fail ("i < getNumParams() && \"Illegal param #\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 2445, __PRETTY_FUNCTION__)); |
2446 | return ParamInfo[i]; |
2447 | } |
2448 | void setParams(ArrayRef<ParmVarDecl *> NewParamInfo) { |
2449 | setParams(getASTContext(), NewParamInfo); |
2450 | } |
2451 | |
2452 | /// Returns the minimum number of arguments needed to call this function. This |
2453 | /// may be fewer than the number of function parameters, if some of the |
2454 | /// parameters have default arguments (in C++). |
2455 | unsigned getMinRequiredArguments() const; |
2456 | |
2457 | /// Determine whether this function has a single parameter, or multiple |
2458 | /// parameters where all but the first have default arguments. |
2459 | /// |
2460 | /// This notion is used in the definition of copy/move constructors and |
2461 | /// initializer list constructors. Note that, unlike getMinRequiredArguments, |
2462 | /// parameter packs are not treated specially here. |
2463 | bool hasOneParamOrDefaultArgs() const; |
2464 | |
2465 | /// Find the source location information for how the type of this function |
2466 | /// was written. May be absent (for example if the function was declared via |
2467 | /// a typedef) and may contain a different type from that of the function |
2468 | /// (for example if the function type was adjusted by an attribute). |
2469 | FunctionTypeLoc getFunctionTypeLoc() const; |
2470 | |
2471 | QualType getReturnType() const { |
2472 | return getType()->castAs<FunctionType>()->getReturnType(); |
2473 | } |
2474 | |
2475 | /// Attempt to compute an informative source range covering the |
2476 | /// function return type. This may omit qualifiers and other information with |
2477 | /// limited representation in the AST. |
2478 | SourceRange getReturnTypeSourceRange() const; |
2479 | |
2480 | /// Attempt to compute an informative source range covering the |
2481 | /// function parameters, including the ellipsis of a variadic function. |
2482 | /// The source range excludes the parentheses, and is invalid if there are |
2483 | /// no parameters and no ellipsis. |
2484 | SourceRange getParametersSourceRange() const; |
2485 | |
2486 | /// Get the declared return type, which may differ from the actual return |
2487 | /// type if the return type is deduced. |
2488 | QualType getDeclaredReturnType() const { |
2489 | auto *TSI = getTypeSourceInfo(); |
2490 | QualType T = TSI ? TSI->getType() : getType(); |
2491 | return T->castAs<FunctionType>()->getReturnType(); |
2492 | } |
2493 | |
2494 | /// Gets the ExceptionSpecificationType as declared. |
2495 | ExceptionSpecificationType getExceptionSpecType() const { |
2496 | auto *TSI = getTypeSourceInfo(); |
2497 | QualType T = TSI ? TSI->getType() : getType(); |
2498 | const auto *FPT = T->getAs<FunctionProtoType>(); |
2499 | return FPT ? FPT->getExceptionSpecType() : EST_None; |
2500 | } |
2501 | |
2502 | /// Attempt to compute an informative source range covering the |
2503 | /// function exception specification, if any. |
2504 | SourceRange getExceptionSpecSourceRange() const; |
2505 | |
2506 | /// Determine the type of an expression that calls this function. |
2507 | QualType getCallResultType() const { |
2508 | return getType()->castAs<FunctionType>()->getCallResultType( |
2509 | getASTContext()); |
2510 | } |
2511 | |
2512 | /// Returns the storage class as written in the source. For the |
2513 | /// computed linkage of symbol, see getLinkage. |
2514 | StorageClass getStorageClass() const { |
2515 | return static_cast<StorageClass>(FunctionDeclBits.SClass); |
2516 | } |
2517 | |
2518 | /// Sets the storage class as written in the source. |
2519 | void setStorageClass(StorageClass SClass) { |
2520 | FunctionDeclBits.SClass = SClass; |
2521 | } |
2522 | |
2523 | /// Determine whether the "inline" keyword was specified for this |
2524 | /// function. |
2525 | bool isInlineSpecified() const { return FunctionDeclBits.IsInlineSpecified; } |
2526 | |
2527 | /// Set whether the "inline" keyword was specified for this function. |
2528 | void setInlineSpecified(bool I) { |
2529 | FunctionDeclBits.IsInlineSpecified = I; |
2530 | FunctionDeclBits.IsInline = I; |
2531 | } |
2532 | |
2533 | /// Flag that this function is implicitly inline. |
2534 | void setImplicitlyInline(bool I = true) { FunctionDeclBits.IsInline = I; } |
2535 | |
2536 | /// Determine whether this function should be inlined, because it is |
2537 | /// either marked "inline" or "constexpr" or is a member function of a class |
2538 | /// that was defined in the class body. |
2539 | bool isInlined() const { return FunctionDeclBits.IsInline; } |
2540 | |
2541 | bool isInlineDefinitionExternallyVisible() const; |
2542 | |
2543 | bool isMSExternInline() const; |
2544 | |
2545 | bool doesDeclarationForceExternallyVisibleDefinition() const; |
2546 | |
2547 | bool isStatic() const { return getStorageClass() == SC_Static; } |
2548 | |
2549 | /// Whether this function declaration represents an C++ overloaded |
2550 | /// operator, e.g., "operator+". |
2551 | bool isOverloadedOperator() const { |
2552 | return getOverloadedOperator() != OO_None; |
2553 | } |
2554 | |
2555 | OverloadedOperatorKind getOverloadedOperator() const; |
2556 | |
2557 | const IdentifierInfo *getLiteralIdentifier() const; |
2558 | |
2559 | /// If this function is an instantiation of a member function |
2560 | /// of a class template specialization, retrieves the function from |
2561 | /// which it was instantiated. |
2562 | /// |
2563 | /// This routine will return non-NULL for (non-templated) member |
2564 | /// functions of class templates and for instantiations of function |
2565 | /// templates. For example, given: |
2566 | /// |
2567 | /// \code |
2568 | /// template<typename T> |
2569 | /// struct X { |
2570 | /// void f(T); |
2571 | /// }; |
2572 | /// \endcode |
2573 | /// |
2574 | /// The declaration for X<int>::f is a (non-templated) FunctionDecl |
2575 | /// whose parent is the class template specialization X<int>. For |
2576 | /// this declaration, getInstantiatedFromFunction() will return |
2577 | /// the FunctionDecl X<T>::A. When a complete definition of |
2578 | /// X<int>::A is required, it will be instantiated from the |
2579 | /// declaration returned by getInstantiatedFromMemberFunction(). |
2580 | FunctionDecl *getInstantiatedFromMemberFunction() const; |
2581 | |
2582 | /// What kind of templated function this is. |
2583 | TemplatedKind getTemplatedKind() const; |
2584 | |
2585 | /// If this function is an instantiation of a member function of a |
2586 | /// class template specialization, retrieves the member specialization |
2587 | /// information. |
2588 | MemberSpecializationInfo *getMemberSpecializationInfo() const; |
2589 | |
2590 | /// Specify that this record is an instantiation of the |
2591 | /// member function FD. |
2592 | void setInstantiationOfMemberFunction(FunctionDecl *FD, |
2593 | TemplateSpecializationKind TSK) { |
2594 | setInstantiationOfMemberFunction(getASTContext(), FD, TSK); |
2595 | } |
2596 | |
2597 | /// Retrieves the function template that is described by this |
2598 | /// function declaration. |
2599 | /// |
2600 | /// Every function template is represented as a FunctionTemplateDecl |
2601 | /// and a FunctionDecl (or something derived from FunctionDecl). The |
2602 | /// former contains template properties (such as the template |
2603 | /// parameter lists) while the latter contains the actual |
2604 | /// description of the template's |
2605 | /// contents. FunctionTemplateDecl::getTemplatedDecl() retrieves the |
2606 | /// FunctionDecl that describes the function template, |
2607 | /// getDescribedFunctionTemplate() retrieves the |
2608 | /// FunctionTemplateDecl from a FunctionDecl. |
2609 | FunctionTemplateDecl *getDescribedFunctionTemplate() const; |
2610 | |
2611 | void setDescribedFunctionTemplate(FunctionTemplateDecl *Template); |
2612 | |
2613 | /// Determine whether this function is a function template |
2614 | /// specialization. |
2615 | bool isFunctionTemplateSpecialization() const { |
2616 | return getPrimaryTemplate() != nullptr; |
2617 | } |
2618 | |
2619 | /// If this function is actually a function template specialization, |
2620 | /// retrieve information about this function template specialization. |
2621 | /// Otherwise, returns NULL. |
2622 | FunctionTemplateSpecializationInfo *getTemplateSpecializationInfo() const; |
2623 | |
2624 | /// Determines whether this function is a function template |
2625 | /// specialization or a member of a class template specialization that can |
2626 | /// be implicitly instantiated. |
2627 | bool isImplicitlyInstantiable() const; |
2628 | |
2629 | /// Determines if the given function was instantiated from a |
2630 | /// function template. |
2631 | bool isTemplateInstantiation() const; |
2632 | |
2633 | /// Retrieve the function declaration from which this function could |
2634 | /// be instantiated, if it is an instantiation (rather than a non-template |
2635 | /// or a specialization, for example). |
2636 | /// |
2637 | /// If \p ForDefinition is \c false, explicit specializations will be treated |
2638 | /// as if they were implicit instantiations. This will then find the pattern |
2639 | /// corresponding to non-definition portions of the declaration, such as |
2640 | /// default arguments and the exception specification. |
2641 | FunctionDecl * |
2642 | getTemplateInstantiationPattern(bool ForDefinition = true) const; |
2643 | |
2644 | /// Retrieve the primary template that this function template |
2645 | /// specialization either specializes or was instantiated from. |
2646 | /// |
2647 | /// If this function declaration is not a function template specialization, |
2648 | /// returns NULL. |
2649 | FunctionTemplateDecl *getPrimaryTemplate() const; |
2650 | |
2651 | /// Retrieve the template arguments used to produce this function |
2652 | /// template specialization from the primary template. |
2653 | /// |
2654 | /// If this function declaration is not a function template specialization, |
2655 | /// returns NULL. |
2656 | const TemplateArgumentList *getTemplateSpecializationArgs() const; |
2657 | |
2658 | /// Retrieve the template argument list as written in the sources, |
2659 | /// if any. |
2660 | /// |
2661 | /// If this function declaration is not a function template specialization |
2662 | /// or if it had no explicit template argument list, returns NULL. |
2663 | /// Note that it an explicit template argument list may be written empty, |
2664 | /// e.g., template<> void foo<>(char* s); |
2665 | const ASTTemplateArgumentListInfo* |
2666 | getTemplateSpecializationArgsAsWritten() const; |
2667 | |
2668 | /// Specify that this function declaration is actually a function |
2669 | /// template specialization. |
2670 | /// |
2671 | /// \param Template the function template that this function template |
2672 | /// specialization specializes. |
2673 | /// |
2674 | /// \param TemplateArgs the template arguments that produced this |
2675 | /// function template specialization from the template. |
2676 | /// |
2677 | /// \param InsertPos If non-NULL, the position in the function template |
2678 | /// specialization set where the function template specialization data will |
2679 | /// be inserted. |
2680 | /// |
2681 | /// \param TSK the kind of template specialization this is. |
2682 | /// |
2683 | /// \param TemplateArgsAsWritten location info of template arguments. |
2684 | /// |
2685 | /// \param PointOfInstantiation point at which the function template |
2686 | /// specialization was first instantiated. |
2687 | void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template, |
2688 | const TemplateArgumentList *TemplateArgs, |
2689 | void *InsertPos, |
2690 | TemplateSpecializationKind TSK = TSK_ImplicitInstantiation, |
2691 | const TemplateArgumentListInfo *TemplateArgsAsWritten = nullptr, |
2692 | SourceLocation PointOfInstantiation = SourceLocation()) { |
2693 | setFunctionTemplateSpecialization(getASTContext(), Template, TemplateArgs, |
2694 | InsertPos, TSK, TemplateArgsAsWritten, |
2695 | PointOfInstantiation); |
2696 | } |
2697 | |
2698 | /// Specifies that this function declaration is actually a |
2699 | /// dependent function template specialization. |
2700 | void setDependentTemplateSpecialization(ASTContext &Context, |
2701 | const UnresolvedSetImpl &Templates, |
2702 | const TemplateArgumentListInfo &TemplateArgs); |
2703 | |
2704 | DependentFunctionTemplateSpecializationInfo * |
2705 | getDependentSpecializationInfo() const; |
2706 | |
2707 | /// Determine what kind of template instantiation this function |
2708 | /// represents. |
2709 | TemplateSpecializationKind getTemplateSpecializationKind() const; |
2710 | |
2711 | /// Determine the kind of template specialization this function represents |
2712 | /// for the purpose of template instantiation. |
2713 | TemplateSpecializationKind |
2714 | getTemplateSpecializationKindForInstantiation() const; |
2715 | |
2716 | /// Determine what kind of template instantiation this function |
2717 | /// represents. |
2718 | void setTemplateSpecializationKind(TemplateSpecializationKind TSK, |
2719 | SourceLocation PointOfInstantiation = SourceLocation()); |
2720 | |
2721 | /// Retrieve the (first) point of instantiation of a function template |
2722 | /// specialization or a member of a class template specialization. |
2723 | /// |
2724 | /// \returns the first point of instantiation, if this function was |
2725 | /// instantiated from a template; otherwise, returns an invalid source |
2726 | /// location. |
2727 | SourceLocation getPointOfInstantiation() const; |
2728 | |
2729 | /// Determine whether this is or was instantiated from an out-of-line |
2730 | /// definition of a member function. |
2731 | bool isOutOfLine() const override; |
2732 | |
2733 | /// Identify a memory copying or setting function. |
2734 | /// If the given function is a memory copy or setting function, returns |
2735 | /// the corresponding Builtin ID. If the function is not a memory function, |
2736 | /// returns 0. |
2737 | unsigned getMemoryFunctionKind() const; |
2738 | |
2739 | /// Returns ODRHash of the function. This value is calculated and |
2740 | /// stored on first call, then the stored value returned on the other calls. |
2741 | unsigned getODRHash(); |
2742 | |
2743 | /// Returns cached ODRHash of the function. This must have been previously |
2744 | /// computed and stored. |
2745 | unsigned getODRHash() const; |
2746 | |
2747 | // Implement isa/cast/dyncast/etc. |
2748 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
2749 | static bool classofKind(Kind K) { |
2750 | return K >= firstFunction && K <= lastFunction; |
2751 | } |
2752 | static DeclContext *castToDeclContext(const FunctionDecl *D) { |
2753 | return static_cast<DeclContext *>(const_cast<FunctionDecl*>(D)); |
2754 | } |
2755 | static FunctionDecl *castFromDeclContext(const DeclContext *DC) { |
2756 | return static_cast<FunctionDecl *>(const_cast<DeclContext*>(DC)); |
2757 | } |
2758 | }; |
2759 | |
2760 | /// Represents a member of a struct/union/class. |
2761 | class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> { |
2762 | unsigned BitField : 1; |
2763 | unsigned Mutable : 1; |
2764 | mutable unsigned CachedFieldIndex : 30; |
2765 | |
2766 | /// The kinds of value we can store in InitializerOrBitWidth. |
2767 | /// |
2768 | /// Note that this is compatible with InClassInitStyle except for |
2769 | /// ISK_CapturedVLAType. |
2770 | enum InitStorageKind { |
2771 | /// If the pointer is null, there's nothing special. Otherwise, |
2772 | /// this is a bitfield and the pointer is the Expr* storing the |
2773 | /// bit-width. |
2774 | ISK_NoInit = (unsigned) ICIS_NoInit, |
2775 | |
2776 | /// The pointer is an (optional due to delayed parsing) Expr* |
2777 | /// holding the copy-initializer. |
2778 | ISK_InClassCopyInit = (unsigned) ICIS_CopyInit, |
2779 | |
2780 | /// The pointer is an (optional due to delayed parsing) Expr* |
2781 | /// holding the list-initializer. |
2782 | ISK_InClassListInit = (unsigned) ICIS_ListInit, |
2783 | |
2784 | /// The pointer is a VariableArrayType* that's been captured; |
2785 | /// the enclosing context is a lambda or captured statement. |
2786 | ISK_CapturedVLAType, |
2787 | }; |
2788 | |
2789 | /// If this is a bitfield with a default member initializer, this |
2790 | /// structure is used to represent the two expressions. |
2791 | struct InitAndBitWidth { |
2792 | Expr *Init; |
2793 | Expr *BitWidth; |
2794 | }; |
2795 | |
2796 | /// Storage for either the bit-width, the in-class initializer, or |
2797 | /// both (via InitAndBitWidth), or the captured variable length array bound. |
2798 | /// |
2799 | /// If the storage kind is ISK_InClassCopyInit or |
2800 | /// ISK_InClassListInit, but the initializer is null, then this |
2801 | /// field has an in-class initializer that has not yet been parsed |
2802 | /// and attached. |
2803 | // FIXME: Tail-allocate this to reduce the size of FieldDecl in the |
2804 | // overwhelmingly common case that we have none of these things. |
2805 | llvm::PointerIntPair<void *, 2, InitStorageKind> InitStorage; |
2806 | |
2807 | protected: |
2808 | FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, |
2809 | SourceLocation IdLoc, IdentifierInfo *Id, |
2810 | QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable, |
2811 | InClassInitStyle InitStyle) |
2812 | : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), |
2813 | BitField(false), Mutable(Mutable), CachedFieldIndex(0), |
2814 | InitStorage(nullptr, (InitStorageKind) InitStyle) { |
2815 | if (BW) |
2816 | setBitWidth(BW); |
2817 | } |
2818 | |
2819 | public: |
2820 | friend class ASTDeclReader; |
2821 | friend class ASTDeclWriter; |
2822 | |
2823 | static FieldDecl *Create(const ASTContext &C, DeclContext *DC, |
2824 | SourceLocation StartLoc, SourceLocation IdLoc, |
2825 | IdentifierInfo *Id, QualType T, |
2826 | TypeSourceInfo *TInfo, Expr *BW, bool Mutable, |
2827 | InClassInitStyle InitStyle); |
2828 | |
2829 | static FieldDecl *CreateDeserialized(ASTContext &C, unsigned ID); |
2830 | |
2831 | /// Returns the index of this field within its record, |
2832 | /// as appropriate for passing to ASTRecordLayout::getFieldOffset. |
2833 | unsigned getFieldIndex() const; |
2834 | |
2835 | /// Determines whether this field is mutable (C++ only). |
2836 | bool isMutable() const { return Mutable; } |
2837 | |
2838 | /// Determines whether this field is a bitfield. |
2839 | bool isBitField() const { return BitField; } |
2840 | |
2841 | /// Determines whether this is an unnamed bitfield. |
2842 | bool isUnnamedBitfield() const { return isBitField() && !getDeclName(); } |
2843 | |
2844 | /// Determines whether this field is a |
2845 | /// representative for an anonymous struct or union. Such fields are |
2846 | /// unnamed and are implicitly generated by the implementation to |
2847 | /// store the data for the anonymous union or struct. |
2848 | bool isAnonymousStructOrUnion() const; |
2849 | |
2850 | Expr *getBitWidth() const { |
2851 | if (!BitField) |
2852 | return nullptr; |
2853 | void *Ptr = InitStorage.getPointer(); |
2854 | if (getInClassInitStyle()) |
2855 | return static_cast<InitAndBitWidth*>(Ptr)->BitWidth; |
2856 | return static_cast<Expr*>(Ptr); |
2857 | } |
2858 | |
2859 | unsigned getBitWidthValue(const ASTContext &Ctx) const; |
2860 | |
2861 | /// Set the bit-field width for this member. |
2862 | // Note: used by some clients (i.e., do not remove it). |
2863 | void setBitWidth(Expr *Width) { |
2864 | assert(!hasCapturedVLAType() && !BitField &&((!hasCapturedVLAType() && !BitField && "bit width or captured type already set" ) ? static_cast<void> (0) : __assert_fail ("!hasCapturedVLAType() && !BitField && \"bit width or captured type already set\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 2865, __PRETTY_FUNCTION__)) |
2865 | "bit width or captured type already set")((!hasCapturedVLAType() && !BitField && "bit width or captured type already set" ) ? static_cast<void> (0) : __assert_fail ("!hasCapturedVLAType() && !BitField && \"bit width or captured type already set\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 2865, __PRETTY_FUNCTION__)); |
2866 | assert(Width && "no bit width specified")((Width && "no bit width specified") ? static_cast< void> (0) : __assert_fail ("Width && \"no bit width specified\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 2866, __PRETTY_FUNCTION__)); |
2867 | InitStorage.setPointer( |
2868 | InitStorage.getInt() |
2869 | ? new (getASTContext()) |
2870 | InitAndBitWidth{getInClassInitializer(), Width} |
2871 | : static_cast<void*>(Width)); |
2872 | BitField = true; |
2873 | } |
2874 | |
2875 | /// Remove the bit-field width from this member. |
2876 | // Note: used by some clients (i.e., do not remove it). |
2877 | void removeBitWidth() { |
2878 | assert(isBitField() && "no bitfield width to remove")((isBitField() && "no bitfield width to remove") ? static_cast <void> (0) : __assert_fail ("isBitField() && \"no bitfield width to remove\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 2878, __PRETTY_FUNCTION__)); |
2879 | InitStorage.setPointer(getInClassInitializer()); |
2880 | BitField = false; |
2881 | } |
2882 | |
2883 | /// Is this a zero-length bit-field? Such bit-fields aren't really bit-fields |
2884 | /// at all and instead act as a separator between contiguous runs of other |
2885 | /// bit-fields. |
2886 | bool isZeroLengthBitField(const ASTContext &Ctx) const; |
2887 | |
2888 | /// Determine if this field is a subobject of zero size, that is, either a |
2889 | /// zero-length bit-field or a field of empty class type with the |
2890 | /// [[no_unique_address]] attribute. |
2891 | bool isZeroSize(const ASTContext &Ctx) const; |
2892 | |
2893 | /// Get the kind of (C++11) default member initializer that this field has. |
2894 | InClassInitStyle getInClassInitStyle() const { |
2895 | InitStorageKind storageKind = InitStorage.getInt(); |
2896 | return (storageKind == ISK_CapturedVLAType |
2897 | ? ICIS_NoInit : (InClassInitStyle) storageKind); |
2898 | } |
2899 | |
2900 | /// Determine whether this member has a C++11 default member initializer. |
2901 | bool hasInClassInitializer() const { |
2902 | return getInClassInitStyle() != ICIS_NoInit; |
2903 | } |
2904 | |
2905 | /// Get the C++11 default member initializer for this member, or null if one |
2906 | /// has not been set. If a valid declaration has a default member initializer, |
2907 | /// but this returns null, then we have not parsed and attached it yet. |
2908 | Expr *getInClassInitializer() const { |
2909 | if (!hasInClassInitializer()) |
2910 | return nullptr; |
2911 | void *Ptr = InitStorage.getPointer(); |
2912 | if (BitField) |
2913 | return static_cast<InitAndBitWidth*>(Ptr)->Init; |
2914 | return static_cast<Expr*>(Ptr); |
2915 | } |
2916 | |
2917 | /// Set the C++11 in-class initializer for this member. |
2918 | void setInClassInitializer(Expr *Init) { |
2919 | assert(hasInClassInitializer() && !getInClassInitializer())((hasInClassInitializer() && !getInClassInitializer() ) ? static_cast<void> (0) : __assert_fail ("hasInClassInitializer() && !getInClassInitializer()" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 2919, __PRETTY_FUNCTION__)); |
2920 | if (BitField) |
2921 | static_cast<InitAndBitWidth*>(InitStorage.getPointer())->Init = Init; |
2922 | else |
2923 | InitStorage.setPointer(Init); |
2924 | } |
2925 | |
2926 | /// Remove the C++11 in-class initializer from this member. |
2927 | void removeInClassInitializer() { |
2928 | assert(hasInClassInitializer() && "no initializer to remove")((hasInClassInitializer() && "no initializer to remove" ) ? static_cast<void> (0) : __assert_fail ("hasInClassInitializer() && \"no initializer to remove\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 2928, __PRETTY_FUNCTION__)); |
2929 | InitStorage.setPointerAndInt(getBitWidth(), ISK_NoInit); |
2930 | } |
2931 | |
2932 | /// Determine whether this member captures the variable length array |
2933 | /// type. |
2934 | bool hasCapturedVLAType() const { |
2935 | return InitStorage.getInt() == ISK_CapturedVLAType; |
2936 | } |
2937 | |
2938 | /// Get the captured variable length array type. |
2939 | const VariableArrayType *getCapturedVLAType() const { |
2940 | return hasCapturedVLAType() ? static_cast<const VariableArrayType *>( |
2941 | InitStorage.getPointer()) |
2942 | : nullptr; |
2943 | } |
2944 | |
2945 | /// Set the captured variable length array type for this field. |
2946 | void setCapturedVLAType(const VariableArrayType *VLAType); |
2947 | |
2948 | /// Returns the parent of this field declaration, which |
2949 | /// is the struct in which this field is defined. |
2950 | /// |
2951 | /// Returns null if this is not a normal class/struct field declaration, e.g. |
2952 | /// ObjCAtDefsFieldDecl, ObjCIvarDecl. |
2953 | const RecordDecl *getParent() const { |
2954 | return dyn_cast<RecordDecl>(getDeclContext()); |
2955 | } |
2956 | |
2957 | RecordDecl *getParent() { |
2958 | return dyn_cast<RecordDecl>(getDeclContext()); |
2959 | } |
2960 | |
2961 | SourceRange getSourceRange() const override LLVM_READONLY__attribute__((__pure__)); |
2962 | |
2963 | /// Retrieves the canonical declaration of this field. |
2964 | FieldDecl *getCanonicalDecl() override { return getFirstDecl(); } |
2965 | const FieldDecl *getCanonicalDecl() const { return getFirstDecl(); } |
2966 | |
2967 | // Implement isa/cast/dyncast/etc. |
2968 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
2969 | static bool classofKind(Kind K) { return K >= firstField && K <= lastField; } |
2970 | }; |
2971 | |
2972 | /// An instance of this object exists for each enum constant |
2973 | /// that is defined. For example, in "enum X {a,b}", each of a/b are |
2974 | /// EnumConstantDecl's, X is an instance of EnumDecl, and the type of a/b is a |
2975 | /// TagType for the X EnumDecl. |
2976 | class EnumConstantDecl : public ValueDecl, public Mergeable<EnumConstantDecl> { |
2977 | Stmt *Init; // an integer constant expression |
2978 | llvm::APSInt Val; // The value. |
2979 | |
2980 | protected: |
2981 | EnumConstantDecl(DeclContext *DC, SourceLocation L, |
2982 | IdentifierInfo *Id, QualType T, Expr *E, |
2983 | const llvm::APSInt &V) |
2984 | : ValueDecl(EnumConstant, DC, L, Id, T), Init((Stmt*)E), Val(V) {} |
2985 | |
2986 | public: |
2987 | friend class StmtIteratorBase; |
2988 | |
2989 | static EnumConstantDecl *Create(ASTContext &C, EnumDecl *DC, |
2990 | SourceLocation L, IdentifierInfo *Id, |
2991 | QualType T, Expr *E, |
2992 | const llvm::APSInt &V); |
2993 | static EnumConstantDecl *CreateDeserialized(ASTContext &C, unsigned ID); |
2994 | |
2995 | const Expr *getInitExpr() const { return (const Expr*) Init; } |
2996 | Expr *getInitExpr() { return (Expr*) Init; } |
2997 | const llvm::APSInt &getInitVal() const { return Val; } |
2998 | |
2999 | void setInitExpr(Expr *E) { Init = (Stmt*) E; } |
3000 | void setInitVal(const llvm::APSInt &V) { Val = V; } |
3001 | |
3002 | SourceRange getSourceRange() const override LLVM_READONLY__attribute__((__pure__)); |
3003 | |
3004 | /// Retrieves the canonical declaration of this enumerator. |
3005 | EnumConstantDecl *getCanonicalDecl() override { return getFirstDecl(); } |
3006 | const EnumConstantDecl *getCanonicalDecl() const { return getFirstDecl(); } |
3007 | |
3008 | // Implement isa/cast/dyncast/etc. |
3009 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
3010 | static bool classofKind(Kind K) { return K == EnumConstant; } |
3011 | }; |
3012 | |
3013 | /// Represents a field injected from an anonymous union/struct into the parent |
3014 | /// scope. These are always implicit. |
3015 | class IndirectFieldDecl : public ValueDecl, |
3016 | public Mergeable<IndirectFieldDecl> { |
3017 | NamedDecl **Chaining; |
3018 | unsigned ChainingSize; |
3019 | |
3020 | IndirectFieldDecl(ASTContext &C, DeclContext *DC, SourceLocation L, |
3021 | DeclarationName N, QualType T, |
3022 | MutableArrayRef<NamedDecl *> CH); |
3023 | |
3024 | void anchor() override; |
3025 | |
3026 | public: |
3027 | friend class ASTDeclReader; |
3028 | |
3029 | static IndirectFieldDecl *Create(ASTContext &C, DeclContext *DC, |
3030 | SourceLocation L, IdentifierInfo *Id, |
3031 | QualType T, llvm::MutableArrayRef<NamedDecl *> CH); |
3032 | |
3033 | static IndirectFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID); |
3034 | |
3035 | using chain_iterator = ArrayRef<NamedDecl *>::const_iterator; |
3036 | |
3037 | ArrayRef<NamedDecl *> chain() const { |
3038 | return llvm::makeArrayRef(Chaining, ChainingSize); |
3039 | } |
3040 | chain_iterator chain_begin() const { return chain().begin(); } |
3041 | chain_iterator chain_end() const { return chain().end(); } |
3042 | |
3043 | unsigned getChainingSize() const { return ChainingSize; } |
3044 | |
3045 | FieldDecl *getAnonField() const { |
3046 | assert(chain().size() >= 2)((chain().size() >= 2) ? static_cast<void> (0) : __assert_fail ("chain().size() >= 2", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 3046, __PRETTY_FUNCTION__)); |
3047 | return cast<FieldDecl>(chain().back()); |
3048 | } |
3049 | |
3050 | VarDecl *getVarDecl() const { |
3051 | assert(chain().size() >= 2)((chain().size() >= 2) ? static_cast<void> (0) : __assert_fail ("chain().size() >= 2", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 3051, __PRETTY_FUNCTION__)); |
3052 | return dyn_cast<VarDecl>(chain().front()); |
3053 | } |
3054 | |
3055 | IndirectFieldDecl *getCanonicalDecl() override { return getFirstDecl(); } |
3056 | const IndirectFieldDecl *getCanonicalDecl() const { return getFirstDecl(); } |
3057 | |
3058 | // Implement isa/cast/dyncast/etc. |
3059 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
3060 | static bool classofKind(Kind K) { return K == IndirectField; } |
3061 | }; |
3062 | |
3063 | /// Represents a declaration of a type. |
3064 | class TypeDecl : public NamedDecl { |
3065 | friend class ASTContext; |
3066 | |
3067 | /// This indicates the Type object that represents |
3068 | /// this TypeDecl. It is a cache maintained by |
3069 | /// ASTContext::getTypedefType, ASTContext::getTagDeclType, and |
3070 | /// ASTContext::getTemplateTypeParmType, and TemplateTypeParmDecl. |
3071 | mutable const Type *TypeForDecl = nullptr; |
3072 | |
3073 | /// The start of the source range for this declaration. |
3074 | SourceLocation LocStart; |
3075 | |
3076 | void anchor() override; |
3077 | |
3078 | protected: |
3079 | TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, |
3080 | SourceLocation StartL = SourceLocation()) |
3081 | : NamedDecl(DK, DC, L, Id), LocStart(StartL) {} |
3082 | |
3083 | public: |
3084 | // Low-level accessor. If you just want the type defined by this node, |
3085 | // check out ASTContext::getTypeDeclType or one of |
3086 | // ASTContext::getTypedefType, ASTContext::getRecordType, etc. if you |
3087 | // already know the specific kind of node this is. |
3088 | const Type *getTypeForDecl() const { return TypeForDecl; } |
3089 | void setTypeForDecl(const Type *TD) { TypeForDecl = TD; } |
3090 | |
3091 | SourceLocation getBeginLoc() const LLVM_READONLY__attribute__((__pure__)) { return LocStart; } |
3092 | void setLocStart(SourceLocation L) { LocStart = L; } |
3093 | SourceRange getSourceRange() const override LLVM_READONLY__attribute__((__pure__)) { |
3094 | if (LocStart.isValid()) |
3095 | return SourceRange(LocStart, getLocation()); |
3096 | else |
3097 | return SourceRange(getLocation()); |
3098 | } |
3099 | |
3100 | // Implement isa/cast/dyncast/etc. |
3101 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
3102 | static bool classofKind(Kind K) { return K >= firstType && K <= lastType; } |
3103 | }; |
3104 | |
3105 | /// Base class for declarations which introduce a typedef-name. |
3106 | class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> { |
3107 | struct alignas(8) ModedTInfo { |
3108 | TypeSourceInfo *first; |
3109 | QualType second; |
3110 | }; |
3111 | |
3112 | /// If int part is 0, we have not computed IsTransparentTag. |
3113 | /// Otherwise, IsTransparentTag is (getInt() >> 1). |
3114 | mutable llvm::PointerIntPair< |
3115 | llvm::PointerUnion<TypeSourceInfo *, ModedTInfo *>, 2> |
3116 | MaybeModedTInfo; |
3117 | |
3118 | void anchor() override; |
3119 | |
3120 | protected: |
3121 | TypedefNameDecl(Kind DK, ASTContext &C, DeclContext *DC, |
3122 | SourceLocation StartLoc, SourceLocation IdLoc, |
3123 | IdentifierInfo *Id, TypeSourceInfo *TInfo) |
3124 | : TypeDecl(DK, DC, IdLoc, Id, StartLoc), redeclarable_base(C), |
3125 | MaybeModedTInfo(TInfo, 0) {} |
3126 | |
3127 | using redeclarable_base = Redeclarable<TypedefNameDecl>; |
3128 | |
3129 | TypedefNameDecl *getNextRedeclarationImpl() override { |
3130 | return getNextRedeclaration(); |
3131 | } |
3132 | |
3133 | TypedefNameDecl *getPreviousDeclImpl() override { |
3134 | return getPreviousDecl(); |
3135 | } |
3136 | |
3137 | TypedefNameDecl *getMostRecentDeclImpl() override { |
3138 | return getMostRecentDecl(); |
3139 | } |
3140 | |
3141 | public: |
3142 | using redecl_range = redeclarable_base::redecl_range; |
3143 | using redecl_iterator = redeclarable_base::redecl_iterator; |
3144 | |
3145 | using redeclarable_base::redecls_begin; |
3146 | using redeclarable_base::redecls_end; |
3147 | using redeclarable_base::redecls; |
3148 | using redeclarable_base::getPreviousDecl; |
3149 | using redeclarable_base::getMostRecentDecl; |
3150 | using redeclarable_base::isFirstDecl; |
3151 | |
3152 | bool isModed() const { |
3153 | return MaybeModedTInfo.getPointer().is<ModedTInfo *>(); |
3154 | } |
3155 | |
3156 | TypeSourceInfo *getTypeSourceInfo() const { |
3157 | return isModed() ? MaybeModedTInfo.getPointer().get<ModedTInfo *>()->first |
3158 | : MaybeModedTInfo.getPointer().get<TypeSourceInfo *>(); |
3159 | } |
3160 | |
3161 | QualType getUnderlyingType() const { |
3162 | return isModed() ? MaybeModedTInfo.getPointer().get<ModedTInfo *>()->second |
3163 | : MaybeModedTInfo.getPointer() |
3164 | .get<TypeSourceInfo *>() |
3165 | ->getType(); |
3166 | } |
3167 | |
3168 | void setTypeSourceInfo(TypeSourceInfo *newType) { |
3169 | MaybeModedTInfo.setPointer(newType); |
3170 | } |
3171 | |
3172 | void setModedTypeSourceInfo(TypeSourceInfo *unmodedTSI, QualType modedTy) { |
3173 | MaybeModedTInfo.setPointer(new (getASTContext(), 8) |
3174 | ModedTInfo({unmodedTSI, modedTy})); |
3175 | } |
3176 | |
3177 | /// Retrieves the canonical declaration of this typedef-name. |
3178 | TypedefNameDecl *getCanonicalDecl() override { return getFirstDecl(); } |
3179 | const TypedefNameDecl *getCanonicalDecl() const { return getFirstDecl(); } |
3180 | |
3181 | /// Retrieves the tag declaration for which this is the typedef name for |
3182 | /// linkage purposes, if any. |
3183 | /// |
3184 | /// \param AnyRedecl Look for the tag declaration in any redeclaration of |
3185 | /// this typedef declaration. |
3186 | TagDecl *getAnonDeclWithTypedefName(bool AnyRedecl = false) const; |
3187 | |
3188 | /// Determines if this typedef shares a name and spelling location with its |
3189 | /// underlying tag type, as is the case with the NS_ENUM macro. |
3190 | bool isTransparentTag() const { |
3191 | if (MaybeModedTInfo.getInt()) |
3192 | return MaybeModedTInfo.getInt() & 0x2; |
3193 | return isTransparentTagSlow(); |
3194 | } |
3195 | |
3196 | // Implement isa/cast/dyncast/etc. |
3197 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
3198 | static bool classofKind(Kind K) { |
3199 | return K >= firstTypedefName && K <= lastTypedefName; |
3200 | } |
3201 | |
3202 | private: |
3203 | bool isTransparentTagSlow() const; |
3204 | }; |
3205 | |
3206 | /// Represents the declaration of a typedef-name via the 'typedef' |
3207 | /// type specifier. |
3208 | class TypedefDecl : public TypedefNameDecl { |
3209 | TypedefDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, |
3210 | SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo) |
3211 | : TypedefNameDecl(Typedef, C, DC, StartLoc, IdLoc, Id, TInfo) {} |
3212 | |
3213 | public: |
3214 | static TypedefDecl *Create(ASTContext &C, DeclContext *DC, |
3215 | SourceLocation StartLoc, SourceLocation IdLoc, |
3216 | IdentifierInfo *Id, TypeSourceInfo *TInfo); |
3217 | static TypedefDecl *CreateDeserialized(ASTContext &C, unsigned ID); |
3218 | |
3219 | SourceRange getSourceRange() const override LLVM_READONLY__attribute__((__pure__)); |
3220 | |
3221 | // Implement isa/cast/dyncast/etc. |
3222 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
3223 | static bool classofKind(Kind K) { return K == Typedef; } |
3224 | }; |
3225 | |
3226 | /// Represents the declaration of a typedef-name via a C++11 |
3227 | /// alias-declaration. |
3228 | class TypeAliasDecl : public TypedefNameDecl { |
3229 | /// The template for which this is the pattern, if any. |
3230 | TypeAliasTemplateDecl *Template; |
3231 | |
3232 | TypeAliasDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, |
3233 | SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo) |
3234 | : TypedefNameDecl(TypeAlias, C, DC, StartLoc, IdLoc, Id, TInfo), |
3235 | Template(nullptr) {} |
3236 | |
3237 | public: |
3238 | static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC, |
3239 | SourceLocation StartLoc, SourceLocation IdLoc, |
3240 | IdentifierInfo *Id, TypeSourceInfo *TInfo); |
3241 | static TypeAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID); |
3242 | |
3243 | SourceRange getSourceRange() const override LLVM_READONLY__attribute__((__pure__)); |
3244 | |
3245 | TypeAliasTemplateDecl *getDescribedAliasTemplate() const { return Template; } |
3246 | void setDescribedAliasTemplate(TypeAliasTemplateDecl *TAT) { Template = TAT; } |
3247 | |
3248 | // Implement isa/cast/dyncast/etc. |
3249 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
3250 | static bool classofKind(Kind K) { return K == TypeAlias; } |
3251 | }; |
3252 | |
3253 | /// Represents the declaration of a struct/union/class/enum. |
3254 | class TagDecl : public TypeDecl, |
3255 | public DeclContext, |
3256 | public Redeclarable<TagDecl> { |
3257 | // This class stores some data in DeclContext::TagDeclBits |
3258 | // to save some space. Use the provided accessors to access it. |
3259 | public: |
3260 | // This is really ugly. |
3261 | using TagKind = TagTypeKind; |
3262 | |
3263 | private: |
3264 | SourceRange BraceRange; |
3265 | |
3266 | // A struct representing syntactic qualifier info, |
3267 | // to be used for the (uncommon) case of out-of-line declarations. |
3268 | using ExtInfo = QualifierInfo; |
3269 | |
3270 | /// If the (out-of-line) tag declaration name |
3271 | /// is qualified, it points to the qualifier info (nns and range); |
3272 | /// otherwise, if the tag declaration is anonymous and it is part of |
3273 | /// a typedef or alias, it points to the TypedefNameDecl (used for mangling); |
3274 | /// otherwise, if the tag declaration is anonymous and it is used as a |
3275 | /// declaration specifier for variables, it points to the first VarDecl (used |
3276 | /// for mangling); |
3277 | /// otherwise, it is a null (TypedefNameDecl) pointer. |
3278 | llvm::PointerUnion<TypedefNameDecl *, ExtInfo *> TypedefNameDeclOrQualifier; |
3279 | |
3280 | bool hasExtInfo() const { return TypedefNameDeclOrQualifier.is<ExtInfo *>(); } |
3281 | ExtInfo *getExtInfo() { return TypedefNameDeclOrQualifier.get<ExtInfo *>(); } |
3282 | const ExtInfo *getExtInfo() const { |
3283 | return TypedefNameDeclOrQualifier.get<ExtInfo *>(); |
3284 | } |
3285 | |
3286 | protected: |
3287 | TagDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC, |
3288 | SourceLocation L, IdentifierInfo *Id, TagDecl *PrevDecl, |
3289 | SourceLocation StartL); |
3290 | |
3291 | using redeclarable_base = Redeclarable<TagDecl>; |
3292 | |
3293 | TagDecl *getNextRedeclarationImpl() override { |
3294 | return getNextRedeclaration(); |
3295 | } |
3296 | |
3297 | TagDecl *getPreviousDeclImpl() override { |
3298 | return getPreviousDecl(); |
3299 | } |
3300 | |
3301 | TagDecl *getMostRecentDeclImpl() override { |
3302 | return getMostRecentDecl(); |
3303 | } |
3304 | |
3305 | /// Completes the definition of this tag declaration. |
3306 | /// |
3307 | /// This is a helper function for derived classes. |
3308 | void completeDefinition(); |
3309 | |
3310 | /// True if this decl is currently being defined. |
3311 | void setBeingDefined(bool V = true) { TagDeclBits.IsBeingDefined = V; } |
3312 | |
3313 | /// Indicates whether it is possible for declarations of this kind |
3314 | /// to have an out-of-date definition. |
3315 | /// |
3316 | /// This option is only enabled when modules are enabled. |
3317 | void setMayHaveOutOfDateDef(bool V = true) { |
3318 | TagDeclBits.MayHaveOutOfDateDef = V; |
3319 | } |
3320 | |
3321 | public: |
3322 | friend class ASTDeclReader; |
3323 | friend class ASTDeclWriter; |
3324 | |
3325 | using redecl_range = redeclarable_base::redecl_range; |
3326 | using redecl_iterator = redeclarable_base::redecl_iterator; |
3327 | |
3328 | using redeclarable_base::redecls_begin; |
3329 | using redeclarable_base::redecls_end; |
3330 | using redeclarable_base::redecls; |
3331 | using redeclarable_base::getPreviousDecl; |
3332 | using redeclarable_base::getMostRecentDecl; |
3333 | using redeclarable_base::isFirstDecl; |
3334 | |
3335 | SourceRange getBraceRange() const { return BraceRange; } |
3336 | void setBraceRange(SourceRange R) { BraceRange = R; } |
3337 | |
3338 | /// Return SourceLocation representing start of source |
3339 | /// range ignoring outer template declarations. |
3340 | SourceLocation getInnerLocStart() const { return getBeginLoc(); } |
3341 | |
3342 | /// Return SourceLocation representing start of source |
3343 | /// range taking into account any outer template declarations. |
3344 | SourceLocation getOuterLocStart() const; |
3345 | SourceRange getSourceRange() const override LLVM_READONLY__attribute__((__pure__)); |
3346 | |
3347 | TagDecl *getCanonicalDecl() override; |
3348 | const TagDecl *getCanonicalDecl() const { |
3349 | return const_cast<TagDecl*>(this)->getCanonicalDecl(); |
3350 | } |
3351 | |
3352 | /// Return true if this declaration is a completion definition of the type. |
3353 | /// Provided for consistency. |
3354 | bool isThisDeclarationADefinition() const { |
3355 | return isCompleteDefinition(); |
3356 | } |
3357 | |
3358 | /// Return true if this decl has its body fully specified. |
3359 | bool isCompleteDefinition() const { return TagDeclBits.IsCompleteDefinition; } |
3360 | |
3361 | /// True if this decl has its body fully specified. |
3362 | void setCompleteDefinition(bool V = true) { |
3363 | TagDeclBits.IsCompleteDefinition = V; |
3364 | } |
3365 | |
3366 | /// Return true if this complete decl is |
3367 | /// required to be complete for some existing use. |
3368 | bool isCompleteDefinitionRequired() const { |
3369 | return TagDeclBits.IsCompleteDefinitionRequired; |
3370 | } |
3371 | |
3372 | /// True if this complete decl is |
3373 | /// required to be complete for some existing use. |
3374 | void setCompleteDefinitionRequired(bool V = true) { |
3375 | TagDeclBits.IsCompleteDefinitionRequired = V; |
3376 | } |
3377 | |
3378 | /// Return true if this decl is currently being defined. |
3379 | bool isBeingDefined() const { return TagDeclBits.IsBeingDefined; } |
3380 | |
3381 | /// True if this tag declaration is "embedded" (i.e., defined or declared |
3382 | /// for the very first time) in the syntax of a declarator. |
3383 | bool isEmbeddedInDeclarator() const { |
3384 | return TagDeclBits.IsEmbeddedInDeclarator; |
3385 | } |
3386 | |
3387 | /// True if this tag declaration is "embedded" (i.e., defined or declared |
3388 | /// for the very first time) in the syntax of a declarator. |
3389 | void setEmbeddedInDeclarator(bool isInDeclarator) { |
3390 | TagDeclBits.IsEmbeddedInDeclarator = isInDeclarator; |
3391 | } |
3392 | |
3393 | /// True if this tag is free standing, e.g. "struct foo;". |
3394 | bool isFreeStanding() const { return TagDeclBits.IsFreeStanding; } |
3395 | |
3396 | /// True if this tag is free standing, e.g. "struct foo;". |
3397 | void setFreeStanding(bool isFreeStanding = true) { |
3398 | TagDeclBits.IsFreeStanding = isFreeStanding; |
3399 | } |
3400 | |
3401 | /// Indicates whether it is possible for declarations of this kind |
3402 | /// to have an out-of-date definition. |
3403 | /// |
3404 | /// This option is only enabled when modules are enabled. |
3405 | bool mayHaveOutOfDateDef() const { return TagDeclBits.MayHaveOutOfDateDef; } |
3406 | |
3407 | /// Whether this declaration declares a type that is |
3408 | /// dependent, i.e., a type that somehow depends on template |
3409 | /// parameters. |
3410 | bool isDependentType() const { return isDependentContext(); } |
3411 | |
3412 | /// Starts the definition of this tag declaration. |
3413 | /// |
3414 | /// This method should be invoked at the beginning of the definition |
3415 | /// of this tag declaration. It will set the tag type into a state |
3416 | /// where it is in the process of being defined. |
3417 | void startDefinition(); |
3418 | |
3419 | /// Returns the TagDecl that actually defines this |
3420 | /// struct/union/class/enum. When determining whether or not a |
3421 | /// struct/union/class/enum has a definition, one should use this |
3422 | /// method as opposed to 'isDefinition'. 'isDefinition' indicates |
3423 | /// whether or not a specific TagDecl is defining declaration, not |
3424 | /// whether or not the struct/union/class/enum type is defined. |
3425 | /// This method returns NULL if there is no TagDecl that defines |
3426 | /// the struct/union/class/enum. |
3427 | TagDecl *getDefinition() const; |
3428 | |
3429 | StringRef getKindName() const { |
3430 | return TypeWithKeyword::getTagTypeKindName(getTagKind()); |
3431 | } |
3432 | |
3433 | TagKind getTagKind() const { |
3434 | return static_cast<TagKind>(TagDeclBits.TagDeclKind); |
3435 | } |
3436 | |
3437 | void setTagKind(TagKind TK) { TagDeclBits.TagDeclKind = TK; } |
3438 | |
3439 | bool isStruct() const { return getTagKind() == TTK_Struct; } |
3440 | bool isInterface() const { return getTagKind() == TTK_Interface; } |
3441 | bool isClass() const { return getTagKind() == TTK_Class; } |
3442 | bool isUnion() const { return getTagKind() == TTK_Union; } |
3443 | bool isEnum() const { return getTagKind() == TTK_Enum; } |
3444 | |
3445 | /// Is this tag type named, either directly or via being defined in |
3446 | /// a typedef of this type? |
3447 | /// |
3448 | /// C++11 [basic.link]p8: |
3449 | /// A type is said to have linkage if and only if: |
3450 | /// - it is a class or enumeration type that is named (or has a |
3451 | /// name for linkage purposes) and the name has linkage; ... |
3452 | /// C++11 [dcl.typedef]p9: |
3453 | /// If the typedef declaration defines an unnamed class (or enum), |
3454 | /// the first typedef-name declared by the declaration to be that |
3455 | /// class type (or enum type) is used to denote the class type (or |
3456 | /// enum type) for linkage purposes only. |
3457 | /// |
3458 | /// C does not have an analogous rule, but the same concept is |
3459 | /// nonetheless useful in some places. |
3460 | bool hasNameForLinkage() const { |
3461 | return (getDeclName() || getTypedefNameForAnonDecl()); |
3462 | } |
3463 | |
3464 | TypedefNameDecl *getTypedefNameForAnonDecl() const { |
3465 | return hasExtInfo() ? nullptr |
3466 | : TypedefNameDeclOrQualifier.get<TypedefNameDecl *>(); |
3467 | } |
3468 | |
3469 | void setTypedefNameForAnonDecl(TypedefNameDecl *TDD); |
3470 | |
3471 | /// Retrieve the nested-name-specifier that qualifies the name of this |
3472 | /// declaration, if it was present in the source. |
3473 | NestedNameSpecifier *getQualifier() const { |
3474 | return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier() |
3475 | : nullptr; |
3476 | } |
3477 | |
3478 | /// Retrieve the nested-name-specifier (with source-location |
3479 | /// information) that qualifies the name of this declaration, if it was |
3480 | /// present in the source. |
3481 | NestedNameSpecifierLoc getQualifierLoc() const { |
3482 | return hasExtInfo() ? getExtInfo()->QualifierLoc |
3483 | : NestedNameSpecifierLoc(); |
3484 | } |
3485 | |
3486 | void setQualifierInfo(NestedNameSpecifierLoc QualifierLoc); |
3487 | |
3488 | unsigned getNumTemplateParameterLists() const { |
3489 | return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0; |
3490 | } |
3491 | |
3492 | TemplateParameterList *getTemplateParameterList(unsigned i) const { |
3493 | assert(i < getNumTemplateParameterLists())((i < getNumTemplateParameterLists()) ? static_cast<void > (0) : __assert_fail ("i < getNumTemplateParameterLists()" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 3493, __PRETTY_FUNCTION__)); |
3494 | return getExtInfo()->TemplParamLists[i]; |
3495 | } |
3496 | |
3497 | void setTemplateParameterListsInfo(ASTContext &Context, |
3498 | ArrayRef<TemplateParameterList *> TPLists); |
3499 | |
3500 | // Implement isa/cast/dyncast/etc. |
3501 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
3502 | static bool classofKind(Kind K) { return K >= firstTag && K <= lastTag; } |
3503 | |
3504 | static DeclContext *castToDeclContext(const TagDecl *D) { |
3505 | return static_cast<DeclContext *>(const_cast<TagDecl*>(D)); |
3506 | } |
3507 | |
3508 | static TagDecl *castFromDeclContext(const DeclContext *DC) { |
3509 | return static_cast<TagDecl *>(const_cast<DeclContext*>(DC)); |
3510 | } |
3511 | }; |
3512 | |
3513 | /// Represents an enum. In C++11, enums can be forward-declared |
3514 | /// with a fixed underlying type, and in C we allow them to be forward-declared |
3515 | /// with no underlying type as an extension. |
3516 | class EnumDecl : public TagDecl { |
3517 | // This class stores some data in DeclContext::EnumDeclBits |
3518 | // to save some space. Use the provided accessors to access it. |
3519 | |
3520 | /// This represent the integer type that the enum corresponds |
3521 | /// to for code generation purposes. Note that the enumerator constants may |
3522 | /// have a different type than this does. |
3523 | /// |
3524 | /// If the underlying integer type was explicitly stated in the source |
3525 | /// code, this is a TypeSourceInfo* for that type. Otherwise this type |
3526 | /// was automatically deduced somehow, and this is a Type*. |
3527 | /// |
3528 | /// Normally if IsFixed(), this would contain a TypeSourceInfo*, but in |
3529 | /// some cases it won't. |
3530 | /// |
3531 | /// The underlying type of an enumeration never has any qualifiers, so |
3532 | /// we can get away with just storing a raw Type*, and thus save an |
3533 | /// extra pointer when TypeSourceInfo is needed. |
3534 | llvm::PointerUnion<const Type *, TypeSourceInfo *> IntegerType; |
3535 | |
3536 | /// The integer type that values of this type should |
3537 | /// promote to. In C, enumerators are generally of an integer type |
3538 | /// directly, but gcc-style large enumerators (and all enumerators |
3539 | /// in C++) are of the enum type instead. |
3540 | QualType PromotionType; |
3541 | |
3542 | /// If this enumeration is an instantiation of a member enumeration |
3543 | /// of a class template specialization, this is the member specialization |
3544 | /// information. |
3545 | MemberSpecializationInfo *SpecializationInfo = nullptr; |
3546 | |
3547 | /// Store the ODRHash after first calculation. |
3548 | /// The corresponding flag HasODRHash is in EnumDeclBits |
3549 | /// and can be accessed with the provided accessors. |
3550 | unsigned ODRHash; |
3551 | |
3552 | EnumDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, |
3553 | SourceLocation IdLoc, IdentifierInfo *Id, EnumDecl *PrevDecl, |
3554 | bool Scoped, bool ScopedUsingClassTag, bool Fixed); |
3555 | |
3556 | void anchor() override; |
3557 | |
3558 | void setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED, |
3559 | TemplateSpecializationKind TSK); |
3560 | |
3561 | /// Sets the width in bits required to store all the |
3562 | /// non-negative enumerators of this enum. |
3563 | void setNumPositiveBits(unsigned Num) { |
3564 | EnumDeclBits.NumPositiveBits = Num; |
3565 | assert(EnumDeclBits.NumPositiveBits == Num && "can't store this bitcount")((EnumDeclBits.NumPositiveBits == Num && "can't store this bitcount" ) ? static_cast<void> (0) : __assert_fail ("EnumDeclBits.NumPositiveBits == Num && \"can't store this bitcount\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 3565, __PRETTY_FUNCTION__)); |
3566 | } |
3567 | |
3568 | /// Returns the width in bits required to store all the |
3569 | /// negative enumerators of this enum. (see getNumNegativeBits) |
3570 | void setNumNegativeBits(unsigned Num) { EnumDeclBits.NumNegativeBits = Num; } |
3571 | |
3572 | public: |
3573 | /// True if this tag declaration is a scoped enumeration. Only |
3574 | /// possible in C++11 mode. |
3575 | void setScoped(bool Scoped = true) { EnumDeclBits.IsScoped = Scoped; } |
3576 | |
3577 | /// If this tag declaration is a scoped enum, |
3578 | /// then this is true if the scoped enum was declared using the class |
3579 | /// tag, false if it was declared with the struct tag. No meaning is |
3580 | /// associated if this tag declaration is not a scoped enum. |
3581 | void setScopedUsingClassTag(bool ScopedUCT = true) { |
3582 | EnumDeclBits.IsScopedUsingClassTag = ScopedUCT; |
3583 | } |
3584 | |
3585 | /// True if this is an Objective-C, C++11, or |
3586 | /// Microsoft-style enumeration with a fixed underlying type. |
3587 | void setFixed(bool Fixed = true) { EnumDeclBits.IsFixed = Fixed; } |
3588 | |
3589 | private: |
3590 | /// True if a valid hash is stored in ODRHash. |
3591 | bool hasODRHash() const { return EnumDeclBits.HasODRHash; } |
3592 | void setHasODRHash(bool Hash = true) { EnumDeclBits.HasODRHash = Hash; } |
3593 | |
3594 | public: |
3595 | friend class ASTDeclReader; |
3596 | |
3597 | EnumDecl *getCanonicalDecl() override { |
3598 | return cast<EnumDecl>(TagDecl::getCanonicalDecl()); |
3599 | } |
3600 | const EnumDecl *getCanonicalDecl() const { |
3601 | return const_cast<EnumDecl*>(this)->getCanonicalDecl(); |
3602 | } |
3603 | |
3604 | EnumDecl *getPreviousDecl() { |
3605 | return cast_or_null<EnumDecl>( |
3606 | static_cast<TagDecl *>(this)->getPreviousDecl()); |
3607 | } |
3608 | const EnumDecl *getPreviousDecl() const { |
3609 | return const_cast<EnumDecl*>(this)->getPreviousDecl(); |
3610 | } |
3611 | |
3612 | EnumDecl *getMostRecentDecl() { |
3613 | return cast<EnumDecl>(static_cast<TagDecl *>(this)->getMostRecentDecl()); |
3614 | } |
3615 | const EnumDecl *getMostRecentDecl() const { |
3616 | return const_cast<EnumDecl*>(this)->getMostRecentDecl(); |
3617 | } |
3618 | |
3619 | EnumDecl *getDefinition() const { |
3620 | return cast_or_null<EnumDecl>(TagDecl::getDefinition()); |
3621 | } |
3622 | |
3623 | static EnumDecl *Create(ASTContext &C, DeclContext *DC, |
3624 | SourceLocation StartLoc, SourceLocation IdLoc, |
3625 | IdentifierInfo *Id, EnumDecl *PrevDecl, |
3626 | bool IsScoped, bool IsScopedUsingClassTag, |
3627 | bool IsFixed); |
3628 | static EnumDecl *CreateDeserialized(ASTContext &C, unsigned ID); |
3629 | |
3630 | /// When created, the EnumDecl corresponds to a |
3631 | /// forward-declared enum. This method is used to mark the |
3632 | /// declaration as being defined; its enumerators have already been |
3633 | /// added (via DeclContext::addDecl). NewType is the new underlying |
3634 | /// type of the enumeration type. |
3635 | void completeDefinition(QualType NewType, |
3636 | QualType PromotionType, |
3637 | unsigned NumPositiveBits, |
3638 | unsigned NumNegativeBits); |
3639 | |
3640 | // Iterates through the enumerators of this enumeration. |
3641 | using enumerator_iterator = specific_decl_iterator<EnumConstantDecl>; |
3642 | using enumerator_range = |
3643 | llvm::iterator_range<specific_decl_iterator<EnumConstantDecl>>; |
3644 | |
3645 | enumerator_range enumerators() const { |
3646 | return enumerator_range(enumerator_begin(), enumerator_end()); |
3647 | } |
3648 | |
3649 | enumerator_iterator enumerator_begin() const { |
3650 | const EnumDecl *E = getDefinition(); |
3651 | if (!E) |
3652 | E = this; |
3653 | return enumerator_iterator(E->decls_begin()); |
3654 | } |
3655 | |
3656 | enumerator_iterator enumerator_end() const { |
3657 | const EnumDecl *E = getDefinition(); |
3658 | if (!E) |
3659 | E = this; |
3660 | return enumerator_iterator(E->decls_end()); |
3661 | } |
3662 | |
3663 | /// Return the integer type that enumerators should promote to. |
3664 | QualType getPromotionType() const { return PromotionType; } |
3665 | |
3666 | /// Set the promotion type. |
3667 | void setPromotionType(QualType T) { PromotionType = T; } |
3668 | |
3669 | /// Return the integer type this enum decl corresponds to. |
3670 | /// This returns a null QualType for an enum forward definition with no fixed |
3671 | /// underlying type. |
3672 | QualType getIntegerType() const { |
3673 | if (!IntegerType) |
3674 | return QualType(); |
3675 | if (const Type *T = IntegerType.dyn_cast<const Type*>()) |
3676 | return QualType(T, 0); |
3677 | return IntegerType.get<TypeSourceInfo*>()->getType().getUnqualifiedType(); |
3678 | } |
3679 | |
3680 | /// Set the underlying integer type. |
3681 | void setIntegerType(QualType T) { IntegerType = T.getTypePtrOrNull(); } |
3682 | |
3683 | /// Set the underlying integer type source info. |
3684 | void setIntegerTypeSourceInfo(TypeSourceInfo *TInfo) { IntegerType = TInfo; } |
3685 | |
3686 | /// Return the type source info for the underlying integer type, |
3687 | /// if no type source info exists, return 0. |
3688 | TypeSourceInfo *getIntegerTypeSourceInfo() const { |
3689 | return IntegerType.dyn_cast<TypeSourceInfo*>(); |
3690 | } |
3691 | |
3692 | /// Retrieve the source range that covers the underlying type if |
3693 | /// specified. |
3694 | SourceRange getIntegerTypeRange() const LLVM_READONLY__attribute__((__pure__)); |
3695 | |
3696 | /// Returns the width in bits required to store all the |
3697 | /// non-negative enumerators of this enum. |
3698 | unsigned getNumPositiveBits() const { return EnumDeclBits.NumPositiveBits; } |
3699 | |
3700 | /// Returns the width in bits required to store all the |
3701 | /// negative enumerators of this enum. These widths include |
3702 | /// the rightmost leading 1; that is: |
3703 | /// |
3704 | /// MOST NEGATIVE ENUMERATOR PATTERN NUM NEGATIVE BITS |
3705 | /// ------------------------ ------- ----------------- |
3706 | /// -1 1111111 1 |
3707 | /// -10 1110110 5 |
3708 | /// -101 1001011 8 |
3709 | unsigned getNumNegativeBits() const { return EnumDeclBits.NumNegativeBits; } |
3710 | |
3711 | /// Returns true if this is a C++11 scoped enumeration. |
3712 | bool isScoped() const { return EnumDeclBits.IsScoped; } |
3713 | |
3714 | /// Returns true if this is a C++11 scoped enumeration. |
3715 | bool isScopedUsingClassTag() const { |
3716 | return EnumDeclBits.IsScopedUsingClassTag; |
3717 | } |
3718 | |
3719 | /// Returns true if this is an Objective-C, C++11, or |
3720 | /// Microsoft-style enumeration with a fixed underlying type. |
3721 | bool isFixed() const { return EnumDeclBits.IsFixed; } |
3722 | |
3723 | unsigned getODRHash(); |
3724 | |
3725 | /// Returns true if this can be considered a complete type. |
3726 | bool isComplete() const { |
3727 | // IntegerType is set for fixed type enums and non-fixed but implicitly |
3728 | // int-sized Microsoft enums. |
3729 | return isCompleteDefinition() || IntegerType; |
3730 | } |
3731 | |
3732 | /// Returns true if this enum is either annotated with |
3733 | /// enum_extensibility(closed) or isn't annotated with enum_extensibility. |
3734 | bool isClosed() const; |
3735 | |
3736 | /// Returns true if this enum is annotated with flag_enum and isn't annotated |
3737 | /// with enum_extensibility(open). |
3738 | bool isClosedFlag() const; |
3739 | |
3740 | /// Returns true if this enum is annotated with neither flag_enum nor |
3741 | /// enum_extensibility(open). |
3742 | bool isClosedNonFlag() const; |
3743 | |
3744 | /// Retrieve the enum definition from which this enumeration could |
3745 | /// be instantiated, if it is an instantiation (rather than a non-template). |
3746 | EnumDecl *getTemplateInstantiationPattern() const; |
3747 | |
3748 | /// Returns the enumeration (declared within the template) |
3749 | /// from which this enumeration type was instantiated, or NULL if |
3750 | /// this enumeration was not instantiated from any template. |
3751 | EnumDecl *getInstantiatedFromMemberEnum() const; |
3752 | |
3753 | /// If this enumeration is a member of a specialization of a |
3754 | /// templated class, determine what kind of template specialization |
3755 | /// or instantiation this is. |
3756 | TemplateSpecializationKind getTemplateSpecializationKind() const; |
3757 | |
3758 | /// For an enumeration member that was instantiated from a member |
3759 | /// enumeration of a templated class, set the template specialiation kind. |
3760 | void setTemplateSpecializationKind(TemplateSpecializationKind TSK, |
3761 | SourceLocation PointOfInstantiation = SourceLocation()); |
3762 | |
3763 | /// If this enumeration is an instantiation of a member enumeration of |
3764 | /// a class template specialization, retrieves the member specialization |
3765 | /// information. |
3766 | MemberSpecializationInfo *getMemberSpecializationInfo() const { |
3767 | return SpecializationInfo; |
3768 | } |
3769 | |
3770 | /// Specify that this enumeration is an instantiation of the |
3771 | /// member enumeration ED. |
3772 | void setInstantiationOfMemberEnum(EnumDecl *ED, |
3773 | TemplateSpecializationKind TSK) { |
3774 | setInstantiationOfMemberEnum(getASTContext(), ED, TSK); |
3775 | } |
3776 | |
3777 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
3778 | static bool classofKind(Kind K) { return K == Enum; } |
3779 | }; |
3780 | |
3781 | /// Represents a struct/union/class. For example: |
3782 | /// struct X; // Forward declaration, no "body". |
3783 | /// union Y { int A, B; }; // Has body with members A and B (FieldDecls). |
3784 | /// This decl will be marked invalid if *any* members are invalid. |
3785 | class RecordDecl : public TagDecl { |
3786 | // This class stores some data in DeclContext::RecordDeclBits |
3787 | // to save some space. Use the provided accessors to access it. |
3788 | public: |
3789 | friend class DeclContext; |
3790 | /// Enum that represents the different ways arguments are passed to and |
3791 | /// returned from function calls. This takes into account the target-specific |
3792 | /// and version-specific rules along with the rules determined by the |
3793 | /// language. |
3794 | enum ArgPassingKind : unsigned { |
3795 | /// The argument of this type can be passed directly in registers. |
3796 | APK_CanPassInRegs, |
3797 | |
3798 | /// The argument of this type cannot be passed directly in registers. |
3799 | /// Records containing this type as a subobject are not forced to be passed |
3800 | /// indirectly. This value is used only in C++. This value is required by |
3801 | /// C++ because, in uncommon situations, it is possible for a class to have |
3802 | /// only trivial copy/move constructors even when one of its subobjects has |
3803 | /// a non-trivial copy/move constructor (if e.g. the corresponding copy/move |
3804 | /// constructor in the derived class is deleted). |
3805 | APK_CannotPassInRegs, |
3806 | |
3807 | /// The argument of this type cannot be passed directly in registers. |
3808 | /// Records containing this type as a subobject are forced to be passed |
3809 | /// indirectly. |
3810 | APK_CanNeverPassInRegs |
3811 | }; |
3812 | |
3813 | protected: |
3814 | RecordDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC, |
3815 | SourceLocation StartLoc, SourceLocation IdLoc, |
3816 | IdentifierInfo *Id, RecordDecl *PrevDecl); |
3817 | |
3818 | public: |
3819 | static RecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC, |
3820 | SourceLocation StartLoc, SourceLocation IdLoc, |
3821 | IdentifierInfo *Id, RecordDecl* PrevDecl = nullptr); |
3822 | static RecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID); |
3823 | |
3824 | RecordDecl *getPreviousDecl() { |
3825 | return cast_or_null<RecordDecl>( |
3826 | static_cast<TagDecl *>(this)->getPreviousDecl()); |
3827 | } |
3828 | const RecordDecl *getPreviousDecl() const { |
3829 | return const_cast<RecordDecl*>(this)->getPreviousDecl(); |
3830 | } |
3831 | |
3832 | RecordDecl *getMostRecentDecl() { |
3833 | return cast<RecordDecl>(static_cast<TagDecl *>(this)->getMostRecentDecl()); |
3834 | } |
3835 | const RecordDecl *getMostRecentDecl() const { |
3836 | return const_cast<RecordDecl*>(this)->getMostRecentDecl(); |
3837 | } |
3838 | |
3839 | bool hasFlexibleArrayMember() const { |
3840 | return RecordDeclBits.HasFlexibleArrayMember; |
3841 | } |
3842 | |
3843 | void setHasFlexibleArrayMember(bool V) { |
3844 | RecordDeclBits.HasFlexibleArrayMember = V; |
3845 | } |
3846 | |
3847 | /// Whether this is an anonymous struct or union. To be an anonymous |
3848 | /// struct or union, it must have been declared without a name and |
3849 | /// there must be no objects of this type declared, e.g., |
3850 | /// @code |
3851 | /// union { int i; float f; }; |
3852 | /// @endcode |
3853 | /// is an anonymous union but neither of the following are: |
3854 | /// @code |
3855 | /// union X { int i; float f; }; |
3856 | /// union { int i; float f; } obj; |
3857 | /// @endcode |
3858 | bool isAnonymousStructOrUnion() const { |
3859 | return RecordDeclBits.AnonymousStructOrUnion; |
3860 | } |
3861 | |
3862 | void setAnonymousStructOrUnion(bool Anon) { |
3863 | RecordDeclBits.AnonymousStructOrUnion = Anon; |
3864 | } |
3865 | |
3866 | bool hasObjectMember() const { return RecordDeclBits.HasObjectMember; } |
3867 | void setHasObjectMember(bool val) { RecordDeclBits.HasObjectMember = val; } |
3868 | |
3869 | bool hasVolatileMember() const { return RecordDeclBits.HasVolatileMember; } |
3870 | |
3871 | void setHasVolatileMember(bool val) { |
3872 | RecordDeclBits.HasVolatileMember = val; |
3873 | } |
3874 | |
3875 | bool hasLoadedFieldsFromExternalStorage() const { |
3876 | return RecordDeclBits.LoadedFieldsFromExternalStorage; |
3877 | } |
3878 | |
3879 | void setHasLoadedFieldsFromExternalStorage(bool val) const { |
3880 | RecordDeclBits.LoadedFieldsFromExternalStorage = val; |
3881 | } |
3882 | |
3883 | /// Functions to query basic properties of non-trivial C structs. |
3884 | bool isNonTrivialToPrimitiveDefaultInitialize() const { |
3885 | return RecordDeclBits.NonTrivialToPrimitiveDefaultInitialize; |
3886 | } |
3887 | |
3888 | void setNonTrivialToPrimitiveDefaultInitialize(bool V) { |
3889 | RecordDeclBits.NonTrivialToPrimitiveDefaultInitialize = V; |
3890 | } |
3891 | |
3892 | bool isNonTrivialToPrimitiveCopy() const { |
3893 | return RecordDeclBits.NonTrivialToPrimitiveCopy; |
3894 | } |
3895 | |
3896 | void setNonTrivialToPrimitiveCopy(bool V) { |
3897 | RecordDeclBits.NonTrivialToPrimitiveCopy = V; |
3898 | } |
3899 | |
3900 | bool isNonTrivialToPrimitiveDestroy() const { |
3901 | return RecordDeclBits.NonTrivialToPrimitiveDestroy; |
3902 | } |
3903 | |
3904 | void setNonTrivialToPrimitiveDestroy(bool V) { |
3905 | RecordDeclBits.NonTrivialToPrimitiveDestroy = V; |
3906 | } |
3907 | |
3908 | bool hasNonTrivialToPrimitiveDefaultInitializeCUnion() const { |
3909 | return RecordDeclBits.HasNonTrivialToPrimitiveDefaultInitializeCUnion; |
3910 | } |
3911 | |
3912 | void setHasNonTrivialToPrimitiveDefaultInitializeCUnion(bool V) { |
3913 | RecordDeclBits.HasNonTrivialToPrimitiveDefaultInitializeCUnion = V; |
3914 | } |
3915 | |
3916 | bool hasNonTrivialToPrimitiveDestructCUnion() const { |
3917 | return RecordDeclBits.HasNonTrivialToPrimitiveDestructCUnion; |
3918 | } |
3919 | |
3920 | void setHasNonTrivialToPrimitiveDestructCUnion(bool V) { |
3921 | RecordDeclBits.HasNonTrivialToPrimitiveDestructCUnion = V; |
3922 | } |
3923 | |
3924 | bool hasNonTrivialToPrimitiveCopyCUnion() const { |
3925 | return RecordDeclBits.HasNonTrivialToPrimitiveCopyCUnion; |
3926 | } |
3927 | |
3928 | void setHasNonTrivialToPrimitiveCopyCUnion(bool V) { |
3929 | RecordDeclBits.HasNonTrivialToPrimitiveCopyCUnion = V; |
3930 | } |
3931 | |
3932 | /// Determine whether this class can be passed in registers. In C++ mode, |
3933 | /// it must have at least one trivial, non-deleted copy or move constructor. |
3934 | /// FIXME: This should be set as part of completeDefinition. |
3935 | bool canPassInRegisters() const { |
3936 | return getArgPassingRestrictions() == APK_CanPassInRegs; |
3937 | } |
3938 | |
3939 | ArgPassingKind getArgPassingRestrictions() const { |
3940 | return static_cast<ArgPassingKind>(RecordDeclBits.ArgPassingRestrictions); |
3941 | } |
3942 | |
3943 | void setArgPassingRestrictions(ArgPassingKind Kind) { |
3944 | RecordDeclBits.ArgPassingRestrictions = Kind; |
3945 | } |
3946 | |
3947 | bool isParamDestroyedInCallee() const { |
3948 | return RecordDeclBits.ParamDestroyedInCallee; |
3949 | } |
3950 | |
3951 | void setParamDestroyedInCallee(bool V) { |
3952 | RecordDeclBits.ParamDestroyedInCallee = V; |
3953 | } |
3954 | |
3955 | /// Determines whether this declaration represents the |
3956 | /// injected class name. |
3957 | /// |
3958 | /// The injected class name in C++ is the name of the class that |
3959 | /// appears inside the class itself. For example: |
3960 | /// |
3961 | /// \code |
3962 | /// struct C { |
3963 | /// // C is implicitly declared here as a synonym for the class name. |
3964 | /// }; |
3965 | /// |
3966 | /// C::C c; // same as "C c;" |
3967 | /// \endcode |
3968 | bool isInjectedClassName() const; |
3969 | |
3970 | /// Determine whether this record is a class describing a lambda |
3971 | /// function object. |
3972 | bool isLambda() const; |
3973 | |
3974 | /// Determine whether this record is a record for captured variables in |
3975 | /// CapturedStmt construct. |
3976 | bool isCapturedRecord() const; |
3977 | |
3978 | /// Mark the record as a record for captured variables in CapturedStmt |
3979 | /// construct. |
3980 | void setCapturedRecord(); |
3981 | |
3982 | /// Returns the RecordDecl that actually defines |
3983 | /// this struct/union/class. When determining whether or not a |
3984 | /// struct/union/class is completely defined, one should use this |
3985 | /// method as opposed to 'isCompleteDefinition'. |
3986 | /// 'isCompleteDefinition' indicates whether or not a specific |
3987 | /// RecordDecl is a completed definition, not whether or not the |
3988 | /// record type is defined. This method returns NULL if there is |
3989 | /// no RecordDecl that defines the struct/union/tag. |
3990 | RecordDecl *getDefinition() const { |
3991 | return cast_or_null<RecordDecl>(TagDecl::getDefinition()); |
3992 | } |
3993 | |
3994 | /// Returns whether this record is a union, or contains (at any nesting level) |
3995 | /// a union member. This is used by CMSE to warn about possible information |
3996 | /// leaks. |
3997 | bool isOrContainsUnion() const; |
3998 | |
3999 | // Iterator access to field members. The field iterator only visits |
4000 | // the non-static data members of this class, ignoring any static |
4001 | // data members, functions, constructors, destructors, etc. |
4002 | using field_iterator = specific_decl_iterator<FieldDecl>; |
4003 | using field_range = llvm::iterator_range<specific_decl_iterator<FieldDecl>>; |
4004 | |
4005 | field_range fields() const { return field_range(field_begin(), field_end()); } |
4006 | field_iterator field_begin() const; |
4007 | |
4008 | field_iterator field_end() const { |
4009 | return field_iterator(decl_iterator()); |
4010 | } |
4011 | |
4012 | // Whether there are any fields (non-static data members) in this record. |
4013 | bool field_empty() const { |
4014 | return field_begin() == field_end(); |
4015 | } |
4016 | |
4017 | /// Note that the definition of this type is now complete. |
4018 | virtual void completeDefinition(); |
4019 | |
4020 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
4021 | static bool classofKind(Kind K) { |
4022 | return K >= firstRecord && K <= lastRecord; |
4023 | } |
4024 | |
4025 | /// Get whether or not this is an ms_struct which can |
4026 | /// be turned on with an attribute, pragma, or -mms-bitfields |
4027 | /// commandline option. |
4028 | bool isMsStruct(const ASTContext &C) const; |
4029 | |
4030 | /// Whether we are allowed to insert extra padding between fields. |
4031 | /// These padding are added to help AddressSanitizer detect |
4032 | /// intra-object-overflow bugs. |
4033 | bool mayInsertExtraPadding(bool EmitRemark = false) const; |
4034 | |
4035 | /// Finds the first data member which has a name. |
4036 | /// nullptr is returned if no named data member exists. |
4037 | const FieldDecl *findFirstNamedDataMember() const; |
4038 | |
4039 | private: |
4040 | /// Deserialize just the fields. |
4041 | void LoadFieldsFromExternalStorage() const; |
4042 | }; |
4043 | |
4044 | class FileScopeAsmDecl : public Decl { |
4045 | StringLiteral *AsmString; |
4046 | SourceLocation RParenLoc; |
4047 | |
4048 | FileScopeAsmDecl(DeclContext *DC, StringLiteral *asmstring, |
4049 | SourceLocation StartL, SourceLocation EndL) |
4050 | : Decl(FileScopeAsm, DC, StartL), AsmString(asmstring), RParenLoc(EndL) {} |
4051 | |
4052 | virtual void anchor(); |
4053 | |
4054 | public: |
4055 | static FileScopeAsmDecl *Create(ASTContext &C, DeclContext *DC, |
4056 | StringLiteral *Str, SourceLocation AsmLoc, |
4057 | SourceLocation RParenLoc); |
4058 | |
4059 | static FileScopeAsmDecl *CreateDeserialized(ASTContext &C, unsigned ID); |
4060 | |
4061 | SourceLocation getAsmLoc() const { return getLocation(); } |
4062 | SourceLocation getRParenLoc() const { return RParenLoc; } |
4063 | void setRParenLoc(SourceLocation L) { RParenLoc = L; } |
4064 | SourceRange getSourceRange() const override LLVM_READONLY__attribute__((__pure__)) { |
4065 | return SourceRange(getAsmLoc(), getRParenLoc()); |
4066 | } |
4067 | |
4068 | const StringLiteral *getAsmString() const { return AsmString; } |
4069 | StringLiteral *getAsmString() { return AsmString; } |
4070 | void setAsmString(StringLiteral *Asm) { AsmString = Asm; } |
4071 | |
4072 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
4073 | static bool classofKind(Kind K) { return K == FileScopeAsm; } |
4074 | }; |
4075 | |
4076 | /// Represents a block literal declaration, which is like an |
4077 | /// unnamed FunctionDecl. For example: |
4078 | /// ^{ statement-body } or ^(int arg1, float arg2){ statement-body } |
4079 | class BlockDecl : public Decl, public DeclContext { |
4080 | // This class stores some data in DeclContext::BlockDeclBits |
4081 | // to save some space. Use the provided accessors to access it. |
4082 | public: |
4083 | /// A class which contains all the information about a particular |
4084 | /// captured value. |
4085 | class Capture { |
4086 | enum { |
4087 | flag_isByRef = 0x1, |
4088 | flag_isNested = 0x2 |
4089 | }; |
4090 | |
4091 | /// The variable being captured. |
4092 | llvm::PointerIntPair<VarDecl*, 2> VariableAndFlags; |
4093 | |
4094 | /// The copy expression, expressed in terms of a DeclRef (or |
4095 | /// BlockDeclRef) to the captured variable. Only required if the |
4096 | /// variable has a C++ class type. |
4097 | Expr *CopyExpr; |
4098 | |
4099 | public: |
4100 | Capture(VarDecl *variable, bool byRef, bool nested, Expr *copy) |
4101 | : VariableAndFlags(variable, |
4102 | (byRef ? flag_isByRef : 0) | (nested ? flag_isNested : 0)), |
4103 | CopyExpr(copy) {} |
4104 | |
4105 | /// The variable being captured. |
4106 | VarDecl *getVariable() const { return VariableAndFlags.getPointer(); } |
4107 | |
4108 | /// Whether this is a "by ref" capture, i.e. a capture of a __block |
4109 | /// variable. |
4110 | bool isByRef() const { return VariableAndFlags.getInt() & flag_isByRef; } |
4111 | |
4112 | bool isEscapingByref() const { |
4113 | return getVariable()->isEscapingByref(); |
4114 | } |
4115 | |
4116 | bool isNonEscapingByref() const { |
4117 | return getVariable()->isNonEscapingByref(); |
4118 | } |
4119 | |
4120 | /// Whether this is a nested capture, i.e. the variable captured |
4121 | /// is not from outside the immediately enclosing function/block. |
4122 | bool isNested() const { return VariableAndFlags.getInt() & flag_isNested; } |
4123 | |
4124 | bool hasCopyExpr() const { return CopyExpr != nullptr; } |
4125 | Expr *getCopyExpr() const { return CopyExpr; } |
4126 | void setCopyExpr(Expr *e) { CopyExpr = e; } |
4127 | }; |
4128 | |
4129 | private: |
4130 | /// A new[]'d array of pointers to ParmVarDecls for the formal |
4131 | /// parameters of this function. This is null if a prototype or if there are |
4132 | /// no formals. |
4133 | ParmVarDecl **ParamInfo = nullptr; |
4134 | unsigned NumParams = 0; |
4135 | |
4136 | Stmt *Body = nullptr; |
4137 | TypeSourceInfo *SignatureAsWritten = nullptr; |
4138 | |
4139 | const Capture *Captures = nullptr; |
4140 | unsigned NumCaptures = 0; |
4141 | |
4142 | unsigned ManglingNumber = 0; |
4143 | Decl *ManglingContextDecl = nullptr; |
4144 | |
4145 | protected: |
4146 | BlockDecl(DeclContext *DC, SourceLocation CaretLoc); |
4147 | |
4148 | public: |
4149 | static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L); |
4150 | static BlockDecl *CreateDeserialized(ASTContext &C, unsigned ID); |
4151 | |
4152 | SourceLocation getCaretLocation() const { return getLocation(); } |
4153 | |
4154 | bool isVariadic() const { return BlockDeclBits.IsVariadic; } |
4155 | void setIsVariadic(bool value) { BlockDeclBits.IsVariadic = value; } |
4156 | |
4157 | CompoundStmt *getCompoundBody() const { return (CompoundStmt*) Body; } |
4158 | Stmt *getBody() const override { return (Stmt*) Body; } |
4159 | void setBody(CompoundStmt *B) { Body = (Stmt*) B; } |
4160 | |
4161 | void setSignatureAsWritten(TypeSourceInfo *Sig) { SignatureAsWritten = Sig; } |
4162 | TypeSourceInfo *getSignatureAsWritten() const { return SignatureAsWritten; } |
4163 | |
4164 | // ArrayRef access to formal parameters. |
4165 | ArrayRef<ParmVarDecl *> parameters() const { |
4166 | return {ParamInfo, getNumParams()}; |
4167 | } |
4168 | MutableArrayRef<ParmVarDecl *> parameters() { |
4169 | return {ParamInfo, getNumParams()}; |
4170 | } |
4171 | |
4172 | // Iterator access to formal parameters. |
4173 | using param_iterator = MutableArrayRef<ParmVarDecl *>::iterator; |
4174 | using param_const_iterator = ArrayRef<ParmVarDecl *>::const_iterator; |
4175 | |
4176 | bool param_empty() const { return parameters().empty(); } |
4177 | param_iterator param_begin() { return parameters().begin(); } |
4178 | param_iterator param_end() { return parameters().end(); } |
4179 | param_const_iterator param_begin() const { return parameters().begin(); } |
4180 | param_const_iterator param_end() const { return parameters().end(); } |
4181 | size_t param_size() const { return parameters().size(); } |
4182 | |
4183 | unsigned getNumParams() const { return NumParams; } |
4184 | |
4185 | const ParmVarDecl *getParamDecl(unsigned i) const { |
4186 | assert(i < getNumParams() && "Illegal param #")((i < getNumParams() && "Illegal param #") ? static_cast <void> (0) : __assert_fail ("i < getNumParams() && \"Illegal param #\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 4186, __PRETTY_FUNCTION__)); |
4187 | return ParamInfo[i]; |
4188 | } |
4189 | ParmVarDecl *getParamDecl(unsigned i) { |
4190 | assert(i < getNumParams() && "Illegal param #")((i < getNumParams() && "Illegal param #") ? static_cast <void> (0) : __assert_fail ("i < getNumParams() && \"Illegal param #\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 4190, __PRETTY_FUNCTION__)); |
4191 | return ParamInfo[i]; |
4192 | } |
4193 | |
4194 | void setParams(ArrayRef<ParmVarDecl *> NewParamInfo); |
4195 | |
4196 | /// True if this block (or its nested blocks) captures |
4197 | /// anything of local storage from its enclosing scopes. |
4198 | bool hasCaptures() const { return NumCaptures || capturesCXXThis(); } |
4199 | |
4200 | /// Returns the number of captured variables. |
4201 | /// Does not include an entry for 'this'. |
4202 | unsigned getNumCaptures() const { return NumCaptures; } |
4203 | |
4204 | using capture_const_iterator = ArrayRef<Capture>::const_iterator; |
4205 | |
4206 | ArrayRef<Capture> captures() const { return {Captures, NumCaptures}; } |
4207 | |
4208 | capture_const_iterator capture_begin() const { return captures().begin(); } |
4209 | capture_const_iterator capture_end() const { return captures().end(); } |
4210 | |
4211 | bool capturesCXXThis() const { return BlockDeclBits.CapturesCXXThis; } |
4212 | void setCapturesCXXThis(bool B = true) { BlockDeclBits.CapturesCXXThis = B; } |
4213 | |
4214 | bool blockMissingReturnType() const { |
4215 | return BlockDeclBits.BlockMissingReturnType; |
4216 | } |
4217 | |
4218 | void setBlockMissingReturnType(bool val = true) { |
4219 | BlockDeclBits.BlockMissingReturnType = val; |
4220 | } |
4221 | |
4222 | bool isConversionFromLambda() const { |
4223 | return BlockDeclBits.IsConversionFromLambda; |
4224 | } |
4225 | |
4226 | void setIsConversionFromLambda(bool val = true) { |
4227 | BlockDeclBits.IsConversionFromLambda = val; |
4228 | } |
4229 | |
4230 | bool doesNotEscape() const { return BlockDeclBits.DoesNotEscape; } |
4231 | void setDoesNotEscape(bool B = true) { BlockDeclBits.DoesNotEscape = B; } |
4232 | |
4233 | bool canAvoidCopyToHeap() const { |
4234 | return BlockDeclBits.CanAvoidCopyToHeap; |
4235 | } |
4236 | void setCanAvoidCopyToHeap(bool B = true) { |
4237 | BlockDeclBits.CanAvoidCopyToHeap = B; |
4238 | } |
4239 | |
4240 | bool capturesVariable(const VarDecl *var) const; |
4241 | |
4242 | void setCaptures(ASTContext &Context, ArrayRef<Capture> Captures, |
4243 | bool CapturesCXXThis); |
4244 | |
4245 | unsigned getBlockManglingNumber() const { return ManglingNumber; } |
4246 | |
4247 | Decl *getBlockManglingContextDecl() const { return ManglingContextDecl; } |
4248 | |
4249 | void setBlockMangling(unsigned Number, Decl *Ctx) { |
4250 | ManglingNumber = Number; |
4251 | ManglingContextDecl = Ctx; |
4252 | } |
4253 | |
4254 | SourceRange getSourceRange() const override LLVM_READONLY__attribute__((__pure__)); |
4255 | |
4256 | // Implement isa/cast/dyncast/etc. |
4257 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
4258 | static bool classofKind(Kind K) { return K == Block; } |
4259 | static DeclContext *castToDeclContext(const BlockDecl *D) { |
4260 | return static_cast<DeclContext *>(const_cast<BlockDecl*>(D)); |
4261 | } |
4262 | static BlockDecl *castFromDeclContext(const DeclContext *DC) { |
4263 | return static_cast<BlockDecl *>(const_cast<DeclContext*>(DC)); |
4264 | } |
4265 | }; |
4266 | |
4267 | /// Represents the body of a CapturedStmt, and serves as its DeclContext. |
4268 | class CapturedDecl final |
4269 | : public Decl, |
4270 | public DeclContext, |
4271 | private llvm::TrailingObjects<CapturedDecl, ImplicitParamDecl *> { |
4272 | protected: |
4273 | size_t numTrailingObjects(OverloadToken<ImplicitParamDecl>) { |
4274 | return NumParams; |
4275 | } |
4276 | |
4277 | private: |
4278 | /// The number of parameters to the outlined function. |
4279 | unsigned NumParams; |
4280 | |
4281 | /// The position of context parameter in list of parameters. |
4282 | unsigned ContextParam; |
4283 | |
4284 | /// The body of the outlined function. |
4285 | llvm::PointerIntPair<Stmt *, 1, bool> BodyAndNothrow; |
4286 | |
4287 | explicit CapturedDecl(DeclContext *DC, unsigned NumParams); |
4288 | |
4289 | ImplicitParamDecl *const *getParams() const { |
4290 | return getTrailingObjects<ImplicitParamDecl *>(); |
4291 | } |
4292 | |
4293 | ImplicitParamDecl **getParams() { |
4294 | return getTrailingObjects<ImplicitParamDecl *>(); |
4295 | } |
4296 | |
4297 | public: |
4298 | friend class ASTDeclReader; |
4299 | friend class ASTDeclWriter; |
4300 | friend TrailingObjects; |
4301 | |
4302 | static CapturedDecl *Create(ASTContext &C, DeclContext *DC, |
4303 | unsigned NumParams); |
4304 | static CapturedDecl *CreateDeserialized(ASTContext &C, unsigned ID, |
4305 | unsigned NumParams); |
4306 | |
4307 | Stmt *getBody() const override; |
4308 | void setBody(Stmt *B); |
4309 | |
4310 | bool isNothrow() const; |
4311 | void setNothrow(bool Nothrow = true); |
4312 | |
4313 | unsigned getNumParams() const { return NumParams; } |
4314 | |
4315 | ImplicitParamDecl *getParam(unsigned i) const { |
4316 | assert(i < NumParams)((i < NumParams) ? static_cast<void> (0) : __assert_fail ("i < NumParams", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 4316, __PRETTY_FUNCTION__)); |
4317 | return getParams()[i]; |
4318 | } |
4319 | void setParam(unsigned i, ImplicitParamDecl *P) { |
4320 | assert(i < NumParams)((i < NumParams) ? static_cast<void> (0) : __assert_fail ("i < NumParams", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 4320, __PRETTY_FUNCTION__)); |
4321 | getParams()[i] = P; |
4322 | } |
4323 | |
4324 | // ArrayRef interface to parameters. |
4325 | ArrayRef<ImplicitParamDecl *> parameters() const { |
4326 | return {getParams(), getNumParams()}; |
4327 | } |
4328 | MutableArrayRef<ImplicitParamDecl *> parameters() { |
4329 | return {getParams(), getNumParams()}; |
4330 | } |
4331 | |
4332 | /// Retrieve the parameter containing captured variables. |
4333 | ImplicitParamDecl *getContextParam() const { |
4334 | assert(ContextParam < NumParams)((ContextParam < NumParams) ? static_cast<void> (0) : __assert_fail ("ContextParam < NumParams", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 4334, __PRETTY_FUNCTION__)); |
4335 | return getParam(ContextParam); |
4336 | } |
4337 | void setContextParam(unsigned i, ImplicitParamDecl *P) { |
4338 | assert(i < NumParams)((i < NumParams) ? static_cast<void> (0) : __assert_fail ("i < NumParams", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 4338, __PRETTY_FUNCTION__)); |
4339 | ContextParam = i; |
4340 | setParam(i, P); |
4341 | } |
4342 | unsigned getContextParamPosition() const { return ContextParam; } |
4343 | |
4344 | using param_iterator = ImplicitParamDecl *const *; |
4345 | using param_range = llvm::iterator_range<param_iterator>; |
4346 | |
4347 | /// Retrieve an iterator pointing to the first parameter decl. |
4348 | param_iterator param_begin() const { return getParams(); } |
4349 | /// Retrieve an iterator one past the last parameter decl. |
4350 | param_iterator param_end() const { return getParams() + NumParams; } |
4351 | |
4352 | // Implement isa/cast/dyncast/etc. |
4353 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
4354 | static bool classofKind(Kind K) { return K == Captured; } |
4355 | static DeclContext *castToDeclContext(const CapturedDecl *D) { |
4356 | return static_cast<DeclContext *>(const_cast<CapturedDecl *>(D)); |
4357 | } |
4358 | static CapturedDecl *castFromDeclContext(const DeclContext *DC) { |
4359 | return static_cast<CapturedDecl *>(const_cast<DeclContext *>(DC)); |
4360 | } |
4361 | }; |
4362 | |
4363 | /// Describes a module import declaration, which makes the contents |
4364 | /// of the named module visible in the current translation unit. |
4365 | /// |
4366 | /// An import declaration imports the named module (or submodule). For example: |
4367 | /// \code |
4368 | /// @import std.vector; |
4369 | /// \endcode |
4370 | /// |
4371 | /// Import declarations can also be implicitly generated from |
4372 | /// \#include/\#import directives. |
4373 | class ImportDecl final : public Decl, |
4374 | llvm::TrailingObjects<ImportDecl, SourceLocation> { |
4375 | friend class ASTContext; |
4376 | friend class ASTDeclReader; |
4377 | friend class ASTReader; |
4378 | friend TrailingObjects; |
4379 | |
4380 | /// The imported module. |
4381 | Module *ImportedModule = nullptr; |
4382 | |
4383 | /// The next import in the list of imports local to the translation |
4384 | /// unit being parsed (not loaded from an AST file). |
4385 | /// |
4386 | /// Includes a bit that indicates whether we have source-location information |
4387 | /// for each identifier in the module name. |
4388 | /// |
4389 | /// When the bit is false, we only have a single source location for the |
4390 | /// end of the import declaration. |
4391 | llvm::PointerIntPair<ImportDecl *, 1, bool> NextLocalImportAndComplete; |
4392 | |
4393 | ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported, |
4394 | ArrayRef<SourceLocation> IdentifierLocs); |
4395 | |
4396 | ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported, |
4397 | SourceLocation EndLoc); |
4398 | |
4399 | ImportDecl(EmptyShell Empty) : Decl(Import, Empty) {} |
4400 | |
4401 | bool isImportComplete() const { return NextLocalImportAndComplete.getInt(); } |
4402 | |
4403 | void setImportComplete(bool C) { NextLocalImportAndComplete.setInt(C); } |
4404 | |
4405 | /// The next import in the list of imports local to the translation |
4406 | /// unit being parsed (not loaded from an AST file). |
4407 | ImportDecl *getNextLocalImport() const { |
4408 | return NextLocalImportAndComplete.getPointer(); |
4409 | } |
4410 | |
4411 | void setNextLocalImport(ImportDecl *Import) { |
4412 | NextLocalImportAndComplete.setPointer(Import); |
4413 | } |
4414 | |
4415 | public: |
4416 | /// Create a new module import declaration. |
4417 | static ImportDecl *Create(ASTContext &C, DeclContext *DC, |
4418 | SourceLocation StartLoc, Module *Imported, |
4419 | ArrayRef<SourceLocation> IdentifierLocs); |
4420 | |
4421 | /// Create a new module import declaration for an implicitly-generated |
4422 | /// import. |
4423 | static ImportDecl *CreateImplicit(ASTContext &C, DeclContext *DC, |
4424 | SourceLocation StartLoc, Module *Imported, |
4425 | SourceLocation EndLoc); |
4426 | |
4427 | /// Create a new, deserialized module import declaration. |
4428 | static ImportDecl *CreateDeserialized(ASTContext &C, unsigned ID, |
4429 | unsigned NumLocations); |
4430 | |
4431 | /// Retrieve the module that was imported by the import declaration. |
4432 | Module *getImportedModule() const { return ImportedModule; } |
4433 | |
4434 | /// Retrieves the locations of each of the identifiers that make up |
4435 | /// the complete module name in the import declaration. |
4436 | /// |
4437 | /// This will return an empty array if the locations of the individual |
4438 | /// identifiers aren't available. |
4439 | ArrayRef<SourceLocation> getIdentifierLocs() const; |
4440 | |
4441 | SourceRange getSourceRange() const override LLVM_READONLY__attribute__((__pure__)); |
4442 | |
4443 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
4444 | static bool classofKind(Kind K) { return K == Import; } |
4445 | }; |
4446 | |
4447 | /// Represents a C++ Modules TS module export declaration. |
4448 | /// |
4449 | /// For example: |
4450 | /// \code |
4451 | /// export void foo(); |
4452 | /// \endcode |
4453 | class ExportDecl final : public Decl, public DeclContext { |
4454 | virtual void anchor(); |
4455 | |
4456 | private: |
4457 | friend class ASTDeclReader; |
4458 | |
4459 | /// The source location for the right brace (if valid). |
4460 | SourceLocation RBraceLoc; |
4461 | |
4462 | ExportDecl(DeclContext *DC, SourceLocation ExportLoc) |
4463 | : Decl(Export, DC, ExportLoc), DeclContext(Export), |
4464 | RBraceLoc(SourceLocation()) {} |
4465 | |
4466 | public: |
4467 | static ExportDecl *Create(ASTContext &C, DeclContext *DC, |
4468 | SourceLocation ExportLoc); |
4469 | static ExportDecl *CreateDeserialized(ASTContext &C, unsigned ID); |
4470 | |
4471 | SourceLocation getExportLoc() const { return getLocation(); } |
4472 | SourceLocation getRBraceLoc() const { return RBraceLoc; } |
4473 | void setRBraceLoc(SourceLocation L) { RBraceLoc = L; } |
4474 | |
4475 | bool hasBraces() const { return RBraceLoc.isValid(); } |
4476 | |
4477 | SourceLocation getEndLoc() const LLVM_READONLY__attribute__((__pure__)) { |
4478 | if (hasBraces()) |
4479 | return RBraceLoc; |
4480 | // No braces: get the end location of the (only) declaration in context |
4481 | // (if present). |
4482 | return decls_empty() ? getLocation() : decls_begin()->getEndLoc(); |
4483 | } |
4484 | |
4485 | SourceRange getSourceRange() const override LLVM_READONLY__attribute__((__pure__)) { |
4486 | return SourceRange(getLocation(), getEndLoc()); |
4487 | } |
4488 | |
4489 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
4490 | static bool classofKind(Kind K) { return K == Export; } |
4491 | static DeclContext *castToDeclContext(const ExportDecl *D) { |
4492 | return static_cast<DeclContext *>(const_cast<ExportDecl*>(D)); |
4493 | } |
4494 | static ExportDecl *castFromDeclContext(const DeclContext *DC) { |
4495 | return static_cast<ExportDecl *>(const_cast<DeclContext*>(DC)); |
4496 | } |
4497 | }; |
4498 | |
4499 | /// Represents an empty-declaration. |
4500 | class EmptyDecl : public Decl { |
4501 | EmptyDecl(DeclContext *DC, SourceLocation L) : Decl(Empty, DC, L) {} |
4502 | |
4503 | virtual void anchor(); |
4504 | |
4505 | public: |
4506 | static EmptyDecl *Create(ASTContext &C, DeclContext *DC, |
4507 | SourceLocation L); |
4508 | static EmptyDecl *CreateDeserialized(ASTContext &C, unsigned ID); |
4509 | |
4510 | static bool classof(const Decl *D) { return classofKind(D->getKind()); } |
4511 | static bool classofKind(Kind K) { return K == Empty; } |
4512 | }; |
4513 | |
4514 | /// Insertion operator for diagnostics. This allows sending NamedDecl's |
4515 | /// into a diagnostic with <<. |
4516 | inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, |
4517 | const NamedDecl* ND) { |
4518 | DB.AddTaggedVal(reinterpret_cast<intptr_t>(ND), |
4519 | DiagnosticsEngine::ak_nameddecl); |
4520 | return DB; |
4521 | } |
4522 | inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, |
4523 | const NamedDecl* ND) { |
4524 | PD.AddTaggedVal(reinterpret_cast<intptr_t>(ND), |
4525 | DiagnosticsEngine::ak_nameddecl); |
4526 | return PD; |
4527 | } |
4528 | |
4529 | template<typename decl_type> |
4530 | void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) { |
4531 | // Note: This routine is implemented here because we need both NamedDecl |
4532 | // and Redeclarable to be defined. |
4533 | assert(RedeclLink.isFirst() &&((RedeclLink.isFirst() && "setPreviousDecl on a decl already in a redeclaration chain" ) ? static_cast<void> (0) : __assert_fail ("RedeclLink.isFirst() && \"setPreviousDecl on a decl already in a redeclaration chain\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 4534, __PRETTY_FUNCTION__)) |
4534 | "setPreviousDecl on a decl already in a redeclaration chain")((RedeclLink.isFirst() && "setPreviousDecl on a decl already in a redeclaration chain" ) ? static_cast<void> (0) : __assert_fail ("RedeclLink.isFirst() && \"setPreviousDecl on a decl already in a redeclaration chain\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 4534, __PRETTY_FUNCTION__)); |
4535 | |
4536 | if (PrevDecl) { |
4537 | // Point to previous. Make sure that this is actually the most recent |
4538 | // redeclaration, or we can build invalid chains. If the most recent |
4539 | // redeclaration is invalid, it won't be PrevDecl, but we want it anyway. |
4540 | First = PrevDecl->getFirstDecl(); |
4541 | assert(First->RedeclLink.isFirst() && "Expected first")((First->RedeclLink.isFirst() && "Expected first") ? static_cast<void> (0) : __assert_fail ("First->RedeclLink.isFirst() && \"Expected first\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 4541, __PRETTY_FUNCTION__)); |
4542 | decl_type *MostRecent = First->getNextRedeclaration(); |
4543 | RedeclLink = PreviousDeclLink(cast<decl_type>(MostRecent)); |
4544 | |
4545 | // If the declaration was previously visible, a redeclaration of it remains |
4546 | // visible even if it wouldn't be visible by itself. |
4547 | static_cast<decl_type*>(this)->IdentifierNamespace |= |
4548 | MostRecent->getIdentifierNamespace() & |
4549 | (Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Type); |
4550 | } else { |
4551 | // Make this first. |
4552 | First = static_cast<decl_type*>(this); |
4553 | } |
4554 | |
4555 | // First one will point to this one as latest. |
4556 | First->RedeclLink.setLatest(static_cast<decl_type*>(this)); |
4557 | |
4558 | assert(!isa<NamedDecl>(static_cast<decl_type*>(this)) ||((!isa<NamedDecl>(static_cast<decl_type*>(this)) || cast<NamedDecl>(static_cast<decl_type*>(this))-> isLinkageValid()) ? static_cast<void> (0) : __assert_fail ("!isa<NamedDecl>(static_cast<decl_type*>(this)) || cast<NamedDecl>(static_cast<decl_type*>(this))->isLinkageValid()" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 4559, __PRETTY_FUNCTION__)) |
4559 | cast<NamedDecl>(static_cast<decl_type*>(this))->isLinkageValid())((!isa<NamedDecl>(static_cast<decl_type*>(this)) || cast<NamedDecl>(static_cast<decl_type*>(this))-> isLinkageValid()) ? static_cast<void> (0) : __assert_fail ("!isa<NamedDecl>(static_cast<decl_type*>(this)) || cast<NamedDecl>(static_cast<decl_type*>(this))->isLinkageValid()" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/AST/Decl.h" , 4559, __PRETTY_FUNCTION__)); |
4560 | } |
4561 | |
4562 | // Inline function definitions. |
4563 | |
4564 | /// Check if the given decl is complete. |
4565 | /// |
4566 | /// We use this function to break a cycle between the inline definitions in |
4567 | /// Type.h and Decl.h. |
4568 | inline bool IsEnumDeclComplete(EnumDecl *ED) { |
4569 | return ED->isComplete(); |
4570 | } |
4571 | |
4572 | /// Check if the given decl is scoped. |
4573 | /// |
4574 | /// We use this function to break a cycle between the inline definitions in |
4575 | /// Type.h and Decl.h. |
4576 | inline bool IsEnumDeclScoped(EnumDecl *ED) { |
4577 | return ED->isScoped(); |
4578 | } |
4579 | |
4580 | /// OpenMP variants are mangled early based on their OpenMP context selector. |
4581 | /// The new name looks likes this: |
4582 | /// <name> + OpenMPVariantManglingSeparatorStr + <mangled OpenMP context> |
4583 | static constexpr StringRef getOpenMPVariantManglingSeparatorStr() { |
4584 | return "$ompvariant"; |
4585 | } |
4586 | |
4587 | } // namespace clang |
4588 | |
4589 | #endif // LLVM_CLANG_AST_DECL_H |
1 | //===--- Sema.h - Semantic Analysis & AST Building --------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file defines the Sema class, which performs semantic analysis and |
10 | // builds ASTs. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_CLANG_SEMA_SEMA_H |
15 | #define LLVM_CLANG_SEMA_SEMA_H |
16 | |
17 | #include "clang/AST/ASTConcept.h" |
18 | #include "clang/AST/ASTFwd.h" |
19 | #include "clang/AST/Attr.h" |
20 | #include "clang/AST/Availability.h" |
21 | #include "clang/AST/ComparisonCategories.h" |
22 | #include "clang/AST/DeclTemplate.h" |
23 | #include "clang/AST/DeclarationName.h" |
24 | #include "clang/AST/Expr.h" |
25 | #include "clang/AST/ExprCXX.h" |
26 | #include "clang/AST/ExprConcepts.h" |
27 | #include "clang/AST/ExprObjC.h" |
28 | #include "clang/AST/ExprOpenMP.h" |
29 | #include "clang/AST/ExternalASTSource.h" |
30 | #include "clang/AST/LocInfoType.h" |
31 | #include "clang/AST/MangleNumberingContext.h" |
32 | #include "clang/AST/NSAPI.h" |
33 | #include "clang/AST/PrettyPrinter.h" |
34 | #include "clang/AST/StmtCXX.h" |
35 | #include "clang/AST/TypeLoc.h" |
36 | #include "clang/AST/TypeOrdering.h" |
37 | #include "clang/Basic/BitmaskEnum.h" |
38 | #include "clang/Basic/ExpressionTraits.h" |
39 | #include "clang/Basic/Module.h" |
40 | #include "clang/Basic/OpenCLOptions.h" |
41 | #include "clang/Basic/OpenMPKinds.h" |
42 | #include "clang/Basic/PragmaKinds.h" |
43 | #include "clang/Basic/Specifiers.h" |
44 | #include "clang/Basic/TemplateKinds.h" |
45 | #include "clang/Basic/TypeTraits.h" |
46 | #include "clang/Sema/AnalysisBasedWarnings.h" |
47 | #include "clang/Sema/CleanupInfo.h" |
48 | #include "clang/Sema/DeclSpec.h" |
49 | #include "clang/Sema/ExternalSemaSource.h" |
50 | #include "clang/Sema/IdentifierResolver.h" |
51 | #include "clang/Sema/ObjCMethodList.h" |
52 | #include "clang/Sema/Ownership.h" |
53 | #include "clang/Sema/Scope.h" |
54 | #include "clang/Sema/SemaConcept.h" |
55 | #include "clang/Sema/TypoCorrection.h" |
56 | #include "clang/Sema/Weak.h" |
57 | #include "llvm/ADT/ArrayRef.h" |
58 | #include "llvm/ADT/Optional.h" |
59 | #include "llvm/ADT/SetVector.h" |
60 | #include "llvm/ADT/SmallBitVector.h" |
61 | #include "llvm/ADT/SmallSet.h" |
62 | #include "llvm/ADT/SmallPtrSet.h" |
63 | #include "llvm/ADT/SmallVector.h" |
64 | #include "llvm/ADT/TinyPtrVector.h" |
65 | #include "llvm/Frontend/OpenMP/OMPConstants.h" |
66 | #include <deque> |
67 | #include <memory> |
68 | #include <string> |
69 | #include <tuple> |
70 | #include <vector> |
71 | |
72 | namespace llvm { |
73 | class APSInt; |
74 | template <typename ValueT> struct DenseMapInfo; |
75 | template <typename ValueT, typename ValueInfoT> class DenseSet; |
76 | class SmallBitVector; |
77 | struct InlineAsmIdentifierInfo; |
78 | } |
79 | |
80 | namespace clang { |
81 | class ADLResult; |
82 | class ASTConsumer; |
83 | class ASTContext; |
84 | class ASTMutationListener; |
85 | class ASTReader; |
86 | class ASTWriter; |
87 | class ArrayType; |
88 | class ParsedAttr; |
89 | class BindingDecl; |
90 | class BlockDecl; |
91 | class CapturedDecl; |
92 | class CXXBasePath; |
93 | class CXXBasePaths; |
94 | class CXXBindTemporaryExpr; |
95 | typedef SmallVector<CXXBaseSpecifier*, 4> CXXCastPath; |
96 | class CXXConstructorDecl; |
97 | class CXXConversionDecl; |
98 | class CXXDeleteExpr; |
99 | class CXXDestructorDecl; |
100 | class CXXFieldCollector; |
101 | class CXXMemberCallExpr; |
102 | class CXXMethodDecl; |
103 | class CXXScopeSpec; |
104 | class CXXTemporary; |
105 | class CXXTryStmt; |
106 | class CallExpr; |
107 | class ClassTemplateDecl; |
108 | class ClassTemplatePartialSpecializationDecl; |
109 | class ClassTemplateSpecializationDecl; |
110 | class VarTemplatePartialSpecializationDecl; |
111 | class CodeCompleteConsumer; |
112 | class CodeCompletionAllocator; |
113 | class CodeCompletionTUInfo; |
114 | class CodeCompletionResult; |
115 | class CoroutineBodyStmt; |
116 | class Decl; |
117 | class DeclAccessPair; |
118 | class DeclContext; |
119 | class DeclRefExpr; |
120 | class DeclaratorDecl; |
121 | class DeducedTemplateArgument; |
122 | class DependentDiagnostic; |
123 | class DesignatedInitExpr; |
124 | class Designation; |
125 | class EnableIfAttr; |
126 | class EnumConstantDecl; |
127 | class Expr; |
128 | class ExtVectorType; |
129 | class FormatAttr; |
130 | class FriendDecl; |
131 | class FunctionDecl; |
132 | class FunctionProtoType; |
133 | class FunctionTemplateDecl; |
134 | class ImplicitConversionSequence; |
135 | typedef MutableArrayRef<ImplicitConversionSequence> ConversionSequenceList; |
136 | class InitListExpr; |
137 | class InitializationKind; |
138 | class InitializationSequence; |
139 | class InitializedEntity; |
140 | class IntegerLiteral; |
141 | class LabelStmt; |
142 | class LambdaExpr; |
143 | class LangOptions; |
144 | class LocalInstantiationScope; |
145 | class LookupResult; |
146 | class MacroInfo; |
147 | typedef ArrayRef<std::pair<IdentifierInfo *, SourceLocation>> ModuleIdPath; |
148 | class ModuleLoader; |
149 | class MultiLevelTemplateArgumentList; |
150 | class NamedDecl; |
151 | class ObjCCategoryDecl; |
152 | class ObjCCategoryImplDecl; |
153 | class ObjCCompatibleAliasDecl; |
154 | class ObjCContainerDecl; |
155 | class ObjCImplDecl; |
156 | class ObjCImplementationDecl; |
157 | class ObjCInterfaceDecl; |
158 | class ObjCIvarDecl; |
159 | template <class T> class ObjCList; |
160 | class ObjCMessageExpr; |
161 | class ObjCMethodDecl; |
162 | class ObjCPropertyDecl; |
163 | class ObjCProtocolDecl; |
164 | class OMPThreadPrivateDecl; |
165 | class OMPRequiresDecl; |
166 | class OMPDeclareReductionDecl; |
167 | class OMPDeclareSimdDecl; |
168 | class OMPClause; |
169 | struct OMPVarListLocTy; |
170 | struct OverloadCandidate; |
171 | enum class OverloadCandidateParamOrder : char; |
172 | enum OverloadCandidateRewriteKind : unsigned; |
173 | class OverloadCandidateSet; |
174 | class OverloadExpr; |
175 | class ParenListExpr; |
176 | class ParmVarDecl; |
177 | class Preprocessor; |
178 | class PseudoDestructorTypeStorage; |
179 | class PseudoObjectExpr; |
180 | class QualType; |
181 | class StandardConversionSequence; |
182 | class Stmt; |
183 | class StringLiteral; |
184 | class SwitchStmt; |
185 | class TemplateArgument; |
186 | class TemplateArgumentList; |
187 | class TemplateArgumentLoc; |
188 | class TemplateDecl; |
189 | class TemplateInstantiationCallback; |
190 | class TemplateParameterList; |
191 | class TemplatePartialOrderingContext; |
192 | class TemplateTemplateParmDecl; |
193 | class Token; |
194 | class TypeAliasDecl; |
195 | class TypedefDecl; |
196 | class TypedefNameDecl; |
197 | class TypeLoc; |
198 | class TypoCorrectionConsumer; |
199 | class UnqualifiedId; |
200 | class UnresolvedLookupExpr; |
201 | class UnresolvedMemberExpr; |
202 | class UnresolvedSetImpl; |
203 | class UnresolvedSetIterator; |
204 | class UsingDecl; |
205 | class UsingShadowDecl; |
206 | class ValueDecl; |
207 | class VarDecl; |
208 | class VarTemplateSpecializationDecl; |
209 | class VisibilityAttr; |
210 | class VisibleDeclConsumer; |
211 | class IndirectFieldDecl; |
212 | struct DeductionFailureInfo; |
213 | class TemplateSpecCandidateSet; |
214 | |
215 | namespace sema { |
216 | class AccessedEntity; |
217 | class BlockScopeInfo; |
218 | class Capture; |
219 | class CapturedRegionScopeInfo; |
220 | class CapturingScopeInfo; |
221 | class CompoundScopeInfo; |
222 | class DelayedDiagnostic; |
223 | class DelayedDiagnosticPool; |
224 | class FunctionScopeInfo; |
225 | class LambdaScopeInfo; |
226 | class PossiblyUnreachableDiag; |
227 | class SemaPPCallbacks; |
228 | class TemplateDeductionInfo; |
229 | } |
230 | |
231 | namespace threadSafety { |
232 | class BeforeSet; |
233 | void threadSafetyCleanup(BeforeSet* Cache); |
234 | } |
235 | |
236 | // FIXME: No way to easily map from TemplateTypeParmTypes to |
237 | // TemplateTypeParmDecls, so we have this horrible PointerUnion. |
238 | typedef std::pair<llvm::PointerUnion<const TemplateTypeParmType*, NamedDecl*>, |
239 | SourceLocation> UnexpandedParameterPack; |
240 | |
241 | /// Describes whether we've seen any nullability information for the given |
242 | /// file. |
243 | struct FileNullability { |
244 | /// The first pointer declarator (of any pointer kind) in the file that does |
245 | /// not have a corresponding nullability annotation. |
246 | SourceLocation PointerLoc; |
247 | |
248 | /// The end location for the first pointer declarator in the file. Used for |
249 | /// placing fix-its. |
250 | SourceLocation PointerEndLoc; |
251 | |
252 | /// Which kind of pointer declarator we saw. |
253 | uint8_t PointerKind; |
254 | |
255 | /// Whether we saw any type nullability annotations in the given file. |
256 | bool SawTypeNullability = false; |
257 | }; |
258 | |
259 | /// A mapping from file IDs to a record of whether we've seen nullability |
260 | /// information in that file. |
261 | class FileNullabilityMap { |
262 | /// A mapping from file IDs to the nullability information for each file ID. |
263 | llvm::DenseMap<FileID, FileNullability> Map; |
264 | |
265 | /// A single-element cache based on the file ID. |
266 | struct { |
267 | FileID File; |
268 | FileNullability Nullability; |
269 | } Cache; |
270 | |
271 | public: |
272 | FileNullability &operator[](FileID file) { |
273 | // Check the single-element cache. |
274 | if (file == Cache.File) |
275 | return Cache.Nullability; |
276 | |
277 | // It's not in the single-element cache; flush the cache if we have one. |
278 | if (!Cache.File.isInvalid()) { |
279 | Map[Cache.File] = Cache.Nullability; |
280 | } |
281 | |
282 | // Pull this entry into the cache. |
283 | Cache.File = file; |
284 | Cache.Nullability = Map[file]; |
285 | return Cache.Nullability; |
286 | } |
287 | }; |
288 | |
289 | /// Keeps track of expected type during expression parsing. The type is tied to |
290 | /// a particular token, all functions that update or consume the type take a |
291 | /// start location of the token they are looking at as a parameter. This allows |
292 | /// to avoid updating the type on hot paths in the parser. |
293 | class PreferredTypeBuilder { |
294 | public: |
295 | PreferredTypeBuilder() = default; |
296 | explicit PreferredTypeBuilder(QualType Type) : Type(Type) {} |
297 | |
298 | void enterCondition(Sema &S, SourceLocation Tok); |
299 | void enterReturn(Sema &S, SourceLocation Tok); |
300 | void enterVariableInit(SourceLocation Tok, Decl *D); |
301 | /// Computing a type for the function argument may require running |
302 | /// overloading, so we postpone its computation until it is actually needed. |
303 | /// |
304 | /// Clients should be very careful when using this funciton, as it stores a |
305 | /// function_ref, clients should make sure all calls to get() with the same |
306 | /// location happen while function_ref is alive. |
307 | void enterFunctionArgument(SourceLocation Tok, |
308 | llvm::function_ref<QualType()> ComputeType); |
309 | |
310 | void enterParenExpr(SourceLocation Tok, SourceLocation LParLoc); |
311 | void enterUnary(Sema &S, SourceLocation Tok, tok::TokenKind OpKind, |
312 | SourceLocation OpLoc); |
313 | void enterBinary(Sema &S, SourceLocation Tok, Expr *LHS, tok::TokenKind Op); |
314 | void enterMemAccess(Sema &S, SourceLocation Tok, Expr *Base); |
315 | void enterSubscript(Sema &S, SourceLocation Tok, Expr *LHS); |
316 | /// Handles all type casts, including C-style cast, C++ casts, etc. |
317 | void enterTypeCast(SourceLocation Tok, QualType CastType); |
318 | |
319 | QualType get(SourceLocation Tok) const { |
320 | if (Tok != ExpectedLoc) |
321 | return QualType(); |
322 | if (!Type.isNull()) |
323 | return Type; |
324 | if (ComputeType) |
325 | return ComputeType(); |
326 | return QualType(); |
327 | } |
328 | |
329 | private: |
330 | /// Start position of a token for which we store expected type. |
331 | SourceLocation ExpectedLoc; |
332 | /// Expected type for a token starting at ExpectedLoc. |
333 | QualType Type; |
334 | /// A function to compute expected type at ExpectedLoc. It is only considered |
335 | /// if Type is null. |
336 | llvm::function_ref<QualType()> ComputeType; |
337 | }; |
338 | |
339 | /// Sema - This implements semantic analysis and AST building for C. |
340 | class Sema final { |
341 | Sema(const Sema &) = delete; |
342 | void operator=(const Sema &) = delete; |
343 | |
344 | /// A key method to reduce duplicate debug info from Sema. |
345 | virtual void anchor(); |
346 | |
347 | ///Source of additional semantic information. |
348 | ExternalSemaSource *ExternalSource; |
349 | |
350 | ///Whether Sema has generated a multiplexer and has to delete it. |
351 | bool isMultiplexExternalSource; |
352 | |
353 | static bool mightHaveNonExternalLinkage(const DeclaratorDecl *FD); |
354 | |
355 | bool isVisibleSlow(const NamedDecl *D); |
356 | |
357 | /// Determine whether two declarations should be linked together, given that |
358 | /// the old declaration might not be visible and the new declaration might |
359 | /// not have external linkage. |
360 | bool shouldLinkPossiblyHiddenDecl(const NamedDecl *Old, |
361 | const NamedDecl *New) { |
362 | if (isVisible(Old)) |
363 | return true; |
364 | // See comment in below overload for why it's safe to compute the linkage |
365 | // of the new declaration here. |
366 | if (New->isExternallyDeclarable()) { |
367 | assert(Old->isExternallyDeclarable() &&((Old->isExternallyDeclarable() && "should not have found a non-externally-declarable previous decl" ) ? static_cast<void> (0) : __assert_fail ("Old->isExternallyDeclarable() && \"should not have found a non-externally-declarable previous decl\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 368, __PRETTY_FUNCTION__)) |
368 | "should not have found a non-externally-declarable previous decl")((Old->isExternallyDeclarable() && "should not have found a non-externally-declarable previous decl" ) ? static_cast<void> (0) : __assert_fail ("Old->isExternallyDeclarable() && \"should not have found a non-externally-declarable previous decl\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 368, __PRETTY_FUNCTION__)); |
369 | return true; |
370 | } |
371 | return false; |
372 | } |
373 | bool shouldLinkPossiblyHiddenDecl(LookupResult &Old, const NamedDecl *New); |
374 | |
375 | void setupImplicitSpecialMemberType(CXXMethodDecl *SpecialMem, |
376 | QualType ResultTy, |
377 | ArrayRef<QualType> Args); |
378 | |
379 | public: |
380 | /// The maximum alignment, same as in llvm::Value. We duplicate them here |
381 | /// because that allows us not to duplicate the constants in clang code, |
382 | /// which we must to since we can't directly use the llvm constants. |
383 | /// The value is verified against llvm here: lib/CodeGen/CGDecl.cpp |
384 | /// |
385 | /// This is the greatest alignment value supported by load, store, and alloca |
386 | /// instructions, and global values. |
387 | static const unsigned MaxAlignmentExponent = 29; |
388 | static const unsigned MaximumAlignment = 1u << MaxAlignmentExponent; |
389 | |
390 | typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy; |
391 | typedef OpaquePtr<TemplateName> TemplateTy; |
392 | typedef OpaquePtr<QualType> TypeTy; |
393 | |
394 | OpenCLOptions OpenCLFeatures; |
395 | FPOptions CurFPFeatures; |
396 | |
397 | const LangOptions &LangOpts; |
398 | Preprocessor &PP; |
399 | ASTContext &Context; |
400 | ASTConsumer &Consumer; |
401 | DiagnosticsEngine &Diags; |
402 | SourceManager &SourceMgr; |
403 | |
404 | /// Flag indicating whether or not to collect detailed statistics. |
405 | bool CollectStats; |
406 | |
407 | /// Code-completion consumer. |
408 | CodeCompleteConsumer *CodeCompleter; |
409 | |
410 | /// CurContext - This is the current declaration context of parsing. |
411 | DeclContext *CurContext; |
412 | |
413 | /// Generally null except when we temporarily switch decl contexts, |
414 | /// like in \see ActOnObjCTemporaryExitContainerContext. |
415 | DeclContext *OriginalLexicalContext; |
416 | |
417 | /// VAListTagName - The declaration name corresponding to __va_list_tag. |
418 | /// This is used as part of a hack to omit that class from ADL results. |
419 | DeclarationName VAListTagName; |
420 | |
421 | bool MSStructPragmaOn; // True when \#pragma ms_struct on |
422 | |
423 | /// Controls member pointer representation format under the MS ABI. |
424 | LangOptions::PragmaMSPointersToMembersKind |
425 | MSPointerToMemberRepresentationMethod; |
426 | |
427 | /// Stack of active SEH __finally scopes. Can be empty. |
428 | SmallVector<Scope*, 2> CurrentSEHFinally; |
429 | |
430 | /// Source location for newly created implicit MSInheritanceAttrs |
431 | SourceLocation ImplicitMSInheritanceAttrLoc; |
432 | |
433 | /// Holds TypoExprs that are created from `createDelayedTypo`. This is used by |
434 | /// `TransformTypos` in order to keep track of any TypoExprs that are created |
435 | /// recursively during typo correction and wipe them away if the correction |
436 | /// fails. |
437 | llvm::SmallVector<TypoExpr *, 2> TypoExprs; |
438 | |
439 | /// pragma clang section kind |
440 | enum PragmaClangSectionKind { |
441 | PCSK_Invalid = 0, |
442 | PCSK_BSS = 1, |
443 | PCSK_Data = 2, |
444 | PCSK_Rodata = 3, |
445 | PCSK_Text = 4, |
446 | PCSK_Relro = 5 |
447 | }; |
448 | |
449 | enum PragmaClangSectionAction { |
450 | PCSA_Set = 0, |
451 | PCSA_Clear = 1 |
452 | }; |
453 | |
454 | struct PragmaClangSection { |
455 | std::string SectionName; |
456 | bool Valid = false; |
457 | SourceLocation PragmaLocation; |
458 | |
459 | void Act(SourceLocation PragmaLocation, |
460 | PragmaClangSectionAction Action, |
461 | StringLiteral* Name); |
462 | }; |
463 | |
464 | PragmaClangSection PragmaClangBSSSection; |
465 | PragmaClangSection PragmaClangDataSection; |
466 | PragmaClangSection PragmaClangRodataSection; |
467 | PragmaClangSection PragmaClangRelroSection; |
468 | PragmaClangSection PragmaClangTextSection; |
469 | |
470 | enum PragmaMsStackAction { |
471 | PSK_Reset = 0x0, // #pragma () |
472 | PSK_Set = 0x1, // #pragma (value) |
473 | PSK_Push = 0x2, // #pragma (push[, id]) |
474 | PSK_Pop = 0x4, // #pragma (pop[, id]) |
475 | PSK_Show = 0x8, // #pragma (show) -- only for "pack"! |
476 | PSK_Push_Set = PSK_Push | PSK_Set, // #pragma (push[, id], value) |
477 | PSK_Pop_Set = PSK_Pop | PSK_Set, // #pragma (pop[, id], value) |
478 | }; |
479 | |
480 | template<typename ValueType> |
481 | struct PragmaStack { |
482 | struct Slot { |
483 | llvm::StringRef StackSlotLabel; |
484 | ValueType Value; |
485 | SourceLocation PragmaLocation; |
486 | SourceLocation PragmaPushLocation; |
487 | Slot(llvm::StringRef StackSlotLabel, ValueType Value, |
488 | SourceLocation PragmaLocation, SourceLocation PragmaPushLocation) |
489 | : StackSlotLabel(StackSlotLabel), Value(Value), |
490 | PragmaLocation(PragmaLocation), |
491 | PragmaPushLocation(PragmaPushLocation) {} |
492 | }; |
493 | |
494 | void Act(SourceLocation PragmaLocation, PragmaMsStackAction Action, |
495 | llvm::StringRef StackSlotLabel, ValueType Value) { |
496 | if (Action == PSK_Reset) { |
497 | CurrentValue = DefaultValue; |
498 | CurrentPragmaLocation = PragmaLocation; |
499 | return; |
500 | } |
501 | if (Action & PSK_Push) |
502 | Stack.emplace_back(StackSlotLabel, CurrentValue, CurrentPragmaLocation, |
503 | PragmaLocation); |
504 | else if (Action & PSK_Pop) { |
505 | if (!StackSlotLabel.empty()) { |
506 | // If we've got a label, try to find it and jump there. |
507 | auto I = llvm::find_if(llvm::reverse(Stack), [&](const Slot &x) { |
508 | return x.StackSlotLabel == StackSlotLabel; |
509 | }); |
510 | // If we found the label so pop from there. |
511 | if (I != Stack.rend()) { |
512 | CurrentValue = I->Value; |
513 | CurrentPragmaLocation = I->PragmaLocation; |
514 | Stack.erase(std::prev(I.base()), Stack.end()); |
515 | } |
516 | } else if (!Stack.empty()) { |
517 | // We do not have a label, just pop the last entry. |
518 | CurrentValue = Stack.back().Value; |
519 | CurrentPragmaLocation = Stack.back().PragmaLocation; |
520 | Stack.pop_back(); |
521 | } |
522 | } |
523 | if (Action & PSK_Set) { |
524 | CurrentValue = Value; |
525 | CurrentPragmaLocation = PragmaLocation; |
526 | } |
527 | } |
528 | |
529 | // MSVC seems to add artificial slots to #pragma stacks on entering a C++ |
530 | // method body to restore the stacks on exit, so it works like this: |
531 | // |
532 | // struct S { |
533 | // #pragma <name>(push, InternalPragmaSlot, <current_pragma_value>) |
534 | // void Method {} |
535 | // #pragma <name>(pop, InternalPragmaSlot) |
536 | // }; |
537 | // |
538 | // It works even with #pragma vtordisp, although MSVC doesn't support |
539 | // #pragma vtordisp(push [, id], n) |
540 | // syntax. |
541 | // |
542 | // Push / pop a named sentinel slot. |
543 | void SentinelAction(PragmaMsStackAction Action, StringRef Label) { |
544 | assert((Action == PSK_Push || Action == PSK_Pop) &&(((Action == PSK_Push || Action == PSK_Pop) && "Can only push / pop #pragma stack sentinels!" ) ? static_cast<void> (0) : __assert_fail ("(Action == PSK_Push || Action == PSK_Pop) && \"Can only push / pop #pragma stack sentinels!\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 545, __PRETTY_FUNCTION__)) |
545 | "Can only push / pop #pragma stack sentinels!")(((Action == PSK_Push || Action == PSK_Pop) && "Can only push / pop #pragma stack sentinels!" ) ? static_cast<void> (0) : __assert_fail ("(Action == PSK_Push || Action == PSK_Pop) && \"Can only push / pop #pragma stack sentinels!\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 545, __PRETTY_FUNCTION__)); |
546 | Act(CurrentPragmaLocation, Action, Label, CurrentValue); |
547 | } |
548 | |
549 | // Constructors. |
550 | explicit PragmaStack(const ValueType &Default) |
551 | : DefaultValue(Default), CurrentValue(Default) {} |
552 | |
553 | bool hasValue() const { return CurrentValue != DefaultValue; } |
554 | |
555 | SmallVector<Slot, 2> Stack; |
556 | ValueType DefaultValue; // Value used for PSK_Reset action. |
557 | ValueType CurrentValue; |
558 | SourceLocation CurrentPragmaLocation; |
559 | }; |
560 | // FIXME: We should serialize / deserialize these if they occur in a PCH (but |
561 | // we shouldn't do so if they're in a module). |
562 | |
563 | /// Whether to insert vtordisps prior to virtual bases in the Microsoft |
564 | /// C++ ABI. Possible values are 0, 1, and 2, which mean: |
565 | /// |
566 | /// 0: Suppress all vtordisps |
567 | /// 1: Insert vtordisps in the presence of vbase overrides and non-trivial |
568 | /// structors |
569 | /// 2: Always insert vtordisps to support RTTI on partially constructed |
570 | /// objects |
571 | PragmaStack<MSVtorDispMode> VtorDispStack; |
572 | // #pragma pack. |
573 | // Sentinel to represent when the stack is set to mac68k alignment. |
574 | static const unsigned kMac68kAlignmentSentinel = ~0U; |
575 | PragmaStack<unsigned> PackStack; |
576 | // The current #pragma pack values and locations at each #include. |
577 | struct PackIncludeState { |
578 | unsigned CurrentValue; |
579 | SourceLocation CurrentPragmaLocation; |
580 | bool HasNonDefaultValue, ShouldWarnOnInclude; |
581 | }; |
582 | SmallVector<PackIncludeState, 8> PackIncludeStack; |
583 | // Segment #pragmas. |
584 | PragmaStack<StringLiteral *> DataSegStack; |
585 | PragmaStack<StringLiteral *> BSSSegStack; |
586 | PragmaStack<StringLiteral *> ConstSegStack; |
587 | PragmaStack<StringLiteral *> CodeSegStack; |
588 | |
589 | // This stack tracks the current state of Sema.CurFPFeatures. |
590 | PragmaStack<FPOptionsOverride> FpPragmaStack; |
591 | FPOptionsOverride CurFPFeatureOverrides() { |
592 | FPOptionsOverride result; |
593 | if (!FpPragmaStack.hasValue()) { |
594 | result = FPOptionsOverride(); |
595 | } else { |
596 | result = FpPragmaStack.CurrentValue; |
597 | } |
598 | return result; |
599 | } |
600 | |
601 | // RAII object to push / pop sentinel slots for all MS #pragma stacks. |
602 | // Actions should be performed only if we enter / exit a C++ method body. |
603 | class PragmaStackSentinelRAII { |
604 | public: |
605 | PragmaStackSentinelRAII(Sema &S, StringRef SlotLabel, bool ShouldAct); |
606 | ~PragmaStackSentinelRAII(); |
607 | |
608 | private: |
609 | Sema &S; |
610 | StringRef SlotLabel; |
611 | bool ShouldAct; |
612 | }; |
613 | |
614 | /// A mapping that describes the nullability we've seen in each header file. |
615 | FileNullabilityMap NullabilityMap; |
616 | |
617 | /// Last section used with #pragma init_seg. |
618 | StringLiteral *CurInitSeg; |
619 | SourceLocation CurInitSegLoc; |
620 | |
621 | /// VisContext - Manages the stack for \#pragma GCC visibility. |
622 | void *VisContext; // Really a "PragmaVisStack*" |
623 | |
624 | /// This an attribute introduced by \#pragma clang attribute. |
625 | struct PragmaAttributeEntry { |
626 | SourceLocation Loc; |
627 | ParsedAttr *Attribute; |
628 | SmallVector<attr::SubjectMatchRule, 4> MatchRules; |
629 | bool IsUsed; |
630 | }; |
631 | |
632 | /// A push'd group of PragmaAttributeEntries. |
633 | struct PragmaAttributeGroup { |
634 | /// The location of the push attribute. |
635 | SourceLocation Loc; |
636 | /// The namespace of this push group. |
637 | const IdentifierInfo *Namespace; |
638 | SmallVector<PragmaAttributeEntry, 2> Entries; |
639 | }; |
640 | |
641 | SmallVector<PragmaAttributeGroup, 2> PragmaAttributeStack; |
642 | |
643 | /// The declaration that is currently receiving an attribute from the |
644 | /// #pragma attribute stack. |
645 | const Decl *PragmaAttributeCurrentTargetDecl; |
646 | |
647 | /// This represents the last location of a "#pragma clang optimize off" |
648 | /// directive if such a directive has not been closed by an "on" yet. If |
649 | /// optimizations are currently "on", this is set to an invalid location. |
650 | SourceLocation OptimizeOffPragmaLocation; |
651 | |
652 | /// Flag indicating if Sema is building a recovery call expression. |
653 | /// |
654 | /// This flag is used to avoid building recovery call expressions |
655 | /// if Sema is already doing so, which would cause infinite recursions. |
656 | bool IsBuildingRecoveryCallExpr; |
657 | |
658 | /// Used to control the generation of ExprWithCleanups. |
659 | CleanupInfo Cleanup; |
660 | |
661 | /// ExprCleanupObjects - This is the stack of objects requiring |
662 | /// cleanup that are created by the current full expression. |
663 | SmallVector<ExprWithCleanups::CleanupObject, 8> ExprCleanupObjects; |
664 | |
665 | /// Store a set of either DeclRefExprs or MemberExprs that contain a reference |
666 | /// to a variable (constant) that may or may not be odr-used in this Expr, and |
667 | /// we won't know until all lvalue-to-rvalue and discarded value conversions |
668 | /// have been applied to all subexpressions of the enclosing full expression. |
669 | /// This is cleared at the end of each full expression. |
670 | using MaybeODRUseExprSet = llvm::SetVector<Expr *, SmallVector<Expr *, 4>, |
671 | llvm::SmallPtrSet<Expr *, 4>>; |
672 | MaybeODRUseExprSet MaybeODRUseExprs; |
673 | |
674 | std::unique_ptr<sema::FunctionScopeInfo> CachedFunctionScope; |
675 | |
676 | /// Stack containing information about each of the nested |
677 | /// function, block, and method scopes that are currently active. |
678 | SmallVector<sema::FunctionScopeInfo *, 4> FunctionScopes; |
679 | |
680 | /// The index of the first FunctionScope that corresponds to the current |
681 | /// context. |
682 | unsigned FunctionScopesStart = 0; |
683 | |
684 | ArrayRef<sema::FunctionScopeInfo*> getFunctionScopes() const { |
685 | return llvm::makeArrayRef(FunctionScopes.begin() + FunctionScopesStart, |
686 | FunctionScopes.end()); |
687 | } |
688 | |
689 | /// Stack containing information needed when in C++2a an 'auto' is encountered |
690 | /// in a function declaration parameter type specifier in order to invent a |
691 | /// corresponding template parameter in the enclosing abbreviated function |
692 | /// template. This information is also present in LambdaScopeInfo, stored in |
693 | /// the FunctionScopes stack. |
694 | SmallVector<InventedTemplateParameterInfo, 4> InventedParameterInfos; |
695 | |
696 | /// The index of the first InventedParameterInfo that refers to the current |
697 | /// context. |
698 | unsigned InventedParameterInfosStart = 0; |
699 | |
700 | ArrayRef<InventedTemplateParameterInfo> getInventedParameterInfos() const { |
701 | return llvm::makeArrayRef(InventedParameterInfos.begin() + |
702 | InventedParameterInfosStart, |
703 | InventedParameterInfos.end()); |
704 | } |
705 | |
706 | typedef LazyVector<TypedefNameDecl *, ExternalSemaSource, |
707 | &ExternalSemaSource::ReadExtVectorDecls, 2, 2> |
708 | ExtVectorDeclsType; |
709 | |
710 | /// ExtVectorDecls - This is a list all the extended vector types. This allows |
711 | /// us to associate a raw vector type with one of the ext_vector type names. |
712 | /// This is only necessary for issuing pretty diagnostics. |
713 | ExtVectorDeclsType ExtVectorDecls; |
714 | |
715 | /// FieldCollector - Collects CXXFieldDecls during parsing of C++ classes. |
716 | std::unique_ptr<CXXFieldCollector> FieldCollector; |
717 | |
718 | typedef llvm::SmallSetVector<NamedDecl *, 16> NamedDeclSetType; |
719 | |
720 | /// Set containing all declared private fields that are not used. |
721 | NamedDeclSetType UnusedPrivateFields; |
722 | |
723 | /// Set containing all typedefs that are likely unused. |
724 | llvm::SmallSetVector<const TypedefNameDecl *, 4> |
725 | UnusedLocalTypedefNameCandidates; |
726 | |
727 | /// Delete-expressions to be analyzed at the end of translation unit |
728 | /// |
729 | /// This list contains class members, and locations of delete-expressions |
730 | /// that could not be proven as to whether they mismatch with new-expression |
731 | /// used in initializer of the field. |
732 | typedef std::pair<SourceLocation, bool> DeleteExprLoc; |
733 | typedef llvm::SmallVector<DeleteExprLoc, 4> DeleteLocs; |
734 | llvm::MapVector<FieldDecl *, DeleteLocs> DeleteExprs; |
735 | |
736 | typedef llvm::SmallPtrSet<const CXXRecordDecl*, 8> RecordDeclSetTy; |
737 | |
738 | /// PureVirtualClassDiagSet - a set of class declarations which we have |
739 | /// emitted a list of pure virtual functions. Used to prevent emitting the |
740 | /// same list more than once. |
741 | std::unique_ptr<RecordDeclSetTy> PureVirtualClassDiagSet; |
742 | |
743 | /// ParsingInitForAutoVars - a set of declarations with auto types for which |
744 | /// we are currently parsing the initializer. |
745 | llvm::SmallPtrSet<const Decl*, 4> ParsingInitForAutoVars; |
746 | |
747 | /// Look for a locally scoped extern "C" declaration by the given name. |
748 | NamedDecl *findLocallyScopedExternCDecl(DeclarationName Name); |
749 | |
750 | typedef LazyVector<VarDecl *, ExternalSemaSource, |
751 | &ExternalSemaSource::ReadTentativeDefinitions, 2, 2> |
752 | TentativeDefinitionsType; |
753 | |
754 | /// All the tentative definitions encountered in the TU. |
755 | TentativeDefinitionsType TentativeDefinitions; |
756 | |
757 | /// All the external declarations encoutered and used in the TU. |
758 | SmallVector<VarDecl *, 4> ExternalDeclarations; |
759 | |
760 | typedef LazyVector<const DeclaratorDecl *, ExternalSemaSource, |
761 | &ExternalSemaSource::ReadUnusedFileScopedDecls, 2, 2> |
762 | UnusedFileScopedDeclsType; |
763 | |
764 | /// The set of file scoped decls seen so far that have not been used |
765 | /// and must warn if not used. Only contains the first declaration. |
766 | UnusedFileScopedDeclsType UnusedFileScopedDecls; |
767 | |
768 | typedef LazyVector<CXXConstructorDecl *, ExternalSemaSource, |
769 | &ExternalSemaSource::ReadDelegatingConstructors, 2, 2> |
770 | DelegatingCtorDeclsType; |
771 | |
772 | /// All the delegating constructors seen so far in the file, used for |
773 | /// cycle detection at the end of the TU. |
774 | DelegatingCtorDeclsType DelegatingCtorDecls; |
775 | |
776 | /// All the overriding functions seen during a class definition |
777 | /// that had their exception spec checks delayed, plus the overridden |
778 | /// function. |
779 | SmallVector<std::pair<const CXXMethodDecl*, const CXXMethodDecl*>, 2> |
780 | DelayedOverridingExceptionSpecChecks; |
781 | |
782 | /// All the function redeclarations seen during a class definition that had |
783 | /// their exception spec checks delayed, plus the prior declaration they |
784 | /// should be checked against. Except during error recovery, the new decl |
785 | /// should always be a friend declaration, as that's the only valid way to |
786 | /// redeclare a special member before its class is complete. |
787 | SmallVector<std::pair<FunctionDecl*, FunctionDecl*>, 2> |
788 | DelayedEquivalentExceptionSpecChecks; |
789 | |
790 | typedef llvm::MapVector<const FunctionDecl *, |
791 | std::unique_ptr<LateParsedTemplate>> |
792 | LateParsedTemplateMapT; |
793 | LateParsedTemplateMapT LateParsedTemplateMap; |
794 | |
795 | /// Callback to the parser to parse templated functions when needed. |
796 | typedef void LateTemplateParserCB(void *P, LateParsedTemplate &LPT); |
797 | typedef void LateTemplateParserCleanupCB(void *P); |
798 | LateTemplateParserCB *LateTemplateParser; |
799 | LateTemplateParserCleanupCB *LateTemplateParserCleanup; |
800 | void *OpaqueParser; |
801 | |
802 | void SetLateTemplateParser(LateTemplateParserCB *LTP, |
803 | LateTemplateParserCleanupCB *LTPCleanup, |
804 | void *P) { |
805 | LateTemplateParser = LTP; |
806 | LateTemplateParserCleanup = LTPCleanup; |
807 | OpaqueParser = P; |
808 | } |
809 | |
810 | class DelayedDiagnostics; |
811 | |
812 | class DelayedDiagnosticsState { |
813 | sema::DelayedDiagnosticPool *SavedPool; |
814 | friend class Sema::DelayedDiagnostics; |
815 | }; |
816 | typedef DelayedDiagnosticsState ParsingDeclState; |
817 | typedef DelayedDiagnosticsState ProcessingContextState; |
818 | |
819 | /// A class which encapsulates the logic for delaying diagnostics |
820 | /// during parsing and other processing. |
821 | class DelayedDiagnostics { |
822 | /// The current pool of diagnostics into which delayed |
823 | /// diagnostics should go. |
824 | sema::DelayedDiagnosticPool *CurPool; |
825 | |
826 | public: |
827 | DelayedDiagnostics() : CurPool(nullptr) {} |
828 | |
829 | /// Adds a delayed diagnostic. |
830 | void add(const sema::DelayedDiagnostic &diag); // in DelayedDiagnostic.h |
831 | |
832 | /// Determines whether diagnostics should be delayed. |
833 | bool shouldDelayDiagnostics() { return CurPool != nullptr; } |
834 | |
835 | /// Returns the current delayed-diagnostics pool. |
836 | sema::DelayedDiagnosticPool *getCurrentPool() const { |
837 | return CurPool; |
838 | } |
839 | |
840 | /// Enter a new scope. Access and deprecation diagnostics will be |
841 | /// collected in this pool. |
842 | DelayedDiagnosticsState push(sema::DelayedDiagnosticPool &pool) { |
843 | DelayedDiagnosticsState state; |
844 | state.SavedPool = CurPool; |
845 | CurPool = &pool; |
846 | return state; |
847 | } |
848 | |
849 | /// Leave a delayed-diagnostic state that was previously pushed. |
850 | /// Do not emit any of the diagnostics. This is performed as part |
851 | /// of the bookkeeping of popping a pool "properly". |
852 | void popWithoutEmitting(DelayedDiagnosticsState state) { |
853 | CurPool = state.SavedPool; |
854 | } |
855 | |
856 | /// Enter a new scope where access and deprecation diagnostics are |
857 | /// not delayed. |
858 | DelayedDiagnosticsState pushUndelayed() { |
859 | DelayedDiagnosticsState state; |
860 | state.SavedPool = CurPool; |
861 | CurPool = nullptr; |
862 | return state; |
863 | } |
864 | |
865 | /// Undo a previous pushUndelayed(). |
866 | void popUndelayed(DelayedDiagnosticsState state) { |
867 | assert(CurPool == nullptr)((CurPool == nullptr) ? static_cast<void> (0) : __assert_fail ("CurPool == nullptr", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 867, __PRETTY_FUNCTION__)); |
868 | CurPool = state.SavedPool; |
869 | } |
870 | } DelayedDiagnostics; |
871 | |
872 | /// A RAII object to temporarily push a declaration context. |
873 | class ContextRAII { |
874 | private: |
875 | Sema &S; |
876 | DeclContext *SavedContext; |
877 | ProcessingContextState SavedContextState; |
878 | QualType SavedCXXThisTypeOverride; |
879 | unsigned SavedFunctionScopesStart; |
880 | unsigned SavedInventedParameterInfosStart; |
881 | |
882 | public: |
883 | ContextRAII(Sema &S, DeclContext *ContextToPush, bool NewThisContext = true) |
884 | : S(S), SavedContext(S.CurContext), |
885 | SavedContextState(S.DelayedDiagnostics.pushUndelayed()), |
886 | SavedCXXThisTypeOverride(S.CXXThisTypeOverride), |
887 | SavedFunctionScopesStart(S.FunctionScopesStart), |
888 | SavedInventedParameterInfosStart(S.InventedParameterInfosStart) |
889 | { |
890 | assert(ContextToPush && "pushing null context")((ContextToPush && "pushing null context") ? static_cast <void> (0) : __assert_fail ("ContextToPush && \"pushing null context\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 890, __PRETTY_FUNCTION__)); |
891 | S.CurContext = ContextToPush; |
892 | if (NewThisContext) |
893 | S.CXXThisTypeOverride = QualType(); |
894 | // Any saved FunctionScopes do not refer to this context. |
895 | S.FunctionScopesStart = S.FunctionScopes.size(); |
896 | S.InventedParameterInfosStart = S.InventedParameterInfos.size(); |
897 | } |
898 | |
899 | void pop() { |
900 | if (!SavedContext) return; |
901 | S.CurContext = SavedContext; |
902 | S.DelayedDiagnostics.popUndelayed(SavedContextState); |
903 | S.CXXThisTypeOverride = SavedCXXThisTypeOverride; |
904 | S.FunctionScopesStart = SavedFunctionScopesStart; |
905 | S.InventedParameterInfosStart = SavedInventedParameterInfosStart; |
906 | SavedContext = nullptr; |
907 | } |
908 | |
909 | ~ContextRAII() { |
910 | pop(); |
911 | } |
912 | }; |
913 | |
914 | /// Whether the AST is currently being rebuilt to correct immediate |
915 | /// invocations. Immediate invocation candidates and references to consteval |
916 | /// functions aren't tracked when this is set. |
917 | bool RebuildingImmediateInvocation = false; |
918 | |
919 | /// Used to change context to isConstantEvaluated without pushing a heavy |
920 | /// ExpressionEvaluationContextRecord object. |
921 | bool isConstantEvaluatedOverride; |
922 | |
923 | bool isConstantEvaluated() { |
924 | return ExprEvalContexts.back().isConstantEvaluated() || |
925 | isConstantEvaluatedOverride; |
926 | } |
927 | |
928 | /// RAII object to handle the state changes required to synthesize |
929 | /// a function body. |
930 | class SynthesizedFunctionScope { |
931 | Sema &S; |
932 | Sema::ContextRAII SavedContext; |
933 | bool PushedCodeSynthesisContext = false; |
934 | |
935 | public: |
936 | SynthesizedFunctionScope(Sema &S, DeclContext *DC) |
937 | : S(S), SavedContext(S, DC) { |
938 | S.PushFunctionScope(); |
939 | S.PushExpressionEvaluationContext( |
940 | Sema::ExpressionEvaluationContext::PotentiallyEvaluated); |
941 | if (auto *FD = dyn_cast<FunctionDecl>(DC)) |
942 | FD->setWillHaveBody(true); |
943 | else |
944 | assert(isa<ObjCMethodDecl>(DC))((isa<ObjCMethodDecl>(DC)) ? static_cast<void> (0 ) : __assert_fail ("isa<ObjCMethodDecl>(DC)", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 944, __PRETTY_FUNCTION__)); |
945 | } |
946 | |
947 | void addContextNote(SourceLocation UseLoc) { |
948 | assert(!PushedCodeSynthesisContext)((!PushedCodeSynthesisContext) ? static_cast<void> (0) : __assert_fail ("!PushedCodeSynthesisContext", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 948, __PRETTY_FUNCTION__)); |
949 | |
950 | Sema::CodeSynthesisContext Ctx; |
951 | Ctx.Kind = Sema::CodeSynthesisContext::DefiningSynthesizedFunction; |
952 | Ctx.PointOfInstantiation = UseLoc; |
953 | Ctx.Entity = cast<Decl>(S.CurContext); |
954 | S.pushCodeSynthesisContext(Ctx); |
955 | |
956 | PushedCodeSynthesisContext = true; |
957 | } |
958 | |
959 | ~SynthesizedFunctionScope() { |
960 | if (PushedCodeSynthesisContext) |
961 | S.popCodeSynthesisContext(); |
962 | if (auto *FD = dyn_cast<FunctionDecl>(S.CurContext)) |
963 | FD->setWillHaveBody(false); |
964 | S.PopExpressionEvaluationContext(); |
965 | S.PopFunctionScopeInfo(); |
966 | } |
967 | }; |
968 | |
969 | /// WeakUndeclaredIdentifiers - Identifiers contained in |
970 | /// \#pragma weak before declared. rare. may alias another |
971 | /// identifier, declared or undeclared |
972 | llvm::MapVector<IdentifierInfo *, WeakInfo> WeakUndeclaredIdentifiers; |
973 | |
974 | /// ExtnameUndeclaredIdentifiers - Identifiers contained in |
975 | /// \#pragma redefine_extname before declared. Used in Solaris system headers |
976 | /// to define functions that occur in multiple standards to call the version |
977 | /// in the currently selected standard. |
978 | llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*> ExtnameUndeclaredIdentifiers; |
979 | |
980 | |
981 | /// Load weak undeclared identifiers from the external source. |
982 | void LoadExternalWeakUndeclaredIdentifiers(); |
983 | |
984 | /// WeakTopLevelDecl - Translation-unit scoped declarations generated by |
985 | /// \#pragma weak during processing of other Decls. |
986 | /// I couldn't figure out a clean way to generate these in-line, so |
987 | /// we store them here and handle separately -- which is a hack. |
988 | /// It would be best to refactor this. |
989 | SmallVector<Decl*,2> WeakTopLevelDecl; |
990 | |
991 | IdentifierResolver IdResolver; |
992 | |
993 | /// Translation Unit Scope - useful to Objective-C actions that need |
994 | /// to lookup file scope declarations in the "ordinary" C decl namespace. |
995 | /// For example, user-defined classes, built-in "id" type, etc. |
996 | Scope *TUScope; |
997 | |
998 | /// The C++ "std" namespace, where the standard library resides. |
999 | LazyDeclPtr StdNamespace; |
1000 | |
1001 | /// The C++ "std::bad_alloc" class, which is defined by the C++ |
1002 | /// standard library. |
1003 | LazyDeclPtr StdBadAlloc; |
1004 | |
1005 | /// The C++ "std::align_val_t" enum class, which is defined by the C++ |
1006 | /// standard library. |
1007 | LazyDeclPtr StdAlignValT; |
1008 | |
1009 | /// The C++ "std::experimental" namespace, where the experimental parts |
1010 | /// of the standard library resides. |
1011 | NamespaceDecl *StdExperimentalNamespaceCache; |
1012 | |
1013 | /// The C++ "std::initializer_list" template, which is defined in |
1014 | /// \<initializer_list>. |
1015 | ClassTemplateDecl *StdInitializerList; |
1016 | |
1017 | /// The C++ "std::coroutine_traits" template, which is defined in |
1018 | /// \<coroutine_traits> |
1019 | ClassTemplateDecl *StdCoroutineTraitsCache; |
1020 | |
1021 | /// The C++ "type_info" declaration, which is defined in \<typeinfo>. |
1022 | RecordDecl *CXXTypeInfoDecl; |
1023 | |
1024 | /// The MSVC "_GUID" struct, which is defined in MSVC header files. |
1025 | RecordDecl *MSVCGuidDecl; |
1026 | |
1027 | /// Caches identifiers/selectors for NSFoundation APIs. |
1028 | std::unique_ptr<NSAPI> NSAPIObj; |
1029 | |
1030 | /// The declaration of the Objective-C NSNumber class. |
1031 | ObjCInterfaceDecl *NSNumberDecl; |
1032 | |
1033 | /// The declaration of the Objective-C NSValue class. |
1034 | ObjCInterfaceDecl *NSValueDecl; |
1035 | |
1036 | /// Pointer to NSNumber type (NSNumber *). |
1037 | QualType NSNumberPointer; |
1038 | |
1039 | /// Pointer to NSValue type (NSValue *). |
1040 | QualType NSValuePointer; |
1041 | |
1042 | /// The Objective-C NSNumber methods used to create NSNumber literals. |
1043 | ObjCMethodDecl *NSNumberLiteralMethods[NSAPI::NumNSNumberLiteralMethods]; |
1044 | |
1045 | /// The declaration of the Objective-C NSString class. |
1046 | ObjCInterfaceDecl *NSStringDecl; |
1047 | |
1048 | /// Pointer to NSString type (NSString *). |
1049 | QualType NSStringPointer; |
1050 | |
1051 | /// The declaration of the stringWithUTF8String: method. |
1052 | ObjCMethodDecl *StringWithUTF8StringMethod; |
1053 | |
1054 | /// The declaration of the valueWithBytes:objCType: method. |
1055 | ObjCMethodDecl *ValueWithBytesObjCTypeMethod; |
1056 | |
1057 | /// The declaration of the Objective-C NSArray class. |
1058 | ObjCInterfaceDecl *NSArrayDecl; |
1059 | |
1060 | /// The declaration of the arrayWithObjects:count: method. |
1061 | ObjCMethodDecl *ArrayWithObjectsMethod; |
1062 | |
1063 | /// The declaration of the Objective-C NSDictionary class. |
1064 | ObjCInterfaceDecl *NSDictionaryDecl; |
1065 | |
1066 | /// The declaration of the dictionaryWithObjects:forKeys:count: method. |
1067 | ObjCMethodDecl *DictionaryWithObjectsMethod; |
1068 | |
1069 | /// id<NSCopying> type. |
1070 | QualType QIDNSCopying; |
1071 | |
1072 | /// will hold 'respondsToSelector:' |
1073 | Selector RespondsToSelectorSel; |
1074 | |
1075 | /// A flag to remember whether the implicit forms of operator new and delete |
1076 | /// have been declared. |
1077 | bool GlobalNewDeleteDeclared; |
1078 | |
1079 | /// A flag to indicate that we're in a context that permits abstract |
1080 | /// references to fields. This is really a |
1081 | bool AllowAbstractFieldReference; |
1082 | |
1083 | /// Describes how the expressions currently being parsed are |
1084 | /// evaluated at run-time, if at all. |
1085 | enum class ExpressionEvaluationContext { |
1086 | /// The current expression and its subexpressions occur within an |
1087 | /// unevaluated operand (C++11 [expr]p7), such as the subexpression of |
1088 | /// \c sizeof, where the type of the expression may be significant but |
1089 | /// no code will be generated to evaluate the value of the expression at |
1090 | /// run time. |
1091 | Unevaluated, |
1092 | |
1093 | /// The current expression occurs within a braced-init-list within |
1094 | /// an unevaluated operand. This is mostly like a regular unevaluated |
1095 | /// context, except that we still instantiate constexpr functions that are |
1096 | /// referenced here so that we can perform narrowing checks correctly. |
1097 | UnevaluatedList, |
1098 | |
1099 | /// The current expression occurs within a discarded statement. |
1100 | /// This behaves largely similarly to an unevaluated operand in preventing |
1101 | /// definitions from being required, but not in other ways. |
1102 | DiscardedStatement, |
1103 | |
1104 | /// The current expression occurs within an unevaluated |
1105 | /// operand that unconditionally permits abstract references to |
1106 | /// fields, such as a SIZE operator in MS-style inline assembly. |
1107 | UnevaluatedAbstract, |
1108 | |
1109 | /// The current context is "potentially evaluated" in C++11 terms, |
1110 | /// but the expression is evaluated at compile-time (like the values of |
1111 | /// cases in a switch statement). |
1112 | ConstantEvaluated, |
1113 | |
1114 | /// The current expression is potentially evaluated at run time, |
1115 | /// which means that code may be generated to evaluate the value of the |
1116 | /// expression at run time. |
1117 | PotentiallyEvaluated, |
1118 | |
1119 | /// The current expression is potentially evaluated, but any |
1120 | /// declarations referenced inside that expression are only used if |
1121 | /// in fact the current expression is used. |
1122 | /// |
1123 | /// This value is used when parsing default function arguments, for which |
1124 | /// we would like to provide diagnostics (e.g., passing non-POD arguments |
1125 | /// through varargs) but do not want to mark declarations as "referenced" |
1126 | /// until the default argument is used. |
1127 | PotentiallyEvaluatedIfUsed |
1128 | }; |
1129 | |
1130 | using ImmediateInvocationCandidate = llvm::PointerIntPair<ConstantExpr *, 1>; |
1131 | |
1132 | /// Data structure used to record current or nested |
1133 | /// expression evaluation contexts. |
1134 | struct ExpressionEvaluationContextRecord { |
1135 | /// The expression evaluation context. |
1136 | ExpressionEvaluationContext Context; |
1137 | |
1138 | /// Whether the enclosing context needed a cleanup. |
1139 | CleanupInfo ParentCleanup; |
1140 | |
1141 | /// Whether we are in a decltype expression. |
1142 | bool IsDecltype; |
1143 | |
1144 | /// The number of active cleanup objects when we entered |
1145 | /// this expression evaluation context. |
1146 | unsigned NumCleanupObjects; |
1147 | |
1148 | /// The number of typos encountered during this expression evaluation |
1149 | /// context (i.e. the number of TypoExprs created). |
1150 | unsigned NumTypos; |
1151 | |
1152 | MaybeODRUseExprSet SavedMaybeODRUseExprs; |
1153 | |
1154 | /// The lambdas that are present within this context, if it |
1155 | /// is indeed an unevaluated context. |
1156 | SmallVector<LambdaExpr *, 2> Lambdas; |
1157 | |
1158 | /// The declaration that provides context for lambda expressions |
1159 | /// and block literals if the normal declaration context does not |
1160 | /// suffice, e.g., in a default function argument. |
1161 | Decl *ManglingContextDecl; |
1162 | |
1163 | /// If we are processing a decltype type, a set of call expressions |
1164 | /// for which we have deferred checking the completeness of the return type. |
1165 | SmallVector<CallExpr *, 8> DelayedDecltypeCalls; |
1166 | |
1167 | /// If we are processing a decltype type, a set of temporary binding |
1168 | /// expressions for which we have deferred checking the destructor. |
1169 | SmallVector<CXXBindTemporaryExpr *, 8> DelayedDecltypeBinds; |
1170 | |
1171 | llvm::SmallPtrSet<const Expr *, 8> PossibleDerefs; |
1172 | |
1173 | /// Expressions appearing as the LHS of a volatile assignment in this |
1174 | /// context. We produce a warning for these when popping the context if |
1175 | /// they are not discarded-value expressions nor unevaluated operands. |
1176 | SmallVector<Expr*, 2> VolatileAssignmentLHSs; |
1177 | |
1178 | /// Set of candidates for starting an immediate invocation. |
1179 | llvm::SmallVector<ImmediateInvocationCandidate, 4> ImmediateInvocationCandidates; |
1180 | |
1181 | /// Set of DeclRefExprs referencing a consteval function when used in a |
1182 | /// context not already known to be immediately invoked. |
1183 | llvm::SmallPtrSet<DeclRefExpr *, 4> ReferenceToConsteval; |
1184 | |
1185 | /// \brief Describes whether we are in an expression constext which we have |
1186 | /// to handle differently. |
1187 | enum ExpressionKind { |
1188 | EK_Decltype, EK_TemplateArgument, EK_Other |
1189 | } ExprContext; |
1190 | |
1191 | ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context, |
1192 | unsigned NumCleanupObjects, |
1193 | CleanupInfo ParentCleanup, |
1194 | Decl *ManglingContextDecl, |
1195 | ExpressionKind ExprContext) |
1196 | : Context(Context), ParentCleanup(ParentCleanup), |
1197 | NumCleanupObjects(NumCleanupObjects), NumTypos(0), |
1198 | ManglingContextDecl(ManglingContextDecl), ExprContext(ExprContext) {} |
1199 | |
1200 | bool isUnevaluated() const { |
1201 | return Context == ExpressionEvaluationContext::Unevaluated || |
1202 | Context == ExpressionEvaluationContext::UnevaluatedAbstract || |
1203 | Context == ExpressionEvaluationContext::UnevaluatedList; |
1204 | } |
1205 | bool isConstantEvaluated() const { |
1206 | return Context == ExpressionEvaluationContext::ConstantEvaluated; |
1207 | } |
1208 | }; |
1209 | |
1210 | /// A stack of expression evaluation contexts. |
1211 | SmallVector<ExpressionEvaluationContextRecord, 8> ExprEvalContexts; |
1212 | |
1213 | /// Emit a warning for all pending noderef expressions that we recorded. |
1214 | void WarnOnPendingNoDerefs(ExpressionEvaluationContextRecord &Rec); |
1215 | |
1216 | /// Compute the mangling number context for a lambda expression or |
1217 | /// block literal. Also return the extra mangling decl if any. |
1218 | /// |
1219 | /// \param DC - The DeclContext containing the lambda expression or |
1220 | /// block literal. |
1221 | std::tuple<MangleNumberingContext *, Decl *> |
1222 | getCurrentMangleNumberContext(const DeclContext *DC); |
1223 | |
1224 | |
1225 | /// SpecialMemberOverloadResult - The overloading result for a special member |
1226 | /// function. |
1227 | /// |
1228 | /// This is basically a wrapper around PointerIntPair. The lowest bits of the |
1229 | /// integer are used to determine whether overload resolution succeeded. |
1230 | class SpecialMemberOverloadResult { |
1231 | public: |
1232 | enum Kind { |
1233 | NoMemberOrDeleted, |
1234 | Ambiguous, |
1235 | Success |
1236 | }; |
1237 | |
1238 | private: |
1239 | llvm::PointerIntPair<CXXMethodDecl*, 2> Pair; |
1240 | |
1241 | public: |
1242 | SpecialMemberOverloadResult() : Pair() {} |
1243 | SpecialMemberOverloadResult(CXXMethodDecl *MD) |
1244 | : Pair(MD, MD->isDeleted() ? NoMemberOrDeleted : Success) {} |
1245 | |
1246 | CXXMethodDecl *getMethod() const { return Pair.getPointer(); } |
1247 | void setMethod(CXXMethodDecl *MD) { Pair.setPointer(MD); } |
1248 | |
1249 | Kind getKind() const { return static_cast<Kind>(Pair.getInt()); } |
1250 | void setKind(Kind K) { Pair.setInt(K); } |
1251 | }; |
1252 | |
1253 | class SpecialMemberOverloadResultEntry |
1254 | : public llvm::FastFoldingSetNode, |
1255 | public SpecialMemberOverloadResult { |
1256 | public: |
1257 | SpecialMemberOverloadResultEntry(const llvm::FoldingSetNodeID &ID) |
1258 | : FastFoldingSetNode(ID) |
1259 | {} |
1260 | }; |
1261 | |
1262 | /// A cache of special member function overload resolution results |
1263 | /// for C++ records. |
1264 | llvm::FoldingSet<SpecialMemberOverloadResultEntry> SpecialMemberCache; |
1265 | |
1266 | /// A cache of the flags available in enumerations with the flag_bits |
1267 | /// attribute. |
1268 | mutable llvm::DenseMap<const EnumDecl*, llvm::APInt> FlagBitsCache; |
1269 | |
1270 | /// The kind of translation unit we are processing. |
1271 | /// |
1272 | /// When we're processing a complete translation unit, Sema will perform |
1273 | /// end-of-translation-unit semantic tasks (such as creating |
1274 | /// initializers for tentative definitions in C) once parsing has |
1275 | /// completed. Modules and precompiled headers perform different kinds of |
1276 | /// checks. |
1277 | TranslationUnitKind TUKind; |
1278 | |
1279 | llvm::BumpPtrAllocator BumpAlloc; |
1280 | |
1281 | /// The number of SFINAE diagnostics that have been trapped. |
1282 | unsigned NumSFINAEErrors; |
1283 | |
1284 | typedef llvm::DenseMap<ParmVarDecl *, llvm::TinyPtrVector<ParmVarDecl *>> |
1285 | UnparsedDefaultArgInstantiationsMap; |
1286 | |
1287 | /// A mapping from parameters with unparsed default arguments to the |
1288 | /// set of instantiations of each parameter. |
1289 | /// |
1290 | /// This mapping is a temporary data structure used when parsing |
1291 | /// nested class templates or nested classes of class templates, |
1292 | /// where we might end up instantiating an inner class before the |
1293 | /// default arguments of its methods have been parsed. |
1294 | UnparsedDefaultArgInstantiationsMap UnparsedDefaultArgInstantiations; |
1295 | |
1296 | // Contains the locations of the beginning of unparsed default |
1297 | // argument locations. |
1298 | llvm::DenseMap<ParmVarDecl *, SourceLocation> UnparsedDefaultArgLocs; |
1299 | |
1300 | /// UndefinedInternals - all the used, undefined objects which require a |
1301 | /// definition in this translation unit. |
1302 | llvm::MapVector<NamedDecl *, SourceLocation> UndefinedButUsed; |
1303 | |
1304 | /// Determine if VD, which must be a variable or function, is an external |
1305 | /// symbol that nonetheless can't be referenced from outside this translation |
1306 | /// unit because its type has no linkage and it's not extern "C". |
1307 | bool isExternalWithNoLinkageType(ValueDecl *VD); |
1308 | |
1309 | /// Obtain a sorted list of functions that are undefined but ODR-used. |
1310 | void getUndefinedButUsed( |
1311 | SmallVectorImpl<std::pair<NamedDecl *, SourceLocation> > &Undefined); |
1312 | |
1313 | /// Retrieves list of suspicious delete-expressions that will be checked at |
1314 | /// the end of translation unit. |
1315 | const llvm::MapVector<FieldDecl *, DeleteLocs> & |
1316 | getMismatchingDeleteExpressions() const; |
1317 | |
1318 | typedef std::pair<ObjCMethodList, ObjCMethodList> GlobalMethods; |
1319 | typedef llvm::DenseMap<Selector, GlobalMethods> GlobalMethodPool; |
1320 | |
1321 | /// Method Pool - allows efficient lookup when typechecking messages to "id". |
1322 | /// We need to maintain a list, since selectors can have differing signatures |
1323 | /// across classes. In Cocoa, this happens to be extremely uncommon (only 1% |
1324 | /// of selectors are "overloaded"). |
1325 | /// At the head of the list it is recorded whether there were 0, 1, or >= 2 |
1326 | /// methods inside categories with a particular selector. |
1327 | GlobalMethodPool MethodPool; |
1328 | |
1329 | /// Method selectors used in a \@selector expression. Used for implementation |
1330 | /// of -Wselector. |
1331 | llvm::MapVector<Selector, SourceLocation> ReferencedSelectors; |
1332 | |
1333 | /// List of SourceLocations where 'self' is implicitly retained inside a |
1334 | /// block. |
1335 | llvm::SmallVector<std::pair<SourceLocation, const BlockDecl *>, 1> |
1336 | ImplicitlyRetainedSelfLocs; |
1337 | |
1338 | /// Kinds of C++ special members. |
1339 | enum CXXSpecialMember { |
1340 | CXXDefaultConstructor, |
1341 | CXXCopyConstructor, |
1342 | CXXMoveConstructor, |
1343 | CXXCopyAssignment, |
1344 | CXXMoveAssignment, |
1345 | CXXDestructor, |
1346 | CXXInvalid |
1347 | }; |
1348 | |
1349 | typedef llvm::PointerIntPair<CXXRecordDecl *, 3, CXXSpecialMember> |
1350 | SpecialMemberDecl; |
1351 | |
1352 | /// The C++ special members which we are currently in the process of |
1353 | /// declaring. If this process recursively triggers the declaration of the |
1354 | /// same special member, we should act as if it is not yet declared. |
1355 | llvm::SmallPtrSet<SpecialMemberDecl, 4> SpecialMembersBeingDeclared; |
1356 | |
1357 | /// Kinds of defaulted comparison operator functions. |
1358 | enum class DefaultedComparisonKind : unsigned char { |
1359 | /// This is not a defaultable comparison operator. |
1360 | None, |
1361 | /// This is an operator== that should be implemented as a series of |
1362 | /// subobject comparisons. |
1363 | Equal, |
1364 | /// This is an operator<=> that should be implemented as a series of |
1365 | /// subobject comparisons. |
1366 | ThreeWay, |
1367 | /// This is an operator!= that should be implemented as a rewrite in terms |
1368 | /// of a == comparison. |
1369 | NotEqual, |
1370 | /// This is an <, <=, >, or >= that should be implemented as a rewrite in |
1371 | /// terms of a <=> comparison. |
1372 | Relational, |
1373 | }; |
1374 | |
1375 | /// The function definitions which were renamed as part of typo-correction |
1376 | /// to match their respective declarations. We want to keep track of them |
1377 | /// to ensure that we don't emit a "redefinition" error if we encounter a |
1378 | /// correctly named definition after the renamed definition. |
1379 | llvm::SmallPtrSet<const NamedDecl *, 4> TypoCorrectedFunctionDefinitions; |
1380 | |
1381 | /// Stack of types that correspond to the parameter entities that are |
1382 | /// currently being copy-initialized. Can be empty. |
1383 | llvm::SmallVector<QualType, 4> CurrentParameterCopyTypes; |
1384 | |
1385 | void ReadMethodPool(Selector Sel); |
1386 | void updateOutOfDateSelector(Selector Sel); |
1387 | |
1388 | /// Private Helper predicate to check for 'self'. |
1389 | bool isSelfExpr(Expr *RExpr); |
1390 | bool isSelfExpr(Expr *RExpr, const ObjCMethodDecl *Method); |
1391 | |
1392 | /// Cause the active diagnostic on the DiagosticsEngine to be |
1393 | /// emitted. This is closely coupled to the SemaDiagnosticBuilder class and |
1394 | /// should not be used elsewhere. |
1395 | void EmitCurrentDiagnostic(unsigned DiagID); |
1396 | |
1397 | /// Records and restores the CurFPFeatures state on entry/exit of compound |
1398 | /// statements. |
1399 | class FPFeaturesStateRAII { |
1400 | public: |
1401 | FPFeaturesStateRAII(Sema &S) : S(S), OldFPFeaturesState(S.CurFPFeatures) { |
1402 | OldOverrides = S.FpPragmaStack.CurrentValue; |
1403 | } |
1404 | ~FPFeaturesStateRAII() { |
1405 | S.CurFPFeatures = OldFPFeaturesState; |
1406 | S.FpPragmaStack.CurrentValue = OldOverrides; |
1407 | } |
1408 | FPOptionsOverride getOverrides() { return OldOverrides; } |
1409 | |
1410 | private: |
1411 | Sema& S; |
1412 | FPOptions OldFPFeaturesState; |
1413 | FPOptionsOverride OldOverrides; |
1414 | }; |
1415 | |
1416 | void addImplicitTypedef(StringRef Name, QualType T); |
1417 | |
1418 | bool WarnedStackExhausted = false; |
1419 | |
1420 | public: |
1421 | Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, |
1422 | TranslationUnitKind TUKind = TU_Complete, |
1423 | CodeCompleteConsumer *CompletionConsumer = nullptr); |
1424 | ~Sema(); |
1425 | |
1426 | /// Perform initialization that occurs after the parser has been |
1427 | /// initialized but before it parses anything. |
1428 | void Initialize(); |
1429 | |
1430 | const LangOptions &getLangOpts() const { return LangOpts; } |
1431 | OpenCLOptions &getOpenCLOptions() { return OpenCLFeatures; } |
1432 | FPOptions &getCurFPFeatures() { return CurFPFeatures; } |
1433 | |
1434 | DiagnosticsEngine &getDiagnostics() const { return Diags; } |
1435 | SourceManager &getSourceManager() const { return SourceMgr; } |
1436 | Preprocessor &getPreprocessor() const { return PP; } |
1437 | ASTContext &getASTContext() const { return Context; } |
1438 | ASTConsumer &getASTConsumer() const { return Consumer; } |
1439 | ASTMutationListener *getASTMutationListener() const; |
1440 | ExternalSemaSource* getExternalSource() const { return ExternalSource; } |
1441 | |
1442 | ///Registers an external source. If an external source already exists, |
1443 | /// creates a multiplex external source and appends to it. |
1444 | /// |
1445 | ///\param[in] E - A non-null external sema source. |
1446 | /// |
1447 | void addExternalSource(ExternalSemaSource *E); |
1448 | |
1449 | void PrintStats() const; |
1450 | |
1451 | /// Warn that the stack is nearly exhausted. |
1452 | void warnStackExhausted(SourceLocation Loc); |
1453 | |
1454 | /// Run some code with "sufficient" stack space. (Currently, at least 256K is |
1455 | /// guaranteed). Produces a warning if we're low on stack space and allocates |
1456 | /// more in that case. Use this in code that may recurse deeply (for example, |
1457 | /// in template instantiation) to avoid stack overflow. |
1458 | void runWithSufficientStackSpace(SourceLocation Loc, |
1459 | llvm::function_ref<void()> Fn); |
1460 | |
1461 | /// Helper class that creates diagnostics with optional |
1462 | /// template instantiation stacks. |
1463 | /// |
1464 | /// This class provides a wrapper around the basic DiagnosticBuilder |
1465 | /// class that emits diagnostics. SemaDiagnosticBuilder is |
1466 | /// responsible for emitting the diagnostic (as DiagnosticBuilder |
1467 | /// does) and, if the diagnostic comes from inside a template |
1468 | /// instantiation, printing the template instantiation stack as |
1469 | /// well. |
1470 | class SemaDiagnosticBuilder : public DiagnosticBuilder { |
1471 | Sema &SemaRef; |
1472 | unsigned DiagID; |
1473 | |
1474 | public: |
1475 | SemaDiagnosticBuilder(DiagnosticBuilder &DB, Sema &SemaRef, unsigned DiagID) |
1476 | : DiagnosticBuilder(DB), SemaRef(SemaRef), DiagID(DiagID) { } |
1477 | |
1478 | // This is a cunning lie. DiagnosticBuilder actually performs move |
1479 | // construction in its copy constructor (but due to varied uses, it's not |
1480 | // possible to conveniently express this as actual move construction). So |
1481 | // the default copy ctor here is fine, because the base class disables the |
1482 | // source anyway, so the user-defined ~SemaDiagnosticBuilder is a safe no-op |
1483 | // in that case anwyay. |
1484 | SemaDiagnosticBuilder(const SemaDiagnosticBuilder&) = default; |
1485 | |
1486 | ~SemaDiagnosticBuilder() { |
1487 | // If we aren't active, there is nothing to do. |
1488 | if (!isActive()) return; |
1489 | |
1490 | // Otherwise, we need to emit the diagnostic. First flush the underlying |
1491 | // DiagnosticBuilder data, and clear the diagnostic builder itself so it |
1492 | // won't emit the diagnostic in its own destructor. |
1493 | // |
1494 | // This seems wasteful, in that as written the DiagnosticBuilder dtor will |
1495 | // do its own needless checks to see if the diagnostic needs to be |
1496 | // emitted. However, because we take care to ensure that the builder |
1497 | // objects never escape, a sufficiently smart compiler will be able to |
1498 | // eliminate that code. |
1499 | FlushCounts(); |
1500 | Clear(); |
1501 | |
1502 | // Dispatch to Sema to emit the diagnostic. |
1503 | SemaRef.EmitCurrentDiagnostic(DiagID); |
1504 | } |
1505 | |
1506 | /// Teach operator<< to produce an object of the correct type. |
1507 | template<typename T> |
1508 | friend const SemaDiagnosticBuilder &operator<<( |
1509 | const SemaDiagnosticBuilder &Diag, const T &Value) { |
1510 | const DiagnosticBuilder &BaseDiag = Diag; |
1511 | BaseDiag << Value; |
1512 | return Diag; |
1513 | } |
1514 | }; |
1515 | |
1516 | /// Emit a diagnostic. |
1517 | SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) { |
1518 | DiagnosticBuilder DB = Diags.Report(Loc, DiagID); |
1519 | return SemaDiagnosticBuilder(DB, *this, DiagID); |
1520 | } |
1521 | |
1522 | /// Emit a partial diagnostic. |
1523 | SemaDiagnosticBuilder Diag(SourceLocation Loc, const PartialDiagnostic& PD); |
1524 | |
1525 | /// Build a partial diagnostic. |
1526 | PartialDiagnostic PDiag(unsigned DiagID = 0); // in SemaInternal.h |
1527 | |
1528 | bool findMacroSpelling(SourceLocation &loc, StringRef name); |
1529 | |
1530 | /// Get a string to suggest for zero-initialization of a type. |
1531 | std::string |
1532 | getFixItZeroInitializerForType(QualType T, SourceLocation Loc) const; |
1533 | std::string getFixItZeroLiteralForType(QualType T, SourceLocation Loc) const; |
1534 | |
1535 | /// Calls \c Lexer::getLocForEndOfToken() |
1536 | SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset = 0); |
1537 | |
1538 | /// Retrieve the module loader associated with the preprocessor. |
1539 | ModuleLoader &getModuleLoader() const; |
1540 | |
1541 | /// Invent a new identifier for parameters of abbreviated templates. |
1542 | IdentifierInfo * |
1543 | InventAbbreviatedTemplateParameterTypeName(IdentifierInfo *ParamName, |
1544 | unsigned Index); |
1545 | |
1546 | void emitAndClearUnusedLocalTypedefWarnings(); |
1547 | |
1548 | private: |
1549 | /// Function or variable declarations to be checked for whether the deferred |
1550 | /// diagnostics should be emitted. |
1551 | SmallVector<Decl *, 4> DeclsToCheckForDeferredDiags; |
1552 | |
1553 | public: |
1554 | // Emit all deferred diagnostics. |
1555 | void emitDeferredDiags(); |
1556 | |
1557 | enum TUFragmentKind { |
1558 | /// The global module fragment, between 'module;' and a module-declaration. |
1559 | Global, |
1560 | /// A normal translation unit fragment. For a non-module unit, this is the |
1561 | /// entire translation unit. Otherwise, it runs from the module-declaration |
1562 | /// to the private-module-fragment (if any) or the end of the TU (if not). |
1563 | Normal, |
1564 | /// The private module fragment, between 'module :private;' and the end of |
1565 | /// the translation unit. |
1566 | Private |
1567 | }; |
1568 | |
1569 | void ActOnStartOfTranslationUnit(); |
1570 | void ActOnEndOfTranslationUnit(); |
1571 | void ActOnEndOfTranslationUnitFragment(TUFragmentKind Kind); |
1572 | |
1573 | void CheckDelegatingCtorCycles(); |
1574 | |
1575 | Scope *getScopeForContext(DeclContext *Ctx); |
1576 | |
1577 | void PushFunctionScope(); |
1578 | void PushBlockScope(Scope *BlockScope, BlockDecl *Block); |
1579 | sema::LambdaScopeInfo *PushLambdaScope(); |
1580 | |
1581 | /// This is used to inform Sema what the current TemplateParameterDepth |
1582 | /// is during Parsing. Currently it is used to pass on the depth |
1583 | /// when parsing generic lambda 'auto' parameters. |
1584 | void RecordParsingTemplateParameterDepth(unsigned Depth); |
1585 | |
1586 | void PushCapturedRegionScope(Scope *RegionScope, CapturedDecl *CD, |
1587 | RecordDecl *RD, CapturedRegionKind K, |
1588 | unsigned OpenMPCaptureLevel = 0); |
1589 | |
1590 | /// Custom deleter to allow FunctionScopeInfos to be kept alive for a short |
1591 | /// time after they've been popped. |
1592 | class PoppedFunctionScopeDeleter { |
1593 | Sema *Self; |
1594 | |
1595 | public: |
1596 | explicit PoppedFunctionScopeDeleter(Sema *Self) : Self(Self) {} |
1597 | void operator()(sema::FunctionScopeInfo *Scope) const; |
1598 | }; |
1599 | |
1600 | using PoppedFunctionScopePtr = |
1601 | std::unique_ptr<sema::FunctionScopeInfo, PoppedFunctionScopeDeleter>; |
1602 | |
1603 | PoppedFunctionScopePtr |
1604 | PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP = nullptr, |
1605 | const Decl *D = nullptr, |
1606 | QualType BlockType = QualType()); |
1607 | |
1608 | sema::FunctionScopeInfo *getCurFunction() const { |
1609 | return FunctionScopes.empty() ? nullptr : FunctionScopes.back(); |
1610 | } |
1611 | |
1612 | sema::FunctionScopeInfo *getEnclosingFunction() const; |
1613 | |
1614 | void setFunctionHasBranchIntoScope(); |
1615 | void setFunctionHasBranchProtectedScope(); |
1616 | void setFunctionHasIndirectGoto(); |
1617 | |
1618 | void PushCompoundScope(bool IsStmtExpr); |
1619 | void PopCompoundScope(); |
1620 | |
1621 | sema::CompoundScopeInfo &getCurCompoundScope() const; |
1622 | |
1623 | bool hasAnyUnrecoverableErrorsInThisFunction() const; |
1624 | |
1625 | /// Retrieve the current block, if any. |
1626 | sema::BlockScopeInfo *getCurBlock(); |
1627 | |
1628 | /// Get the innermost lambda enclosing the current location, if any. This |
1629 | /// looks through intervening non-lambda scopes such as local functions and |
1630 | /// blocks. |
1631 | sema::LambdaScopeInfo *getEnclosingLambda() const; |
1632 | |
1633 | /// Retrieve the current lambda scope info, if any. |
1634 | /// \param IgnoreNonLambdaCapturingScope true if should find the top-most |
1635 | /// lambda scope info ignoring all inner capturing scopes that are not |
1636 | /// lambda scopes. |
1637 | sema::LambdaScopeInfo * |
1638 | getCurLambda(bool IgnoreNonLambdaCapturingScope = false); |
1639 | |
1640 | /// Retrieve the current generic lambda info, if any. |
1641 | sema::LambdaScopeInfo *getCurGenericLambda(); |
1642 | |
1643 | /// Retrieve the current captured region, if any. |
1644 | sema::CapturedRegionScopeInfo *getCurCapturedRegion(); |
1645 | |
1646 | /// WeakTopLevelDeclDecls - access to \#pragma weak-generated Decls |
1647 | SmallVectorImpl<Decl *> &WeakTopLevelDecls() { return WeakTopLevelDecl; } |
1648 | |
1649 | /// Called before parsing a function declarator belonging to a function |
1650 | /// declaration. |
1651 | void ActOnStartFunctionDeclarationDeclarator(Declarator &D, |
1652 | unsigned TemplateParameterDepth); |
1653 | |
1654 | /// Called after parsing a function declarator belonging to a function |
1655 | /// declaration. |
1656 | void ActOnFinishFunctionDeclarationDeclarator(Declarator &D); |
1657 | |
1658 | void ActOnComment(SourceRange Comment); |
1659 | |
1660 | //===--------------------------------------------------------------------===// |
1661 | // Type Analysis / Processing: SemaType.cpp. |
1662 | // |
1663 | |
1664 | QualType BuildQualifiedType(QualType T, SourceLocation Loc, Qualifiers Qs, |
1665 | const DeclSpec *DS = nullptr); |
1666 | QualType BuildQualifiedType(QualType T, SourceLocation Loc, unsigned CVRA, |
1667 | const DeclSpec *DS = nullptr); |
1668 | QualType BuildPointerType(QualType T, |
1669 | SourceLocation Loc, DeclarationName Entity); |
1670 | QualType BuildReferenceType(QualType T, bool LValueRef, |
1671 | SourceLocation Loc, DeclarationName Entity); |
1672 | QualType BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM, |
1673 | Expr *ArraySize, unsigned Quals, |
1674 | SourceRange Brackets, DeclarationName Entity); |
1675 | QualType BuildVectorType(QualType T, Expr *VecSize, SourceLocation AttrLoc); |
1676 | QualType BuildExtVectorType(QualType T, Expr *ArraySize, |
1677 | SourceLocation AttrLoc); |
1678 | QualType BuildMatrixType(QualType T, Expr *NumRows, Expr *NumColumns, |
1679 | SourceLocation AttrLoc); |
1680 | |
1681 | QualType BuildAddressSpaceAttr(QualType &T, LangAS ASIdx, Expr *AddrSpace, |
1682 | SourceLocation AttrLoc); |
1683 | |
1684 | /// Same as above, but constructs the AddressSpace index if not provided. |
1685 | QualType BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace, |
1686 | SourceLocation AttrLoc); |
1687 | |
1688 | bool CheckQualifiedFunctionForTypeId(QualType T, SourceLocation Loc); |
1689 | |
1690 | bool CheckFunctionReturnType(QualType T, SourceLocation Loc); |
1691 | |
1692 | /// Build a function type. |
1693 | /// |
1694 | /// This routine checks the function type according to C++ rules and |
1695 | /// under the assumption that the result type and parameter types have |
1696 | /// just been instantiated from a template. It therefore duplicates |
1697 | /// some of the behavior of GetTypeForDeclarator, but in a much |
1698 | /// simpler form that is only suitable for this narrow use case. |
1699 | /// |
1700 | /// \param T The return type of the function. |
1701 | /// |
1702 | /// \param ParamTypes The parameter types of the function. This array |
1703 | /// will be modified to account for adjustments to the types of the |
1704 | /// function parameters. |
1705 | /// |
1706 | /// \param Loc The location of the entity whose type involves this |
1707 | /// function type or, if there is no such entity, the location of the |
1708 | /// type that will have function type. |
1709 | /// |
1710 | /// \param Entity The name of the entity that involves the function |
1711 | /// type, if known. |
1712 | /// |
1713 | /// \param EPI Extra information about the function type. Usually this will |
1714 | /// be taken from an existing function with the same prototype. |
1715 | /// |
1716 | /// \returns A suitable function type, if there are no errors. The |
1717 | /// unqualified type will always be a FunctionProtoType. |
1718 | /// Otherwise, returns a NULL type. |
1719 | QualType BuildFunctionType(QualType T, |
1720 | MutableArrayRef<QualType> ParamTypes, |
1721 | SourceLocation Loc, DeclarationName Entity, |
1722 | const FunctionProtoType::ExtProtoInfo &EPI); |
1723 | |
1724 | QualType BuildMemberPointerType(QualType T, QualType Class, |
1725 | SourceLocation Loc, |
1726 | DeclarationName Entity); |
1727 | QualType BuildBlockPointerType(QualType T, |
1728 | SourceLocation Loc, DeclarationName Entity); |
1729 | QualType BuildParenType(QualType T); |
1730 | QualType BuildAtomicType(QualType T, SourceLocation Loc); |
1731 | QualType BuildReadPipeType(QualType T, |
1732 | SourceLocation Loc); |
1733 | QualType BuildWritePipeType(QualType T, |
1734 | SourceLocation Loc); |
1735 | QualType BuildExtIntType(bool IsUnsigned, Expr *BitWidth, SourceLocation Loc); |
1736 | |
1737 | TypeSourceInfo *GetTypeForDeclarator(Declarator &D, Scope *S); |
1738 | TypeSourceInfo *GetTypeForDeclaratorCast(Declarator &D, QualType FromTy); |
1739 | |
1740 | /// Package the given type and TSI into a ParsedType. |
1741 | ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo); |
1742 | DeclarationNameInfo GetNameForDeclarator(Declarator &D); |
1743 | DeclarationNameInfo GetNameFromUnqualifiedId(const UnqualifiedId &Name); |
1744 | static QualType GetTypeFromParser(ParsedType Ty, |
1745 | TypeSourceInfo **TInfo = nullptr); |
1746 | CanThrowResult canThrow(const Stmt *E); |
1747 | /// Determine whether the callee of a particular function call can throw. |
1748 | /// E, D and Loc are all optional. |
1749 | static CanThrowResult canCalleeThrow(Sema &S, const Expr *E, const Decl *D, |
1750 | SourceLocation Loc = SourceLocation()); |
1751 | const FunctionProtoType *ResolveExceptionSpec(SourceLocation Loc, |
1752 | const FunctionProtoType *FPT); |
1753 | void UpdateExceptionSpec(FunctionDecl *FD, |
1754 | const FunctionProtoType::ExceptionSpecInfo &ESI); |
1755 | bool CheckSpecifiedExceptionType(QualType &T, SourceRange Range); |
1756 | bool CheckDistantExceptionSpec(QualType T); |
1757 | bool CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New); |
1758 | bool CheckEquivalentExceptionSpec( |
1759 | const FunctionProtoType *Old, SourceLocation OldLoc, |
1760 | const FunctionProtoType *New, SourceLocation NewLoc); |
1761 | bool CheckEquivalentExceptionSpec( |
1762 | const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID, |
1763 | const FunctionProtoType *Old, SourceLocation OldLoc, |
1764 | const FunctionProtoType *New, SourceLocation NewLoc); |
1765 | bool handlerCanCatch(QualType HandlerType, QualType ExceptionType); |
1766 | bool CheckExceptionSpecSubset(const PartialDiagnostic &DiagID, |
1767 | const PartialDiagnostic &NestedDiagID, |
1768 | const PartialDiagnostic &NoteID, |
1769 | const PartialDiagnostic &NoThrowDiagID, |
1770 | const FunctionProtoType *Superset, |
1771 | SourceLocation SuperLoc, |
1772 | const FunctionProtoType *Subset, |
1773 | SourceLocation SubLoc); |
1774 | bool CheckParamExceptionSpec(const PartialDiagnostic &NestedDiagID, |
1775 | const PartialDiagnostic &NoteID, |
1776 | const FunctionProtoType *Target, |
1777 | SourceLocation TargetLoc, |
1778 | const FunctionProtoType *Source, |
1779 | SourceLocation SourceLoc); |
1780 | |
1781 | TypeResult ActOnTypeName(Scope *S, Declarator &D); |
1782 | |
1783 | /// The parser has parsed the context-sensitive type 'instancetype' |
1784 | /// in an Objective-C message declaration. Return the appropriate type. |
1785 | ParsedType ActOnObjCInstanceType(SourceLocation Loc); |
1786 | |
1787 | /// Abstract class used to diagnose incomplete types. |
1788 | struct TypeDiagnoser { |
1789 | TypeDiagnoser() {} |
1790 | |
1791 | virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) = 0; |
1792 | virtual ~TypeDiagnoser() {} |
1793 | }; |
1794 | |
1795 | static int getPrintable(int I) { return I; } |
1796 | static unsigned getPrintable(unsigned I) { return I; } |
1797 | static bool getPrintable(bool B) { return B; } |
1798 | static const char * getPrintable(const char *S) { return S; } |
1799 | static StringRef getPrintable(StringRef S) { return S; } |
1800 | static const std::string &getPrintable(const std::string &S) { return S; } |
1801 | static const IdentifierInfo *getPrintable(const IdentifierInfo *II) { |
1802 | return II; |
1803 | } |
1804 | static DeclarationName getPrintable(DeclarationName N) { return N; } |
1805 | static QualType getPrintable(QualType T) { return T; } |
1806 | static SourceRange getPrintable(SourceRange R) { return R; } |
1807 | static SourceRange getPrintable(SourceLocation L) { return L; } |
1808 | static SourceRange getPrintable(const Expr *E) { return E->getSourceRange(); } |
1809 | static SourceRange getPrintable(TypeLoc TL) { return TL.getSourceRange();} |
1810 | |
1811 | template <typename... Ts> class BoundTypeDiagnoser : public TypeDiagnoser { |
1812 | protected: |
1813 | unsigned DiagID; |
1814 | std::tuple<const Ts &...> Args; |
1815 | |
1816 | template <std::size_t... Is> |
1817 | void emit(const SemaDiagnosticBuilder &DB, |
1818 | std::index_sequence<Is...>) const { |
1819 | // Apply all tuple elements to the builder in order. |
1820 | bool Dummy[] = {false, (DB << getPrintable(std::get<Is>(Args)))...}; |
1821 | (void)Dummy; |
1822 | } |
1823 | |
1824 | public: |
1825 | BoundTypeDiagnoser(unsigned DiagID, const Ts &...Args) |
1826 | : TypeDiagnoser(), DiagID(DiagID), Args(Args...) { |
1827 | assert(DiagID != 0 && "no diagnostic for type diagnoser")((DiagID != 0 && "no diagnostic for type diagnoser") ? static_cast<void> (0) : __assert_fail ("DiagID != 0 && \"no diagnostic for type diagnoser\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 1827, __PRETTY_FUNCTION__)); |
1828 | } |
1829 | |
1830 | void diagnose(Sema &S, SourceLocation Loc, QualType T) override { |
1831 | const SemaDiagnosticBuilder &DB = S.Diag(Loc, DiagID); |
1832 | emit(DB, std::index_sequence_for<Ts...>()); |
1833 | DB << T; |
1834 | } |
1835 | }; |
1836 | |
1837 | /// A derivative of BoundTypeDiagnoser for which the diagnostic's type |
1838 | /// parameter is preceded by a 0/1 enum that is 1 if the type is sizeless. |
1839 | /// For example, a diagnostic with no other parameters would generally have |
1840 | /// the form "...%select{incomplete|sizeless}0 type %1...". |
1841 | template <typename... Ts> |
1842 | class SizelessTypeDiagnoser : public BoundTypeDiagnoser<Ts...> { |
1843 | public: |
1844 | SizelessTypeDiagnoser(unsigned DiagID, const Ts &... Args) |
1845 | : BoundTypeDiagnoser<Ts...>(DiagID, Args...) {} |
1846 | |
1847 | void diagnose(Sema &S, SourceLocation Loc, QualType T) override { |
1848 | const SemaDiagnosticBuilder &DB = S.Diag(Loc, this->DiagID); |
1849 | this->emit(DB, std::index_sequence_for<Ts...>()); |
1850 | DB << T->isSizelessType() << T; |
1851 | } |
1852 | }; |
1853 | |
1854 | enum class CompleteTypeKind { |
1855 | /// Apply the normal rules for complete types. In particular, |
1856 | /// treat all sizeless types as incomplete. |
1857 | Normal, |
1858 | |
1859 | /// Relax the normal rules for complete types so that they include |
1860 | /// sizeless built-in types. |
1861 | AcceptSizeless, |
1862 | |
1863 | // FIXME: Eventually we should flip the default to Normal and opt in |
1864 | // to AcceptSizeless rather than opt out of it. |
1865 | Default = AcceptSizeless |
1866 | }; |
1867 | |
1868 | private: |
1869 | /// Methods for marking which expressions involve dereferencing a pointer |
1870 | /// marked with the 'noderef' attribute. Expressions are checked bottom up as |
1871 | /// they are parsed, meaning that a noderef pointer may not be accessed. For |
1872 | /// example, in `&*p` where `p` is a noderef pointer, we will first parse the |
1873 | /// `*p`, but need to check that `address of` is called on it. This requires |
1874 | /// keeping a container of all pending expressions and checking if the address |
1875 | /// of them are eventually taken. |
1876 | void CheckSubscriptAccessOfNoDeref(const ArraySubscriptExpr *E); |
1877 | void CheckAddressOfNoDeref(const Expr *E); |
1878 | void CheckMemberAccessOfNoDeref(const MemberExpr *E); |
1879 | |
1880 | bool RequireCompleteTypeImpl(SourceLocation Loc, QualType T, |
1881 | CompleteTypeKind Kind, TypeDiagnoser *Diagnoser); |
1882 | |
1883 | struct ModuleScope { |
1884 | SourceLocation BeginLoc; |
1885 | clang::Module *Module = nullptr; |
1886 | bool ModuleInterface = false; |
1887 | bool ImplicitGlobalModuleFragment = false; |
1888 | VisibleModuleSet OuterVisibleModules; |
1889 | }; |
1890 | /// The modules we're currently parsing. |
1891 | llvm::SmallVector<ModuleScope, 16> ModuleScopes; |
1892 | |
1893 | /// Namespace definitions that we will export when they finish. |
1894 | llvm::SmallPtrSet<const NamespaceDecl*, 8> DeferredExportedNamespaces; |
1895 | |
1896 | /// Get the module whose scope we are currently within. |
1897 | Module *getCurrentModule() const { |
1898 | return ModuleScopes.empty() ? nullptr : ModuleScopes.back().Module; |
1899 | } |
1900 | |
1901 | VisibleModuleSet VisibleModules; |
1902 | |
1903 | public: |
1904 | /// Get the module owning an entity. |
1905 | Module *getOwningModule(const Decl *Entity) { |
1906 | return Entity->getOwningModule(); |
1907 | } |
1908 | |
1909 | /// Make a merged definition of an existing hidden definition \p ND |
1910 | /// visible at the specified location. |
1911 | void makeMergedDefinitionVisible(NamedDecl *ND); |
1912 | |
1913 | bool isModuleVisible(const Module *M, bool ModulePrivate = false); |
1914 | |
1915 | // When loading a non-modular PCH files, this is used to restore module |
1916 | // visibility. |
1917 | void makeModuleVisible(Module *Mod, SourceLocation ImportLoc) { |
1918 | VisibleModules.setVisible(Mod, ImportLoc); |
1919 | } |
1920 | |
1921 | /// Determine whether a declaration is visible to name lookup. |
1922 | bool isVisible(const NamedDecl *D) { |
1923 | return D->isUnconditionallyVisible() || isVisibleSlow(D); |
1924 | } |
1925 | |
1926 | /// Determine whether any declaration of an entity is visible. |
1927 | bool |
1928 | hasVisibleDeclaration(const NamedDecl *D, |
1929 | llvm::SmallVectorImpl<Module *> *Modules = nullptr) { |
1930 | return isVisible(D) || hasVisibleDeclarationSlow(D, Modules); |
1931 | } |
1932 | bool hasVisibleDeclarationSlow(const NamedDecl *D, |
1933 | llvm::SmallVectorImpl<Module *> *Modules); |
1934 | |
1935 | bool hasVisibleMergedDefinition(NamedDecl *Def); |
1936 | bool hasMergedDefinitionInCurrentModule(NamedDecl *Def); |
1937 | |
1938 | /// Determine if \p D and \p Suggested have a structurally compatible |
1939 | /// layout as described in C11 6.2.7/1. |
1940 | bool hasStructuralCompatLayout(Decl *D, Decl *Suggested); |
1941 | |
1942 | /// Determine if \p D has a visible definition. If not, suggest a declaration |
1943 | /// that should be made visible to expose the definition. |
1944 | bool hasVisibleDefinition(NamedDecl *D, NamedDecl **Suggested, |
1945 | bool OnlyNeedComplete = false); |
1946 | bool hasVisibleDefinition(const NamedDecl *D) { |
1947 | NamedDecl *Hidden; |
1948 | return hasVisibleDefinition(const_cast<NamedDecl*>(D), &Hidden); |
1949 | } |
1950 | |
1951 | /// Determine if the template parameter \p D has a visible default argument. |
1952 | bool |
1953 | hasVisibleDefaultArgument(const NamedDecl *D, |
1954 | llvm::SmallVectorImpl<Module *> *Modules = nullptr); |
1955 | |
1956 | /// Determine if there is a visible declaration of \p D that is an explicit |
1957 | /// specialization declaration for a specialization of a template. (For a |
1958 | /// member specialization, use hasVisibleMemberSpecialization.) |
1959 | bool hasVisibleExplicitSpecialization( |
1960 | const NamedDecl *D, llvm::SmallVectorImpl<Module *> *Modules = nullptr); |
1961 | |
1962 | /// Determine if there is a visible declaration of \p D that is a member |
1963 | /// specialization declaration (as opposed to an instantiated declaration). |
1964 | bool hasVisibleMemberSpecialization( |
1965 | const NamedDecl *D, llvm::SmallVectorImpl<Module *> *Modules = nullptr); |
1966 | |
1967 | /// Determine if \p A and \p B are equivalent internal linkage declarations |
1968 | /// from different modules, and thus an ambiguity error can be downgraded to |
1969 | /// an extension warning. |
1970 | bool isEquivalentInternalLinkageDeclaration(const NamedDecl *A, |
1971 | const NamedDecl *B); |
1972 | void diagnoseEquivalentInternalLinkageDeclarations( |
1973 | SourceLocation Loc, const NamedDecl *D, |
1974 | ArrayRef<const NamedDecl *> Equiv); |
1975 | |
1976 | bool isUsualDeallocationFunction(const CXXMethodDecl *FD); |
1977 | |
1978 | bool isCompleteType(SourceLocation Loc, QualType T, |
1979 | CompleteTypeKind Kind = CompleteTypeKind::Default) { |
1980 | return !RequireCompleteTypeImpl(Loc, T, Kind, nullptr); |
1981 | } |
1982 | bool RequireCompleteType(SourceLocation Loc, QualType T, |
1983 | CompleteTypeKind Kind, TypeDiagnoser &Diagnoser); |
1984 | bool RequireCompleteType(SourceLocation Loc, QualType T, |
1985 | CompleteTypeKind Kind, unsigned DiagID); |
1986 | |
1987 | bool RequireCompleteType(SourceLocation Loc, QualType T, |
1988 | TypeDiagnoser &Diagnoser) { |
1989 | return RequireCompleteType(Loc, T, CompleteTypeKind::Default, Diagnoser); |
1990 | } |
1991 | bool RequireCompleteType(SourceLocation Loc, QualType T, unsigned DiagID) { |
1992 | return RequireCompleteType(Loc, T, CompleteTypeKind::Default, DiagID); |
1993 | } |
1994 | |
1995 | template <typename... Ts> |
1996 | bool RequireCompleteType(SourceLocation Loc, QualType T, unsigned DiagID, |
1997 | const Ts &...Args) { |
1998 | BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...); |
1999 | return RequireCompleteType(Loc, T, Diagnoser); |
2000 | } |
2001 | |
2002 | template <typename... Ts> |
2003 | bool RequireCompleteSizedType(SourceLocation Loc, QualType T, unsigned DiagID, |
2004 | const Ts &... Args) { |
2005 | SizelessTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...); |
2006 | return RequireCompleteType(Loc, T, CompleteTypeKind::Normal, Diagnoser); |
2007 | } |
2008 | |
2009 | void completeExprArrayBound(Expr *E); |
2010 | bool RequireCompleteExprType(Expr *E, CompleteTypeKind Kind, |
2011 | TypeDiagnoser &Diagnoser); |
2012 | bool RequireCompleteExprType(Expr *E, unsigned DiagID); |
2013 | |
2014 | template <typename... Ts> |
2015 | bool RequireCompleteExprType(Expr *E, unsigned DiagID, const Ts &...Args) { |
2016 | BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...); |
2017 | return RequireCompleteExprType(E, CompleteTypeKind::Default, Diagnoser); |
2018 | } |
2019 | |
2020 | template <typename... Ts> |
2021 | bool RequireCompleteSizedExprType(Expr *E, unsigned DiagID, |
2022 | const Ts &... Args) { |
2023 | SizelessTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...); |
2024 | return RequireCompleteExprType(E, CompleteTypeKind::Normal, Diagnoser); |
2025 | } |
2026 | |
2027 | bool RequireLiteralType(SourceLocation Loc, QualType T, |
2028 | TypeDiagnoser &Diagnoser); |
2029 | bool RequireLiteralType(SourceLocation Loc, QualType T, unsigned DiagID); |
2030 | |
2031 | template <typename... Ts> |
2032 | bool RequireLiteralType(SourceLocation Loc, QualType T, unsigned DiagID, |
2033 | const Ts &...Args) { |
2034 | BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...); |
2035 | return RequireLiteralType(Loc, T, Diagnoser); |
2036 | } |
2037 | |
2038 | QualType getElaboratedType(ElaboratedTypeKeyword Keyword, |
2039 | const CXXScopeSpec &SS, QualType T, |
2040 | TagDecl *OwnedTagDecl = nullptr); |
2041 | |
2042 | QualType BuildTypeofExprType(Expr *E, SourceLocation Loc); |
2043 | /// If AsUnevaluated is false, E is treated as though it were an evaluated |
2044 | /// context, such as when building a type for decltype(auto). |
2045 | QualType BuildDecltypeType(Expr *E, SourceLocation Loc, |
2046 | bool AsUnevaluated = true); |
2047 | QualType BuildUnaryTransformType(QualType BaseType, |
2048 | UnaryTransformType::UTTKind UKind, |
2049 | SourceLocation Loc); |
2050 | |
2051 | //===--------------------------------------------------------------------===// |
2052 | // Symbol table / Decl tracking callbacks: SemaDecl.cpp. |
2053 | // |
2054 | |
2055 | struct SkipBodyInfo { |
2056 | SkipBodyInfo() |
2057 | : ShouldSkip(false), CheckSameAsPrevious(false), Previous(nullptr), |
2058 | New(nullptr) {} |
2059 | bool ShouldSkip; |
2060 | bool CheckSameAsPrevious; |
2061 | NamedDecl *Previous; |
2062 | NamedDecl *New; |
2063 | }; |
2064 | |
2065 | DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType = nullptr); |
2066 | |
2067 | void DiagnoseUseOfUnimplementedSelectors(); |
2068 | |
2069 | bool isSimpleTypeSpecifier(tok::TokenKind Kind) const; |
2070 | |
2071 | ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, |
2072 | Scope *S, CXXScopeSpec *SS = nullptr, |
2073 | bool isClassName = false, bool HasTrailingDot = false, |
2074 | ParsedType ObjectType = nullptr, |
2075 | bool IsCtorOrDtorName = false, |
2076 | bool WantNontrivialTypeSourceInfo = false, |
2077 | bool IsClassTemplateDeductionContext = true, |
2078 | IdentifierInfo **CorrectedII = nullptr); |
2079 | TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S); |
2080 | bool isMicrosoftMissingTypename(const CXXScopeSpec *SS, Scope *S); |
2081 | void DiagnoseUnknownTypeName(IdentifierInfo *&II, |
2082 | SourceLocation IILoc, |
2083 | Scope *S, |
2084 | CXXScopeSpec *SS, |
2085 | ParsedType &SuggestedType, |
2086 | bool IsTemplateName = false); |
2087 | |
2088 | /// Attempt to behave like MSVC in situations where lookup of an unqualified |
2089 | /// type name has failed in a dependent context. In these situations, we |
2090 | /// automatically form a DependentTypeName that will retry lookup in a related |
2091 | /// scope during instantiation. |
2092 | ParsedType ActOnMSVCUnknownTypeName(const IdentifierInfo &II, |
2093 | SourceLocation NameLoc, |
2094 | bool IsTemplateTypeArg); |
2095 | |
2096 | /// Describes the result of the name lookup and resolution performed |
2097 | /// by \c ClassifyName(). |
2098 | enum NameClassificationKind { |
2099 | /// This name is not a type or template in this context, but might be |
2100 | /// something else. |
2101 | NC_Unknown, |
2102 | /// Classification failed; an error has been produced. |
2103 | NC_Error, |
2104 | /// The name has been typo-corrected to a keyword. |
2105 | NC_Keyword, |
2106 | /// The name was classified as a type. |
2107 | NC_Type, |
2108 | /// The name was classified as a specific non-type, non-template |
2109 | /// declaration. ActOnNameClassifiedAsNonType should be called to |
2110 | /// convert the declaration to an expression. |
2111 | NC_NonType, |
2112 | /// The name was classified as an ADL-only function name. |
2113 | /// ActOnNameClassifiedAsUndeclaredNonType should be called to convert the |
2114 | /// result to an expression. |
2115 | NC_UndeclaredNonType, |
2116 | /// The name denotes a member of a dependent type that could not be |
2117 | /// resolved. ActOnNameClassifiedAsDependentNonType should be called to |
2118 | /// convert the result to an expression. |
2119 | NC_DependentNonType, |
2120 | /// The name was classified as an overload set, and an expression |
2121 | /// representing that overload set has been formed. |
2122 | /// ActOnNameClassifiedAsOverloadSet should be called to form a suitable |
2123 | /// expression referencing the overload set. |
2124 | NC_OverloadSet, |
2125 | /// The name was classified as a template whose specializations are types. |
2126 | NC_TypeTemplate, |
2127 | /// The name was classified as a variable template name. |
2128 | NC_VarTemplate, |
2129 | /// The name was classified as a function template name. |
2130 | NC_FunctionTemplate, |
2131 | /// The name was classified as an ADL-only function template name. |
2132 | NC_UndeclaredTemplate, |
2133 | /// The name was classified as a concept name. |
2134 | NC_Concept, |
2135 | }; |
2136 | |
2137 | class NameClassification { |
2138 | NameClassificationKind Kind; |
2139 | union { |
2140 | ExprResult Expr; |
2141 | NamedDecl *NonTypeDecl; |
2142 | TemplateName Template; |
2143 | ParsedType Type; |
2144 | }; |
2145 | |
2146 | explicit NameClassification(NameClassificationKind Kind) : Kind(Kind) {} |
2147 | |
2148 | public: |
2149 | NameClassification(ParsedType Type) : Kind(NC_Type), Type(Type) {} |
2150 | |
2151 | NameClassification(const IdentifierInfo *Keyword) : Kind(NC_Keyword) {} |
2152 | |
2153 | static NameClassification Error() { |
2154 | return NameClassification(NC_Error); |
2155 | } |
2156 | |
2157 | static NameClassification Unknown() { |
2158 | return NameClassification(NC_Unknown); |
2159 | } |
2160 | |
2161 | static NameClassification OverloadSet(ExprResult E) { |
2162 | NameClassification Result(NC_OverloadSet); |
2163 | Result.Expr = E; |
2164 | return Result; |
2165 | } |
2166 | |
2167 | static NameClassification NonType(NamedDecl *D) { |
2168 | NameClassification Result(NC_NonType); |
2169 | Result.NonTypeDecl = D; |
2170 | return Result; |
2171 | } |
2172 | |
2173 | static NameClassification UndeclaredNonType() { |
2174 | return NameClassification(NC_UndeclaredNonType); |
2175 | } |
2176 | |
2177 | static NameClassification DependentNonType() { |
2178 | return NameClassification(NC_DependentNonType); |
2179 | } |
2180 | |
2181 | static NameClassification TypeTemplate(TemplateName Name) { |
2182 | NameClassification Result(NC_TypeTemplate); |
2183 | Result.Template = Name; |
2184 | return Result; |
2185 | } |
2186 | |
2187 | static NameClassification VarTemplate(TemplateName Name) { |
2188 | NameClassification Result(NC_VarTemplate); |
2189 | Result.Template = Name; |
2190 | return Result; |
2191 | } |
2192 | |
2193 | static NameClassification FunctionTemplate(TemplateName Name) { |
2194 | NameClassification Result(NC_FunctionTemplate); |
2195 | Result.Template = Name; |
2196 | return Result; |
2197 | } |
2198 | |
2199 | static NameClassification Concept(TemplateName Name) { |
2200 | NameClassification Result(NC_Concept); |
2201 | Result.Template = Name; |
2202 | return Result; |
2203 | } |
2204 | |
2205 | static NameClassification UndeclaredTemplate(TemplateName Name) { |
2206 | NameClassification Result(NC_UndeclaredTemplate); |
2207 | Result.Template = Name; |
2208 | return Result; |
2209 | } |
2210 | |
2211 | NameClassificationKind getKind() const { return Kind; } |
2212 | |
2213 | ExprResult getExpression() const { |
2214 | assert(Kind == NC_OverloadSet)((Kind == NC_OverloadSet) ? static_cast<void> (0) : __assert_fail ("Kind == NC_OverloadSet", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 2214, __PRETTY_FUNCTION__)); |
2215 | return Expr; |
2216 | } |
2217 | |
2218 | ParsedType getType() const { |
2219 | assert(Kind == NC_Type)((Kind == NC_Type) ? static_cast<void> (0) : __assert_fail ("Kind == NC_Type", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 2219, __PRETTY_FUNCTION__)); |
2220 | return Type; |
2221 | } |
2222 | |
2223 | NamedDecl *getNonTypeDecl() const { |
2224 | assert(Kind == NC_NonType)((Kind == NC_NonType) ? static_cast<void> (0) : __assert_fail ("Kind == NC_NonType", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 2224, __PRETTY_FUNCTION__)); |
2225 | return NonTypeDecl; |
2226 | } |
2227 | |
2228 | TemplateName getTemplateName() const { |
2229 | assert(Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate ||((Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate || Kind == NC_VarTemplate || Kind == NC_Concept || Kind == NC_UndeclaredTemplate ) ? static_cast<void> (0) : __assert_fail ("Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate || Kind == NC_VarTemplate || Kind == NC_Concept || Kind == NC_UndeclaredTemplate" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 2231, __PRETTY_FUNCTION__)) |
2230 | Kind == NC_VarTemplate || Kind == NC_Concept ||((Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate || Kind == NC_VarTemplate || Kind == NC_Concept || Kind == NC_UndeclaredTemplate ) ? static_cast<void> (0) : __assert_fail ("Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate || Kind == NC_VarTemplate || Kind == NC_Concept || Kind == NC_UndeclaredTemplate" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 2231, __PRETTY_FUNCTION__)) |
2231 | Kind == NC_UndeclaredTemplate)((Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate || Kind == NC_VarTemplate || Kind == NC_Concept || Kind == NC_UndeclaredTemplate ) ? static_cast<void> (0) : __assert_fail ("Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate || Kind == NC_VarTemplate || Kind == NC_Concept || Kind == NC_UndeclaredTemplate" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 2231, __PRETTY_FUNCTION__)); |
2232 | return Template; |
2233 | } |
2234 | |
2235 | TemplateNameKind getTemplateNameKind() const { |
2236 | switch (Kind) { |
2237 | case NC_TypeTemplate: |
2238 | return TNK_Type_template; |
2239 | case NC_FunctionTemplate: |
2240 | return TNK_Function_template; |
2241 | case NC_VarTemplate: |
2242 | return TNK_Var_template; |
2243 | case NC_Concept: |
2244 | return TNK_Concept_template; |
2245 | case NC_UndeclaredTemplate: |
2246 | return TNK_Undeclared_template; |
2247 | default: |
2248 | llvm_unreachable("unsupported name classification.")::llvm::llvm_unreachable_internal("unsupported name classification." , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 2248); |
2249 | } |
2250 | } |
2251 | }; |
2252 | |
2253 | /// Perform name lookup on the given name, classifying it based on |
2254 | /// the results of name lookup and the following token. |
2255 | /// |
2256 | /// This routine is used by the parser to resolve identifiers and help direct |
2257 | /// parsing. When the identifier cannot be found, this routine will attempt |
2258 | /// to correct the typo and classify based on the resulting name. |
2259 | /// |
2260 | /// \param S The scope in which we're performing name lookup. |
2261 | /// |
2262 | /// \param SS The nested-name-specifier that precedes the name. |
2263 | /// |
2264 | /// \param Name The identifier. If typo correction finds an alternative name, |
2265 | /// this pointer parameter will be updated accordingly. |
2266 | /// |
2267 | /// \param NameLoc The location of the identifier. |
2268 | /// |
2269 | /// \param NextToken The token following the identifier. Used to help |
2270 | /// disambiguate the name. |
2271 | /// |
2272 | /// \param CCC The correction callback, if typo correction is desired. |
2273 | NameClassification ClassifyName(Scope *S, CXXScopeSpec &SS, |
2274 | IdentifierInfo *&Name, SourceLocation NameLoc, |
2275 | const Token &NextToken, |
2276 | CorrectionCandidateCallback *CCC = nullptr); |
2277 | |
2278 | /// Act on the result of classifying a name as an undeclared (ADL-only) |
2279 | /// non-type declaration. |
2280 | ExprResult ActOnNameClassifiedAsUndeclaredNonType(IdentifierInfo *Name, |
2281 | SourceLocation NameLoc); |
2282 | /// Act on the result of classifying a name as an undeclared member of a |
2283 | /// dependent base class. |
2284 | ExprResult ActOnNameClassifiedAsDependentNonType(const CXXScopeSpec &SS, |
2285 | IdentifierInfo *Name, |
2286 | SourceLocation NameLoc, |
2287 | bool IsAddressOfOperand); |
2288 | /// Act on the result of classifying a name as a specific non-type |
2289 | /// declaration. |
2290 | ExprResult ActOnNameClassifiedAsNonType(Scope *S, const CXXScopeSpec &SS, |
2291 | NamedDecl *Found, |
2292 | SourceLocation NameLoc, |
2293 | const Token &NextToken); |
2294 | /// Act on the result of classifying a name as an overload set. |
2295 | ExprResult ActOnNameClassifiedAsOverloadSet(Scope *S, Expr *OverloadSet); |
2296 | |
2297 | /// Describes the detailed kind of a template name. Used in diagnostics. |
2298 | enum class TemplateNameKindForDiagnostics { |
2299 | ClassTemplate, |
2300 | FunctionTemplate, |
2301 | VarTemplate, |
2302 | AliasTemplate, |
2303 | TemplateTemplateParam, |
2304 | Concept, |
2305 | DependentTemplate |
2306 | }; |
2307 | TemplateNameKindForDiagnostics |
2308 | getTemplateNameKindForDiagnostics(TemplateName Name); |
2309 | |
2310 | /// Determine whether it's plausible that E was intended to be a |
2311 | /// template-name. |
2312 | bool mightBeIntendedToBeTemplateName(ExprResult E, bool &Dependent) { |
2313 | if (!getLangOpts().CPlusPlus || E.isInvalid()) |
2314 | return false; |
2315 | Dependent = false; |
2316 | if (auto *DRE = dyn_cast<DeclRefExpr>(E.get())) |
2317 | return !DRE->hasExplicitTemplateArgs(); |
2318 | if (auto *ME = dyn_cast<MemberExpr>(E.get())) |
2319 | return !ME->hasExplicitTemplateArgs(); |
2320 | Dependent = true; |
2321 | if (auto *DSDRE = dyn_cast<DependentScopeDeclRefExpr>(E.get())) |
2322 | return !DSDRE->hasExplicitTemplateArgs(); |
2323 | if (auto *DSME = dyn_cast<CXXDependentScopeMemberExpr>(E.get())) |
2324 | return !DSME->hasExplicitTemplateArgs(); |
2325 | // Any additional cases recognized here should also be handled by |
2326 | // diagnoseExprIntendedAsTemplateName. |
2327 | return false; |
2328 | } |
2329 | void diagnoseExprIntendedAsTemplateName(Scope *S, ExprResult TemplateName, |
2330 | SourceLocation Less, |
2331 | SourceLocation Greater); |
2332 | |
2333 | Decl *ActOnDeclarator(Scope *S, Declarator &D); |
2334 | |
2335 | NamedDecl *HandleDeclarator(Scope *S, Declarator &D, |
2336 | MultiTemplateParamsArg TemplateParameterLists); |
2337 | void RegisterLocallyScopedExternCDecl(NamedDecl *ND, Scope *S); |
2338 | bool DiagnoseClassNameShadow(DeclContext *DC, DeclarationNameInfo Info); |
2339 | bool diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC, |
2340 | DeclarationName Name, SourceLocation Loc, |
2341 | bool IsTemplateId); |
2342 | void |
2343 | diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals, |
2344 | SourceLocation FallbackLoc, |
2345 | SourceLocation ConstQualLoc = SourceLocation(), |
2346 | SourceLocation VolatileQualLoc = SourceLocation(), |
2347 | SourceLocation RestrictQualLoc = SourceLocation(), |
2348 | SourceLocation AtomicQualLoc = SourceLocation(), |
2349 | SourceLocation UnalignedQualLoc = SourceLocation()); |
2350 | |
2351 | static bool adjustContextForLocalExternDecl(DeclContext *&DC); |
2352 | void DiagnoseFunctionSpecifiers(const DeclSpec &DS); |
2353 | NamedDecl *getShadowedDeclaration(const TypedefNameDecl *D, |
2354 | const LookupResult &R); |
2355 | NamedDecl *getShadowedDeclaration(const VarDecl *D, const LookupResult &R); |
2356 | void CheckShadow(NamedDecl *D, NamedDecl *ShadowedDecl, |
2357 | const LookupResult &R); |
2358 | void CheckShadow(Scope *S, VarDecl *D); |
2359 | |
2360 | /// Warn if 'E', which is an expression that is about to be modified, refers |
2361 | /// to a shadowing declaration. |
2362 | void CheckShadowingDeclModification(Expr *E, SourceLocation Loc); |
2363 | |
2364 | void DiagnoseShadowingLambdaDecls(const sema::LambdaScopeInfo *LSI); |
2365 | |
2366 | private: |
2367 | /// Map of current shadowing declarations to shadowed declarations. Warn if |
2368 | /// it looks like the user is trying to modify the shadowing declaration. |
2369 | llvm::DenseMap<const NamedDecl *, const NamedDecl *> ShadowingDecls; |
2370 | |
2371 | public: |
2372 | void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange); |
2373 | void handleTagNumbering(const TagDecl *Tag, Scope *TagScope); |
2374 | void setTagNameForLinkagePurposes(TagDecl *TagFromDeclSpec, |
2375 | TypedefNameDecl *NewTD); |
2376 | void CheckTypedefForVariablyModifiedType(Scope *S, TypedefNameDecl *D); |
2377 | NamedDecl* ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC, |
2378 | TypeSourceInfo *TInfo, |
2379 | LookupResult &Previous); |
2380 | NamedDecl* ActOnTypedefNameDecl(Scope* S, DeclContext* DC, TypedefNameDecl *D, |
2381 | LookupResult &Previous, bool &Redeclaration); |
2382 | NamedDecl *ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, |
2383 | TypeSourceInfo *TInfo, |
2384 | LookupResult &Previous, |
2385 | MultiTemplateParamsArg TemplateParamLists, |
2386 | bool &AddToScope, |
2387 | ArrayRef<BindingDecl *> Bindings = None); |
2388 | NamedDecl * |
2389 | ActOnDecompositionDeclarator(Scope *S, Declarator &D, |
2390 | MultiTemplateParamsArg TemplateParamLists); |
2391 | // Returns true if the variable declaration is a redeclaration |
2392 | bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous); |
2393 | void CheckVariableDeclarationType(VarDecl *NewVD); |
2394 | bool DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit, |
2395 | Expr *Init); |
2396 | void CheckCompleteVariableDeclaration(VarDecl *VD); |
2397 | void CheckCompleteDecompositionDeclaration(DecompositionDecl *DD); |
2398 | void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D); |
2399 | |
2400 | NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, |
2401 | TypeSourceInfo *TInfo, |
2402 | LookupResult &Previous, |
2403 | MultiTemplateParamsArg TemplateParamLists, |
2404 | bool &AddToScope); |
2405 | bool AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD); |
2406 | |
2407 | enum class CheckConstexprKind { |
2408 | /// Diagnose issues that are non-constant or that are extensions. |
2409 | Diagnose, |
2410 | /// Identify whether this function satisfies the formal rules for constexpr |
2411 | /// functions in the current lanugage mode (with no extensions). |
2412 | CheckValid |
2413 | }; |
2414 | |
2415 | bool CheckConstexprFunctionDefinition(const FunctionDecl *FD, |
2416 | CheckConstexprKind Kind); |
2417 | |
2418 | void DiagnoseHiddenVirtualMethods(CXXMethodDecl *MD); |
2419 | void FindHiddenVirtualMethods(CXXMethodDecl *MD, |
2420 | SmallVectorImpl<CXXMethodDecl*> &OverloadedMethods); |
2421 | void NoteHiddenVirtualMethods(CXXMethodDecl *MD, |
2422 | SmallVectorImpl<CXXMethodDecl*> &OverloadedMethods); |
2423 | // Returns true if the function declaration is a redeclaration |
2424 | bool CheckFunctionDeclaration(Scope *S, |
2425 | FunctionDecl *NewFD, LookupResult &Previous, |
2426 | bool IsMemberSpecialization); |
2427 | bool shouldLinkDependentDeclWithPrevious(Decl *D, Decl *OldDecl); |
2428 | bool canFullyTypeCheckRedeclaration(ValueDecl *NewD, ValueDecl *OldD, |
2429 | QualType NewT, QualType OldT); |
2430 | void CheckMain(FunctionDecl *FD, const DeclSpec &D); |
2431 | void CheckMSVCRTEntryPoint(FunctionDecl *FD); |
2432 | Attr *getImplicitCodeSegOrSectionAttrForFunction(const FunctionDecl *FD, |
2433 | bool IsDefinition); |
2434 | void CheckFunctionOrTemplateParamDeclarator(Scope *S, Declarator &D); |
2435 | Decl *ActOnParamDeclarator(Scope *S, Declarator &D); |
2436 | ParmVarDecl *BuildParmVarDeclForTypedef(DeclContext *DC, |
2437 | SourceLocation Loc, |
2438 | QualType T); |
2439 | ParmVarDecl *CheckParameter(DeclContext *DC, SourceLocation StartLoc, |
2440 | SourceLocation NameLoc, IdentifierInfo *Name, |
2441 | QualType T, TypeSourceInfo *TSInfo, |
2442 | StorageClass SC); |
2443 | void ActOnParamDefaultArgument(Decl *param, |
2444 | SourceLocation EqualLoc, |
2445 | Expr *defarg); |
2446 | void ActOnParamUnparsedDefaultArgument(Decl *param, SourceLocation EqualLoc, |
2447 | SourceLocation ArgLoc); |
2448 | void ActOnParamDefaultArgumentError(Decl *param, SourceLocation EqualLoc); |
2449 | ExprResult ConvertParamDefaultArgument(const ParmVarDecl *Param, |
2450 | Expr *DefaultArg, |
2451 | SourceLocation EqualLoc); |
2452 | void SetParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg, |
2453 | SourceLocation EqualLoc); |
2454 | |
2455 | // Contexts where using non-trivial C union types can be disallowed. This is |
2456 | // passed to err_non_trivial_c_union_in_invalid_context. |
2457 | enum NonTrivialCUnionContext { |
2458 | // Function parameter. |
2459 | NTCUC_FunctionParam, |
2460 | // Function return. |
2461 | NTCUC_FunctionReturn, |
2462 | // Default-initialized object. |
2463 | NTCUC_DefaultInitializedObject, |
2464 | // Variable with automatic storage duration. |
2465 | NTCUC_AutoVar, |
2466 | // Initializer expression that might copy from another object. |
2467 | NTCUC_CopyInit, |
2468 | // Assignment. |
2469 | NTCUC_Assignment, |
2470 | // Compound literal. |
2471 | NTCUC_CompoundLiteral, |
2472 | // Block capture. |
2473 | NTCUC_BlockCapture, |
2474 | // lvalue-to-rvalue conversion of volatile type. |
2475 | NTCUC_LValueToRValueVolatile, |
2476 | }; |
2477 | |
2478 | /// Emit diagnostics if the initializer or any of its explicit or |
2479 | /// implicitly-generated subexpressions require copying or |
2480 | /// default-initializing a type that is or contains a C union type that is |
2481 | /// non-trivial to copy or default-initialize. |
2482 | void checkNonTrivialCUnionInInitializer(const Expr *Init, SourceLocation Loc); |
2483 | |
2484 | // These flags are passed to checkNonTrivialCUnion. |
2485 | enum NonTrivialCUnionKind { |
2486 | NTCUK_Init = 0x1, |
2487 | NTCUK_Destruct = 0x2, |
2488 | NTCUK_Copy = 0x4, |
2489 | }; |
2490 | |
2491 | /// Emit diagnostics if a non-trivial C union type or a struct that contains |
2492 | /// a non-trivial C union is used in an invalid context. |
2493 | void checkNonTrivialCUnion(QualType QT, SourceLocation Loc, |
2494 | NonTrivialCUnionContext UseContext, |
2495 | unsigned NonTrivialKind); |
2496 | |
2497 | void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit); |
2498 | void ActOnUninitializedDecl(Decl *dcl); |
2499 | void ActOnInitializerError(Decl *Dcl); |
2500 | |
2501 | void ActOnPureSpecifier(Decl *D, SourceLocation PureSpecLoc); |
2502 | void ActOnCXXForRangeDecl(Decl *D); |
2503 | StmtResult ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc, |
2504 | IdentifierInfo *Ident, |
2505 | ParsedAttributes &Attrs, |
2506 | SourceLocation AttrEnd); |
2507 | void SetDeclDeleted(Decl *dcl, SourceLocation DelLoc); |
2508 | void SetDeclDefaulted(Decl *dcl, SourceLocation DefaultLoc); |
2509 | void CheckStaticLocalForDllExport(VarDecl *VD); |
2510 | void FinalizeDeclaration(Decl *D); |
2511 | DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, |
2512 | ArrayRef<Decl *> Group); |
2513 | DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef<Decl *> Group); |
2514 | |
2515 | /// Should be called on all declarations that might have attached |
2516 | /// documentation comments. |
2517 | void ActOnDocumentableDecl(Decl *D); |
2518 | void ActOnDocumentableDecls(ArrayRef<Decl *> Group); |
2519 | |
2520 | void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D, |
2521 | SourceLocation LocAfterDecls); |
2522 | void CheckForFunctionRedefinition( |
2523 | FunctionDecl *FD, const FunctionDecl *EffectiveDefinition = nullptr, |
2524 | SkipBodyInfo *SkipBody = nullptr); |
2525 | Decl *ActOnStartOfFunctionDef(Scope *S, Declarator &D, |
2526 | MultiTemplateParamsArg TemplateParamLists, |
2527 | SkipBodyInfo *SkipBody = nullptr); |
2528 | Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D, |
2529 | SkipBodyInfo *SkipBody = nullptr); |
2530 | void ActOnStartTrailingRequiresClause(Scope *S, Declarator &D); |
2531 | ExprResult ActOnFinishTrailingRequiresClause(ExprResult ConstraintExpr); |
2532 | void ActOnStartOfObjCMethodDef(Scope *S, Decl *D); |
2533 | bool isObjCMethodDecl(Decl *D) { |
2534 | return D && isa<ObjCMethodDecl>(D); |
2535 | } |
2536 | |
2537 | /// Determine whether we can delay parsing the body of a function or |
2538 | /// function template until it is used, assuming we don't care about emitting |
2539 | /// code for that function. |
2540 | /// |
2541 | /// This will be \c false if we may need the body of the function in the |
2542 | /// middle of parsing an expression (where it's impractical to switch to |
2543 | /// parsing a different function), for instance, if it's constexpr in C++11 |
2544 | /// or has an 'auto' return type in C++14. These cases are essentially bugs. |
2545 | bool canDelayFunctionBody(const Declarator &D); |
2546 | |
2547 | /// Determine whether we can skip parsing the body of a function |
2548 | /// definition, assuming we don't care about analyzing its body or emitting |
2549 | /// code for that function. |
2550 | /// |
2551 | /// This will be \c false only if we may need the body of the function in |
2552 | /// order to parse the rest of the program (for instance, if it is |
2553 | /// \c constexpr in C++11 or has an 'auto' return type in C++14). |
2554 | bool canSkipFunctionBody(Decl *D); |
2555 | |
2556 | void computeNRVO(Stmt *Body, sema::FunctionScopeInfo *Scope); |
2557 | Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body); |
2558 | Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body, bool IsInstantiation); |
2559 | Decl *ActOnSkippedFunctionBody(Decl *Decl); |
2560 | void ActOnFinishInlineFunctionDef(FunctionDecl *D); |
2561 | |
2562 | /// ActOnFinishDelayedAttribute - Invoked when we have finished parsing an |
2563 | /// attribute for which parsing is delayed. |
2564 | void ActOnFinishDelayedAttribute(Scope *S, Decl *D, ParsedAttributes &Attrs); |
2565 | |
2566 | /// Diagnose any unused parameters in the given sequence of |
2567 | /// ParmVarDecl pointers. |
2568 | void DiagnoseUnusedParameters(ArrayRef<ParmVarDecl *> Parameters); |
2569 | |
2570 | /// Diagnose whether the size of parameters or return value of a |
2571 | /// function or obj-c method definition is pass-by-value and larger than a |
2572 | /// specified threshold. |
2573 | void |
2574 | DiagnoseSizeOfParametersAndReturnValue(ArrayRef<ParmVarDecl *> Parameters, |
2575 | QualType ReturnTy, NamedDecl *D); |
2576 | |
2577 | void DiagnoseInvalidJumps(Stmt *Body); |
2578 | Decl *ActOnFileScopeAsmDecl(Expr *expr, |
2579 | SourceLocation AsmLoc, |
2580 | SourceLocation RParenLoc); |
2581 | |
2582 | /// Handle a C++11 empty-declaration and attribute-declaration. |
2583 | Decl *ActOnEmptyDeclaration(Scope *S, const ParsedAttributesView &AttrList, |
2584 | SourceLocation SemiLoc); |
2585 | |
2586 | enum class ModuleDeclKind { |
2587 | Interface, ///< 'export module X;' |
2588 | Implementation, ///< 'module X;' |
2589 | }; |
2590 | |
2591 | /// The parser has processed a module-declaration that begins the definition |
2592 | /// of a module interface or implementation. |
2593 | DeclGroupPtrTy ActOnModuleDecl(SourceLocation StartLoc, |
2594 | SourceLocation ModuleLoc, ModuleDeclKind MDK, |
2595 | ModuleIdPath Path, bool IsFirstDecl); |
2596 | |
2597 | /// The parser has processed a global-module-fragment declaration that begins |
2598 | /// the definition of the global module fragment of the current module unit. |
2599 | /// \param ModuleLoc The location of the 'module' keyword. |
2600 | DeclGroupPtrTy ActOnGlobalModuleFragmentDecl(SourceLocation ModuleLoc); |
2601 | |
2602 | /// The parser has processed a private-module-fragment declaration that begins |
2603 | /// the definition of the private module fragment of the current module unit. |
2604 | /// \param ModuleLoc The location of the 'module' keyword. |
2605 | /// \param PrivateLoc The location of the 'private' keyword. |
2606 | DeclGroupPtrTy ActOnPrivateModuleFragmentDecl(SourceLocation ModuleLoc, |
2607 | SourceLocation PrivateLoc); |
2608 | |
2609 | /// The parser has processed a module import declaration. |
2610 | /// |
2611 | /// \param StartLoc The location of the first token in the declaration. This |
2612 | /// could be the location of an '@', 'export', or 'import'. |
2613 | /// \param ExportLoc The location of the 'export' keyword, if any. |
2614 | /// \param ImportLoc The location of the 'import' keyword. |
2615 | /// \param Path The module access path. |
2616 | DeclResult ActOnModuleImport(SourceLocation StartLoc, |
2617 | SourceLocation ExportLoc, |
2618 | SourceLocation ImportLoc, ModuleIdPath Path); |
2619 | DeclResult ActOnModuleImport(SourceLocation StartLoc, |
2620 | SourceLocation ExportLoc, |
2621 | SourceLocation ImportLoc, Module *M, |
2622 | ModuleIdPath Path = {}); |
2623 | |
2624 | /// The parser has processed a module import translated from a |
2625 | /// #include or similar preprocessing directive. |
2626 | void ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod); |
2627 | void BuildModuleInclude(SourceLocation DirectiveLoc, Module *Mod); |
2628 | |
2629 | /// The parsed has entered a submodule. |
2630 | void ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod); |
2631 | /// The parser has left a submodule. |
2632 | void ActOnModuleEnd(SourceLocation DirectiveLoc, Module *Mod); |
2633 | |
2634 | /// Create an implicit import of the given module at the given |
2635 | /// source location, for error recovery, if possible. |
2636 | /// |
2637 | /// This routine is typically used when an entity found by name lookup |
2638 | /// is actually hidden within a module that we know about but the user |
2639 | /// has forgotten to import. |
2640 | void createImplicitModuleImportForErrorRecovery(SourceLocation Loc, |
2641 | Module *Mod); |
2642 | |
2643 | /// Kinds of missing import. Note, the values of these enumerators correspond |
2644 | /// to %select values in diagnostics. |
2645 | enum class MissingImportKind { |
2646 | Declaration, |
2647 | Definition, |
2648 | DefaultArgument, |
2649 | ExplicitSpecialization, |
2650 | PartialSpecialization |
2651 | }; |
2652 | |
2653 | /// Diagnose that the specified declaration needs to be visible but |
2654 | /// isn't, and suggest a module import that would resolve the problem. |
2655 | void diagnoseMissingImport(SourceLocation Loc, NamedDecl *Decl, |
2656 | MissingImportKind MIK, bool Recover = true); |
2657 | void diagnoseMissingImport(SourceLocation Loc, NamedDecl *Decl, |
2658 | SourceLocation DeclLoc, ArrayRef<Module *> Modules, |
2659 | MissingImportKind MIK, bool Recover); |
2660 | |
2661 | Decl *ActOnStartExportDecl(Scope *S, SourceLocation ExportLoc, |
2662 | SourceLocation LBraceLoc); |
2663 | Decl *ActOnFinishExportDecl(Scope *S, Decl *ExportDecl, |
2664 | SourceLocation RBraceLoc); |
2665 | |
2666 | /// We've found a use of a templated declaration that would trigger an |
2667 | /// implicit instantiation. Check that any relevant explicit specializations |
2668 | /// and partial specializations are visible, and diagnose if not. |
2669 | void checkSpecializationVisibility(SourceLocation Loc, NamedDecl *Spec); |
2670 | |
2671 | /// We've found a use of a template specialization that would select a |
2672 | /// partial specialization. Check that the partial specialization is visible, |
2673 | /// and diagnose if not. |
2674 | void checkPartialSpecializationVisibility(SourceLocation Loc, |
2675 | NamedDecl *Spec); |
2676 | |
2677 | /// Retrieve a suitable printing policy for diagnostics. |
2678 | PrintingPolicy getPrintingPolicy() const { |
2679 | return getPrintingPolicy(Context, PP); |
2680 | } |
2681 | |
2682 | /// Retrieve a suitable printing policy for diagnostics. |
2683 | static PrintingPolicy getPrintingPolicy(const ASTContext &Ctx, |
2684 | const Preprocessor &PP); |
2685 | |
2686 | /// Scope actions. |
2687 | void ActOnPopScope(SourceLocation Loc, Scope *S); |
2688 | void ActOnTranslationUnitScope(Scope *S); |
2689 | |
2690 | Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS, |
2691 | RecordDecl *&AnonRecord); |
2692 | Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS, |
2693 | MultiTemplateParamsArg TemplateParams, |
2694 | bool IsExplicitInstantiation, |
2695 | RecordDecl *&AnonRecord); |
2696 | |
2697 | Decl *BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, |
2698 | AccessSpecifier AS, |
2699 | RecordDecl *Record, |
2700 | const PrintingPolicy &Policy); |
2701 | |
2702 | Decl *BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS, |
2703 | RecordDecl *Record); |
2704 | |
2705 | /// Common ways to introduce type names without a tag for use in diagnostics. |
2706 | /// Keep in sync with err_tag_reference_non_tag. |
2707 | enum NonTagKind { |
2708 | NTK_NonStruct, |
2709 | NTK_NonClass, |
2710 | NTK_NonUnion, |
2711 | NTK_NonEnum, |
2712 | NTK_Typedef, |
2713 | NTK_TypeAlias, |
2714 | NTK_Template, |
2715 | NTK_TypeAliasTemplate, |
2716 | NTK_TemplateTemplateArgument, |
2717 | }; |
2718 | |
2719 | /// Given a non-tag type declaration, returns an enum useful for indicating |
2720 | /// what kind of non-tag type this is. |
2721 | NonTagKind getNonTagTypeDeclKind(const Decl *D, TagTypeKind TTK); |
2722 | |
2723 | bool isAcceptableTagRedeclaration(const TagDecl *Previous, |
2724 | TagTypeKind NewTag, bool isDefinition, |
2725 | SourceLocation NewTagLoc, |
2726 | const IdentifierInfo *Name); |
2727 | |
2728 | enum TagUseKind { |
2729 | TUK_Reference, // Reference to a tag: 'struct foo *X;' |
2730 | TUK_Declaration, // Fwd decl of a tag: 'struct foo;' |
2731 | TUK_Definition, // Definition of a tag: 'struct foo { int X; } Y;' |
2732 | TUK_Friend // Friend declaration: 'friend struct foo;' |
2733 | }; |
2734 | |
2735 | Decl *ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, |
2736 | SourceLocation KWLoc, CXXScopeSpec &SS, IdentifierInfo *Name, |
2737 | SourceLocation NameLoc, const ParsedAttributesView &Attr, |
2738 | AccessSpecifier AS, SourceLocation ModulePrivateLoc, |
2739 | MultiTemplateParamsArg TemplateParameterLists, bool &OwnedDecl, |
2740 | bool &IsDependent, SourceLocation ScopedEnumKWLoc, |
2741 | bool ScopedEnumUsesClassTag, TypeResult UnderlyingType, |
2742 | bool IsTypeSpecifier, bool IsTemplateParamOrArg, |
2743 | SkipBodyInfo *SkipBody = nullptr); |
2744 | |
2745 | Decl *ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc, |
2746 | unsigned TagSpec, SourceLocation TagLoc, |
2747 | CXXScopeSpec &SS, IdentifierInfo *Name, |
2748 | SourceLocation NameLoc, |
2749 | const ParsedAttributesView &Attr, |
2750 | MultiTemplateParamsArg TempParamLists); |
2751 | |
2752 | TypeResult ActOnDependentTag(Scope *S, |
2753 | unsigned TagSpec, |
2754 | TagUseKind TUK, |
2755 | const CXXScopeSpec &SS, |
2756 | IdentifierInfo *Name, |
2757 | SourceLocation TagLoc, |
2758 | SourceLocation NameLoc); |
2759 | |
2760 | void ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart, |
2761 | IdentifierInfo *ClassName, |
2762 | SmallVectorImpl<Decl *> &Decls); |
2763 | Decl *ActOnField(Scope *S, Decl *TagD, SourceLocation DeclStart, |
2764 | Declarator &D, Expr *BitfieldWidth); |
2765 | |
2766 | FieldDecl *HandleField(Scope *S, RecordDecl *TagD, SourceLocation DeclStart, |
2767 | Declarator &D, Expr *BitfieldWidth, |
2768 | InClassInitStyle InitStyle, |
2769 | AccessSpecifier AS); |
2770 | MSPropertyDecl *HandleMSProperty(Scope *S, RecordDecl *TagD, |
2771 | SourceLocation DeclStart, Declarator &D, |
2772 | Expr *BitfieldWidth, |
2773 | InClassInitStyle InitStyle, |
2774 | AccessSpecifier AS, |
2775 | const ParsedAttr &MSPropertyAttr); |
2776 | |
2777 | FieldDecl *CheckFieldDecl(DeclarationName Name, QualType T, |
2778 | TypeSourceInfo *TInfo, |
2779 | RecordDecl *Record, SourceLocation Loc, |
2780 | bool Mutable, Expr *BitfieldWidth, |
2781 | InClassInitStyle InitStyle, |
2782 | SourceLocation TSSL, |
2783 | AccessSpecifier AS, NamedDecl *PrevDecl, |
2784 | Declarator *D = nullptr); |
2785 | |
2786 | bool CheckNontrivialField(FieldDecl *FD); |
2787 | void DiagnoseNontrivial(const CXXRecordDecl *Record, CXXSpecialMember CSM); |
2788 | |
2789 | enum TrivialABIHandling { |
2790 | /// The triviality of a method unaffected by "trivial_abi". |
2791 | TAH_IgnoreTrivialABI, |
2792 | |
2793 | /// The triviality of a method affected by "trivial_abi". |
2794 | TAH_ConsiderTrivialABI |
2795 | }; |
2796 | |
2797 | bool SpecialMemberIsTrivial(CXXMethodDecl *MD, CXXSpecialMember CSM, |
2798 | TrivialABIHandling TAH = TAH_IgnoreTrivialABI, |
2799 | bool Diagnose = false); |
2800 | |
2801 | /// For a defaulted function, the kind of defaulted function that it is. |
2802 | class DefaultedFunctionKind { |
2803 | CXXSpecialMember SpecialMember : 8; |
2804 | DefaultedComparisonKind Comparison : 8; |
2805 | |
2806 | public: |
2807 | DefaultedFunctionKind() |
2808 | : SpecialMember(CXXInvalid), Comparison(DefaultedComparisonKind::None) { |
2809 | } |
2810 | DefaultedFunctionKind(CXXSpecialMember CSM) |
2811 | : SpecialMember(CSM), Comparison(DefaultedComparisonKind::None) {} |
2812 | DefaultedFunctionKind(DefaultedComparisonKind Comp) |
2813 | : SpecialMember(CXXInvalid), Comparison(Comp) {} |
2814 | |
2815 | bool isSpecialMember() const { return SpecialMember != CXXInvalid; } |
2816 | bool isComparison() const { |
2817 | return Comparison != DefaultedComparisonKind::None; |
2818 | } |
2819 | |
2820 | explicit operator bool() const { |
2821 | return isSpecialMember() || isComparison(); |
2822 | } |
2823 | |
2824 | CXXSpecialMember asSpecialMember() const { return SpecialMember; } |
2825 | DefaultedComparisonKind asComparison() const { return Comparison; } |
2826 | |
2827 | /// Get the index of this function kind for use in diagnostics. |
2828 | unsigned getDiagnosticIndex() const { |
2829 | static_assert(CXXInvalid > CXXDestructor, |
2830 | "invalid should have highest index"); |
2831 | static_assert((unsigned)DefaultedComparisonKind::None == 0, |
2832 | "none should be equal to zero"); |
2833 | return SpecialMember + (unsigned)Comparison; |
2834 | } |
2835 | }; |
2836 | |
2837 | DefaultedFunctionKind getDefaultedFunctionKind(const FunctionDecl *FD); |
2838 | |
2839 | CXXSpecialMember getSpecialMember(const CXXMethodDecl *MD) { |
2840 | return getDefaultedFunctionKind(MD).asSpecialMember(); |
2841 | } |
2842 | DefaultedComparisonKind getDefaultedComparisonKind(const FunctionDecl *FD) { |
2843 | return getDefaultedFunctionKind(FD).asComparison(); |
2844 | } |
2845 | |
2846 | void ActOnLastBitfield(SourceLocation DeclStart, |
2847 | SmallVectorImpl<Decl *> &AllIvarDecls); |
2848 | Decl *ActOnIvar(Scope *S, SourceLocation DeclStart, |
2849 | Declarator &D, Expr *BitfieldWidth, |
2850 | tok::ObjCKeywordKind visibility); |
2851 | |
2852 | // This is used for both record definitions and ObjC interface declarations. |
2853 | void ActOnFields(Scope *S, SourceLocation RecLoc, Decl *TagDecl, |
2854 | ArrayRef<Decl *> Fields, SourceLocation LBrac, |
2855 | SourceLocation RBrac, const ParsedAttributesView &AttrList); |
2856 | |
2857 | /// ActOnTagStartDefinition - Invoked when we have entered the |
2858 | /// scope of a tag's definition (e.g., for an enumeration, class, |
2859 | /// struct, or union). |
2860 | void ActOnTagStartDefinition(Scope *S, Decl *TagDecl); |
2861 | |
2862 | /// Perform ODR-like check for C/ObjC when merging tag types from modules. |
2863 | /// Differently from C++, actually parse the body and reject / error out |
2864 | /// in case of a structural mismatch. |
2865 | bool ActOnDuplicateDefinition(DeclSpec &DS, Decl *Prev, |
2866 | SkipBodyInfo &SkipBody); |
2867 | |
2868 | typedef void *SkippedDefinitionContext; |
2869 | |
2870 | /// Invoked when we enter a tag definition that we're skipping. |
2871 | SkippedDefinitionContext ActOnTagStartSkippedDefinition(Scope *S, Decl *TD); |
2872 | |
2873 | Decl *ActOnObjCContainerStartDefinition(Decl *IDecl); |
2874 | |
2875 | /// ActOnStartCXXMemberDeclarations - Invoked when we have parsed a |
2876 | /// C++ record definition's base-specifiers clause and are starting its |
2877 | /// member declarations. |
2878 | void ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagDecl, |
2879 | SourceLocation FinalLoc, |
2880 | bool IsFinalSpelledSealed, |
2881 | SourceLocation LBraceLoc); |
2882 | |
2883 | /// ActOnTagFinishDefinition - Invoked once we have finished parsing |
2884 | /// the definition of a tag (enumeration, class, struct, or union). |
2885 | void ActOnTagFinishDefinition(Scope *S, Decl *TagDecl, |
2886 | SourceRange BraceRange); |
2887 | |
2888 | void ActOnTagFinishSkippedDefinition(SkippedDefinitionContext Context); |
2889 | |
2890 | void ActOnObjCContainerFinishDefinition(); |
2891 | |
2892 | /// Invoked when we must temporarily exit the objective-c container |
2893 | /// scope for parsing/looking-up C constructs. |
2894 | /// |
2895 | /// Must be followed by a call to \see ActOnObjCReenterContainerContext |
2896 | void ActOnObjCTemporaryExitContainerContext(DeclContext *DC); |
2897 | void ActOnObjCReenterContainerContext(DeclContext *DC); |
2898 | |
2899 | /// ActOnTagDefinitionError - Invoked when there was an unrecoverable |
2900 | /// error parsing the definition of a tag. |
2901 | void ActOnTagDefinitionError(Scope *S, Decl *TagDecl); |
2902 | |
2903 | EnumConstantDecl *CheckEnumConstant(EnumDecl *Enum, |
2904 | EnumConstantDecl *LastEnumConst, |
2905 | SourceLocation IdLoc, |
2906 | IdentifierInfo *Id, |
2907 | Expr *val); |
2908 | bool CheckEnumUnderlyingType(TypeSourceInfo *TI); |
2909 | bool CheckEnumRedeclaration(SourceLocation EnumLoc, bool IsScoped, |
2910 | QualType EnumUnderlyingTy, bool IsFixed, |
2911 | const EnumDecl *Prev); |
2912 | |
2913 | /// Determine whether the body of an anonymous enumeration should be skipped. |
2914 | /// \param II The name of the first enumerator. |
2915 | SkipBodyInfo shouldSkipAnonEnumBody(Scope *S, IdentifierInfo *II, |
2916 | SourceLocation IILoc); |
2917 | |
2918 | Decl *ActOnEnumConstant(Scope *S, Decl *EnumDecl, Decl *LastEnumConstant, |
2919 | SourceLocation IdLoc, IdentifierInfo *Id, |
2920 | const ParsedAttributesView &Attrs, |
2921 | SourceLocation EqualLoc, Expr *Val); |
2922 | void ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, |
2923 | Decl *EnumDecl, ArrayRef<Decl *> Elements, Scope *S, |
2924 | const ParsedAttributesView &Attr); |
2925 | |
2926 | /// Set the current declaration context until it gets popped. |
2927 | void PushDeclContext(Scope *S, DeclContext *DC); |
2928 | void PopDeclContext(); |
2929 | |
2930 | /// EnterDeclaratorContext - Used when we must lookup names in the context |
2931 | /// of a declarator's nested name specifier. |
2932 | void EnterDeclaratorContext(Scope *S, DeclContext *DC); |
2933 | void ExitDeclaratorContext(Scope *S); |
2934 | |
2935 | /// Enter a template parameter scope, after it's been associated with a particular |
2936 | /// DeclContext. Causes lookup within the scope to chain through enclosing contexts |
2937 | /// in the correct order. |
2938 | void EnterTemplatedContext(Scope *S, DeclContext *DC); |
2939 | |
2940 | /// Push the parameters of D, which must be a function, into scope. |
2941 | void ActOnReenterFunctionContext(Scope* S, Decl* D); |
2942 | void ActOnExitFunctionContext(); |
2943 | |
2944 | DeclContext *getFunctionLevelDeclContext(); |
2945 | |
2946 | /// getCurFunctionDecl - If inside of a function body, this returns a pointer |
2947 | /// to the function decl for the function being parsed. If we're currently |
2948 | /// in a 'block', this returns the containing context. |
2949 | FunctionDecl *getCurFunctionDecl(); |
2950 | |
2951 | /// getCurMethodDecl - If inside of a method body, this returns a pointer to |
2952 | /// the method decl for the method being parsed. If we're currently |
2953 | /// in a 'block', this returns the containing context. |
2954 | ObjCMethodDecl *getCurMethodDecl(); |
2955 | |
2956 | /// getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method |
2957 | /// or C function we're in, otherwise return null. If we're currently |
2958 | /// in a 'block', this returns the containing context. |
2959 | NamedDecl *getCurFunctionOrMethodDecl(); |
2960 | |
2961 | /// Add this decl to the scope shadowed decl chains. |
2962 | void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext = true); |
2963 | |
2964 | /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true |
2965 | /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns |
2966 | /// true if 'D' belongs to the given declaration context. |
2967 | /// |
2968 | /// \param AllowInlineNamespace If \c true, allow the declaration to be in the |
2969 | /// enclosing namespace set of the context, rather than contained |
2970 | /// directly within it. |
2971 | bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S = nullptr, |
2972 | bool AllowInlineNamespace = false); |
2973 | |
2974 | /// Finds the scope corresponding to the given decl context, if it |
2975 | /// happens to be an enclosing scope. Otherwise return NULL. |
2976 | static Scope *getScopeForDeclContext(Scope *S, DeclContext *DC); |
2977 | |
2978 | /// Subroutines of ActOnDeclarator(). |
2979 | TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T, |
2980 | TypeSourceInfo *TInfo); |
2981 | bool isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New); |
2982 | |
2983 | /// Describes the kind of merge to perform for availability |
2984 | /// attributes (including "deprecated", "unavailable", and "availability"). |
2985 | enum AvailabilityMergeKind { |
2986 | /// Don't merge availability attributes at all. |
2987 | AMK_None, |
2988 | /// Merge availability attributes for a redeclaration, which requires |
2989 | /// an exact match. |
2990 | AMK_Redeclaration, |
2991 | /// Merge availability attributes for an override, which requires |
2992 | /// an exact match or a weakening of constraints. |
2993 | AMK_Override, |
2994 | /// Merge availability attributes for an implementation of |
2995 | /// a protocol requirement. |
2996 | AMK_ProtocolImplementation, |
2997 | }; |
2998 | |
2999 | /// Describes the kind of priority given to an availability attribute. |
3000 | /// |
3001 | /// The sum of priorities deteremines the final priority of the attribute. |
3002 | /// The final priority determines how the attribute will be merged. |
3003 | /// An attribute with a lower priority will always remove higher priority |
3004 | /// attributes for the specified platform when it is being applied. An |
3005 | /// attribute with a higher priority will not be applied if the declaration |
3006 | /// already has an availability attribute with a lower priority for the |
3007 | /// specified platform. The final prirority values are not expected to match |
3008 | /// the values in this enumeration, but instead should be treated as a plain |
3009 | /// integer value. This enumeration just names the priority weights that are |
3010 | /// used to calculate that final vaue. |
3011 | enum AvailabilityPriority : int { |
3012 | /// The availability attribute was specified explicitly next to the |
3013 | /// declaration. |
3014 | AP_Explicit = 0, |
3015 | |
3016 | /// The availability attribute was applied using '#pragma clang attribute'. |
3017 | AP_PragmaClangAttribute = 1, |
3018 | |
3019 | /// The availability attribute for a specific platform was inferred from |
3020 | /// an availability attribute for another platform. |
3021 | AP_InferredFromOtherPlatform = 2 |
3022 | }; |
3023 | |
3024 | /// Attribute merging methods. Return true if a new attribute was added. |
3025 | AvailabilityAttr * |
3026 | mergeAvailabilityAttr(NamedDecl *D, const AttributeCommonInfo &CI, |
3027 | IdentifierInfo *Platform, bool Implicit, |
3028 | VersionTuple Introduced, VersionTuple Deprecated, |
3029 | VersionTuple Obsoleted, bool IsUnavailable, |
3030 | StringRef Message, bool IsStrict, StringRef Replacement, |
3031 | AvailabilityMergeKind AMK, int Priority); |
3032 | TypeVisibilityAttr * |
3033 | mergeTypeVisibilityAttr(Decl *D, const AttributeCommonInfo &CI, |
3034 | TypeVisibilityAttr::VisibilityType Vis); |
3035 | VisibilityAttr *mergeVisibilityAttr(Decl *D, const AttributeCommonInfo &CI, |
3036 | VisibilityAttr::VisibilityType Vis); |
3037 | UuidAttr *mergeUuidAttr(Decl *D, const AttributeCommonInfo &CI, |
3038 | StringRef UuidAsWritten, MSGuidDecl *GuidDecl); |
3039 | DLLImportAttr *mergeDLLImportAttr(Decl *D, const AttributeCommonInfo &CI); |
3040 | DLLExportAttr *mergeDLLExportAttr(Decl *D, const AttributeCommonInfo &CI); |
3041 | MSInheritanceAttr *mergeMSInheritanceAttr(Decl *D, |
3042 | const AttributeCommonInfo &CI, |
3043 | bool BestCase, |
3044 | MSInheritanceModel Model); |
3045 | FormatAttr *mergeFormatAttr(Decl *D, const AttributeCommonInfo &CI, |
3046 | IdentifierInfo *Format, int FormatIdx, |
3047 | int FirstArg); |
3048 | SectionAttr *mergeSectionAttr(Decl *D, const AttributeCommonInfo &CI, |
3049 | StringRef Name); |
3050 | CodeSegAttr *mergeCodeSegAttr(Decl *D, const AttributeCommonInfo &CI, |
3051 | StringRef Name); |
3052 | AlwaysInlineAttr *mergeAlwaysInlineAttr(Decl *D, |
3053 | const AttributeCommonInfo &CI, |
3054 | const IdentifierInfo *Ident); |
3055 | MinSizeAttr *mergeMinSizeAttr(Decl *D, const AttributeCommonInfo &CI); |
3056 | NoSpeculativeLoadHardeningAttr * |
3057 | mergeNoSpeculativeLoadHardeningAttr(Decl *D, |
3058 | const NoSpeculativeLoadHardeningAttr &AL); |
3059 | SpeculativeLoadHardeningAttr * |
3060 | mergeSpeculativeLoadHardeningAttr(Decl *D, |
3061 | const SpeculativeLoadHardeningAttr &AL); |
3062 | OptimizeNoneAttr *mergeOptimizeNoneAttr(Decl *D, |
3063 | const AttributeCommonInfo &CI); |
3064 | InternalLinkageAttr *mergeInternalLinkageAttr(Decl *D, const ParsedAttr &AL); |
3065 | InternalLinkageAttr *mergeInternalLinkageAttr(Decl *D, |
3066 | const InternalLinkageAttr &AL); |
3067 | CommonAttr *mergeCommonAttr(Decl *D, const ParsedAttr &AL); |
3068 | CommonAttr *mergeCommonAttr(Decl *D, const CommonAttr &AL); |
3069 | WebAssemblyImportNameAttr *mergeImportNameAttr( |
3070 | Decl *D, const WebAssemblyImportNameAttr &AL); |
3071 | WebAssemblyImportModuleAttr *mergeImportModuleAttr( |
3072 | Decl *D, const WebAssemblyImportModuleAttr &AL); |
3073 | |
3074 | void mergeDeclAttributes(NamedDecl *New, Decl *Old, |
3075 | AvailabilityMergeKind AMK = AMK_Redeclaration); |
3076 | void MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New, |
3077 | LookupResult &OldDecls); |
3078 | bool MergeFunctionDecl(FunctionDecl *New, NamedDecl *&Old, Scope *S, |
3079 | bool MergeTypeWithOld); |
3080 | bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old, |
3081 | Scope *S, bool MergeTypeWithOld); |
3082 | void mergeObjCMethodDecls(ObjCMethodDecl *New, ObjCMethodDecl *Old); |
3083 | void MergeVarDecl(VarDecl *New, LookupResult &Previous); |
3084 | void MergeVarDeclTypes(VarDecl *New, VarDecl *Old, bool MergeTypeWithOld); |
3085 | void MergeVarDeclExceptionSpecs(VarDecl *New, VarDecl *Old); |
3086 | bool checkVarDeclRedefinition(VarDecl *OldDefn, VarDecl *NewDefn); |
3087 | void notePreviousDefinition(const NamedDecl *Old, SourceLocation New); |
3088 | bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, Scope *S); |
3089 | |
3090 | // AssignmentAction - This is used by all the assignment diagnostic functions |
3091 | // to represent what is actually causing the operation |
3092 | enum AssignmentAction { |
3093 | AA_Assigning, |
3094 | AA_Passing, |
3095 | AA_Returning, |
3096 | AA_Converting, |
3097 | AA_Initializing, |
3098 | AA_Sending, |
3099 | AA_Casting, |
3100 | AA_Passing_CFAudited |
3101 | }; |
3102 | |
3103 | /// C++ Overloading. |
3104 | enum OverloadKind { |
3105 | /// This is a legitimate overload: the existing declarations are |
3106 | /// functions or function templates with different signatures. |
3107 | Ovl_Overload, |
3108 | |
3109 | /// This is not an overload because the signature exactly matches |
3110 | /// an existing declaration. |
3111 | Ovl_Match, |
3112 | |
3113 | /// This is not an overload because the lookup results contain a |
3114 | /// non-function. |
3115 | Ovl_NonFunction |
3116 | }; |
3117 | OverloadKind CheckOverload(Scope *S, |
3118 | FunctionDecl *New, |
3119 | const LookupResult &OldDecls, |
3120 | NamedDecl *&OldDecl, |
3121 | bool IsForUsingDecl); |
3122 | bool IsOverload(FunctionDecl *New, FunctionDecl *Old, bool IsForUsingDecl, |
3123 | bool ConsiderCudaAttrs = true, |
3124 | bool ConsiderRequiresClauses = true); |
3125 | |
3126 | enum class AllowedExplicit { |
3127 | /// Allow no explicit functions to be used. |
3128 | None, |
3129 | /// Allow explicit conversion functions but not explicit constructors. |
3130 | Conversions, |
3131 | /// Allow both explicit conversion functions and explicit constructors. |
3132 | All |
3133 | }; |
3134 | |
3135 | ImplicitConversionSequence |
3136 | TryImplicitConversion(Expr *From, QualType ToType, |
3137 | bool SuppressUserConversions, |
3138 | AllowedExplicit AllowExplicit, |
3139 | bool InOverloadResolution, |
3140 | bool CStyle, |
3141 | bool AllowObjCWritebackConversion); |
3142 | |
3143 | bool IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType); |
3144 | bool IsFloatingPointPromotion(QualType FromType, QualType ToType); |
3145 | bool IsComplexPromotion(QualType FromType, QualType ToType); |
3146 | bool IsPointerConversion(Expr *From, QualType FromType, QualType ToType, |
3147 | bool InOverloadResolution, |
3148 | QualType& ConvertedType, bool &IncompatibleObjC); |
3149 | bool isObjCPointerConversion(QualType FromType, QualType ToType, |
3150 | QualType& ConvertedType, bool &IncompatibleObjC); |
3151 | bool isObjCWritebackConversion(QualType FromType, QualType ToType, |
3152 | QualType &ConvertedType); |
3153 | bool IsBlockPointerConversion(QualType FromType, QualType ToType, |
3154 | QualType& ConvertedType); |
3155 | bool FunctionParamTypesAreEqual(const FunctionProtoType *OldType, |
3156 | const FunctionProtoType *NewType, |
3157 | unsigned *ArgPos = nullptr); |
3158 | void HandleFunctionTypeMismatch(PartialDiagnostic &PDiag, |
3159 | QualType FromType, QualType ToType); |
3160 | |
3161 | void maybeExtendBlockObject(ExprResult &E); |
3162 | CastKind PrepareCastToObjCObjectPointer(ExprResult &E); |
3163 | bool CheckPointerConversion(Expr *From, QualType ToType, |
3164 | CastKind &Kind, |
3165 | CXXCastPath& BasePath, |
3166 | bool IgnoreBaseAccess, |
3167 | bool Diagnose = true); |
3168 | bool IsMemberPointerConversion(Expr *From, QualType FromType, QualType ToType, |
3169 | bool InOverloadResolution, |
3170 | QualType &ConvertedType); |
3171 | bool CheckMemberPointerConversion(Expr *From, QualType ToType, |
3172 | CastKind &Kind, |
3173 | CXXCastPath &BasePath, |
3174 | bool IgnoreBaseAccess); |
3175 | bool IsQualificationConversion(QualType FromType, QualType ToType, |
3176 | bool CStyle, bool &ObjCLifetimeConversion); |
3177 | bool IsFunctionConversion(QualType FromType, QualType ToType, |
3178 | QualType &ResultTy); |
3179 | bool DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType); |
3180 | bool isSameOrCompatibleFunctionType(CanQualType Param, CanQualType Arg); |
3181 | |
3182 | ExprResult PerformMoveOrCopyInitialization(const InitializedEntity &Entity, |
3183 | const VarDecl *NRVOCandidate, |
3184 | QualType ResultType, |
3185 | Expr *Value, |
3186 | bool AllowNRVO = true); |
3187 | |
3188 | bool CanPerformAggregateInitializationForOverloadResolution( |
3189 | const InitializedEntity &Entity, InitListExpr *From); |
3190 | |
3191 | bool CanPerformCopyInitialization(const InitializedEntity &Entity, |
3192 | ExprResult Init); |
3193 | ExprResult PerformCopyInitialization(const InitializedEntity &Entity, |
3194 | SourceLocation EqualLoc, |
3195 | ExprResult Init, |
3196 | bool TopLevelOfInitList = false, |
3197 | bool AllowExplicit = false); |
3198 | ExprResult PerformObjectArgumentInitialization(Expr *From, |
3199 | NestedNameSpecifier *Qualifier, |
3200 | NamedDecl *FoundDecl, |
3201 | CXXMethodDecl *Method); |
3202 | |
3203 | /// Check that the lifetime of the initializer (and its subobjects) is |
3204 | /// sufficient for initializing the entity, and perform lifetime extension |
3205 | /// (when permitted) if not. |
3206 | void checkInitializerLifetime(const InitializedEntity &Entity, Expr *Init); |
3207 | |
3208 | ExprResult PerformContextuallyConvertToBool(Expr *From); |
3209 | ExprResult PerformContextuallyConvertToObjCPointer(Expr *From); |
3210 | |
3211 | /// Contexts in which a converted constant expression is required. |
3212 | enum CCEKind { |
3213 | CCEK_CaseValue, ///< Expression in a case label. |
3214 | CCEK_Enumerator, ///< Enumerator value with fixed underlying type. |
3215 | CCEK_TemplateArg, ///< Value of a non-type template parameter. |
3216 | CCEK_ArrayBound, ///< Array bound in array declarator or new-expression. |
3217 | CCEK_ConstexprIf, ///< Condition in a constexpr if statement. |
3218 | CCEK_ExplicitBool ///< Condition in an explicit(bool) specifier. |
3219 | }; |
3220 | ExprResult CheckConvertedConstantExpression(Expr *From, QualType T, |
3221 | llvm::APSInt &Value, CCEKind CCE); |
3222 | ExprResult CheckConvertedConstantExpression(Expr *From, QualType T, |
3223 | APValue &Value, CCEKind CCE); |
3224 | |
3225 | /// Abstract base class used to perform a contextual implicit |
3226 | /// conversion from an expression to any type passing a filter. |
3227 | class ContextualImplicitConverter { |
3228 | public: |
3229 | bool Suppress; |
3230 | bool SuppressConversion; |
3231 | |
3232 | ContextualImplicitConverter(bool Suppress = false, |
3233 | bool SuppressConversion = false) |
3234 | : Suppress(Suppress), SuppressConversion(SuppressConversion) {} |
3235 | |
3236 | /// Determine whether the specified type is a valid destination type |
3237 | /// for this conversion. |
3238 | virtual bool match(QualType T) = 0; |
3239 | |
3240 | /// Emits a diagnostic complaining that the expression does not have |
3241 | /// integral or enumeration type. |
3242 | virtual SemaDiagnosticBuilder |
3243 | diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) = 0; |
3244 | |
3245 | /// Emits a diagnostic when the expression has incomplete class type. |
3246 | virtual SemaDiagnosticBuilder |
3247 | diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) = 0; |
3248 | |
3249 | /// Emits a diagnostic when the only matching conversion function |
3250 | /// is explicit. |
3251 | virtual SemaDiagnosticBuilder diagnoseExplicitConv( |
3252 | Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) = 0; |
3253 | |
3254 | /// Emits a note for the explicit conversion function. |
3255 | virtual SemaDiagnosticBuilder |
3256 | noteExplicitConv(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) = 0; |
3257 | |
3258 | /// Emits a diagnostic when there are multiple possible conversion |
3259 | /// functions. |
3260 | virtual SemaDiagnosticBuilder |
3261 | diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) = 0; |
3262 | |
3263 | /// Emits a note for one of the candidate conversions. |
3264 | virtual SemaDiagnosticBuilder |
3265 | noteAmbiguous(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) = 0; |
3266 | |
3267 | /// Emits a diagnostic when we picked a conversion function |
3268 | /// (for cases when we are not allowed to pick a conversion function). |
3269 | virtual SemaDiagnosticBuilder diagnoseConversion( |
3270 | Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) = 0; |
3271 | |
3272 | virtual ~ContextualImplicitConverter() {} |
3273 | }; |
3274 | |
3275 | class ICEConvertDiagnoser : public ContextualImplicitConverter { |
3276 | bool AllowScopedEnumerations; |
3277 | |
3278 | public: |
3279 | ICEConvertDiagnoser(bool AllowScopedEnumerations, |
3280 | bool Suppress, bool SuppressConversion) |
3281 | : ContextualImplicitConverter(Suppress, SuppressConversion), |
3282 | AllowScopedEnumerations(AllowScopedEnumerations) {} |
3283 | |
3284 | /// Match an integral or (possibly scoped) enumeration type. |
3285 | bool match(QualType T) override; |
3286 | |
3287 | SemaDiagnosticBuilder |
3288 | diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) override { |
3289 | return diagnoseNotInt(S, Loc, T); |
3290 | } |
3291 | |
3292 | /// Emits a diagnostic complaining that the expression does not have |
3293 | /// integral or enumeration type. |
3294 | virtual SemaDiagnosticBuilder |
3295 | diagnoseNotInt(Sema &S, SourceLocation Loc, QualType T) = 0; |
3296 | }; |
3297 | |
3298 | /// Perform a contextual implicit conversion. |
3299 | ExprResult PerformContextualImplicitConversion( |
3300 | SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter); |
3301 | |
3302 | |
3303 | enum ObjCSubscriptKind { |
3304 | OS_Array, |
3305 | OS_Dictionary, |
3306 | OS_Error |
3307 | }; |
3308 | ObjCSubscriptKind CheckSubscriptingKind(Expr *FromE); |
3309 | |
3310 | // Note that LK_String is intentionally after the other literals, as |
3311 | // this is used for diagnostics logic. |
3312 | enum ObjCLiteralKind { |
3313 | LK_Array, |
3314 | LK_Dictionary, |
3315 | LK_Numeric, |
3316 | LK_Boxed, |
3317 | LK_String, |
3318 | LK_Block, |
3319 | LK_None |
3320 | }; |
3321 | ObjCLiteralKind CheckLiteralKind(Expr *FromE); |
3322 | |
3323 | ExprResult PerformObjectMemberConversion(Expr *From, |
3324 | NestedNameSpecifier *Qualifier, |
3325 | NamedDecl *FoundDecl, |
3326 | NamedDecl *Member); |
3327 | |
3328 | // Members have to be NamespaceDecl* or TranslationUnitDecl*. |
3329 | // TODO: make this is a typesafe union. |
3330 | typedef llvm::SmallSetVector<DeclContext *, 16> AssociatedNamespaceSet; |
3331 | typedef llvm::SmallSetVector<CXXRecordDecl *, 16> AssociatedClassSet; |
3332 | |
3333 | using ADLCallKind = CallExpr::ADLCallKind; |
3334 | |
3335 | void AddOverloadCandidate(FunctionDecl *Function, DeclAccessPair FoundDecl, |
3336 | ArrayRef<Expr *> Args, |
3337 | OverloadCandidateSet &CandidateSet, |
3338 | bool SuppressUserConversions = false, |
3339 | bool PartialOverloading = false, |
3340 | bool AllowExplicit = true, |
3341 | bool AllowExplicitConversion = false, |
3342 | ADLCallKind IsADLCandidate = ADLCallKind::NotADL, |
3343 | ConversionSequenceList EarlyConversions = None, |
3344 | OverloadCandidateParamOrder PO = {}); |
3345 | void AddFunctionCandidates(const UnresolvedSetImpl &Functions, |
3346 | ArrayRef<Expr *> Args, |
3347 | OverloadCandidateSet &CandidateSet, |
3348 | TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr, |
3349 | bool SuppressUserConversions = false, |
3350 | bool PartialOverloading = false, |
3351 | bool FirstArgumentIsBase = false); |
3352 | void AddMethodCandidate(DeclAccessPair FoundDecl, |
3353 | QualType ObjectType, |
3354 | Expr::Classification ObjectClassification, |
3355 | ArrayRef<Expr *> Args, |
3356 | OverloadCandidateSet& CandidateSet, |
3357 | bool SuppressUserConversion = false, |
3358 | OverloadCandidateParamOrder PO = {}); |
3359 | void AddMethodCandidate(CXXMethodDecl *Method, |
3360 | DeclAccessPair FoundDecl, |
3361 | CXXRecordDecl *ActingContext, QualType ObjectType, |
3362 | Expr::Classification ObjectClassification, |
3363 | ArrayRef<Expr *> Args, |
3364 | OverloadCandidateSet& CandidateSet, |
3365 | bool SuppressUserConversions = false, |
3366 | bool PartialOverloading = false, |
3367 | ConversionSequenceList EarlyConversions = None, |
3368 | OverloadCandidateParamOrder PO = {}); |
3369 | void AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl, |
3370 | DeclAccessPair FoundDecl, |
3371 | CXXRecordDecl *ActingContext, |
3372 | TemplateArgumentListInfo *ExplicitTemplateArgs, |
3373 | QualType ObjectType, |
3374 | Expr::Classification ObjectClassification, |
3375 | ArrayRef<Expr *> Args, |
3376 | OverloadCandidateSet& CandidateSet, |
3377 | bool SuppressUserConversions = false, |
3378 | bool PartialOverloading = false, |
3379 | OverloadCandidateParamOrder PO = {}); |
3380 | void AddTemplateOverloadCandidate( |
3381 | FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl, |
3382 | TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args, |
3383 | OverloadCandidateSet &CandidateSet, bool SuppressUserConversions = false, |
3384 | bool PartialOverloading = false, bool AllowExplicit = true, |
3385 | ADLCallKind IsADLCandidate = ADLCallKind::NotADL, |
3386 | OverloadCandidateParamOrder PO = {}); |
3387 | bool CheckNonDependentConversions( |
3388 | FunctionTemplateDecl *FunctionTemplate, ArrayRef<QualType> ParamTypes, |
3389 | ArrayRef<Expr *> Args, OverloadCandidateSet &CandidateSet, |
3390 | ConversionSequenceList &Conversions, bool SuppressUserConversions, |
3391 | CXXRecordDecl *ActingContext = nullptr, QualType ObjectType = QualType(), |
3392 | Expr::Classification ObjectClassification = {}, |
3393 | OverloadCandidateParamOrder PO = {}); |
3394 | void AddConversionCandidate( |
3395 | CXXConversionDecl *Conversion, DeclAccessPair FoundDecl, |
3396 | CXXRecordDecl *ActingContext, Expr *From, QualType ToType, |
3397 | OverloadCandidateSet &CandidateSet, bool AllowObjCConversionOnExplicit, |
3398 | bool AllowExplicit, bool AllowResultConversion = true); |
3399 | void AddTemplateConversionCandidate( |
3400 | FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl, |
3401 | CXXRecordDecl *ActingContext, Expr *From, QualType ToType, |
3402 | OverloadCandidateSet &CandidateSet, bool AllowObjCConversionOnExplicit, |
3403 | bool AllowExplicit, bool AllowResultConversion = true); |
3404 | void AddSurrogateCandidate(CXXConversionDecl *Conversion, |
3405 | DeclAccessPair FoundDecl, |
3406 | CXXRecordDecl *ActingContext, |
3407 | const FunctionProtoType *Proto, |
3408 | Expr *Object, ArrayRef<Expr *> Args, |
3409 | OverloadCandidateSet& CandidateSet); |
3410 | void AddNonMemberOperatorCandidates( |
3411 | const UnresolvedSetImpl &Functions, ArrayRef<Expr *> Args, |
3412 | OverloadCandidateSet &CandidateSet, |
3413 | TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr); |
3414 | void AddMemberOperatorCandidates(OverloadedOperatorKind Op, |
3415 | SourceLocation OpLoc, ArrayRef<Expr *> Args, |
3416 | OverloadCandidateSet &CandidateSet, |
3417 | OverloadCandidateParamOrder PO = {}); |
3418 | void AddBuiltinCandidate(QualType *ParamTys, ArrayRef<Expr *> Args, |
3419 | OverloadCandidateSet& CandidateSet, |
3420 | bool IsAssignmentOperator = false, |
3421 | unsigned NumContextualBoolArguments = 0); |
3422 | void AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, |
3423 | SourceLocation OpLoc, ArrayRef<Expr *> Args, |
3424 | OverloadCandidateSet& CandidateSet); |
3425 | void AddArgumentDependentLookupCandidates(DeclarationName Name, |
3426 | SourceLocation Loc, |
3427 | ArrayRef<Expr *> Args, |
3428 | TemplateArgumentListInfo *ExplicitTemplateArgs, |
3429 | OverloadCandidateSet& CandidateSet, |
3430 | bool PartialOverloading = false); |
3431 | |
3432 | // Emit as a 'note' the specific overload candidate |
3433 | void NoteOverloadCandidate( |
3434 | NamedDecl *Found, FunctionDecl *Fn, |
3435 | OverloadCandidateRewriteKind RewriteKind = OverloadCandidateRewriteKind(), |
3436 | QualType DestType = QualType(), bool TakingAddress = false); |
3437 | |
3438 | // Emit as a series of 'note's all template and non-templates identified by |
3439 | // the expression Expr |
3440 | void NoteAllOverloadCandidates(Expr *E, QualType DestType = QualType(), |
3441 | bool TakingAddress = false); |
3442 | |
3443 | /// Check the enable_if expressions on the given function. Returns the first |
3444 | /// failing attribute, or NULL if they were all successful. |
3445 | EnableIfAttr *CheckEnableIf(FunctionDecl *Function, SourceLocation CallLoc, |
3446 | ArrayRef<Expr *> Args, |
3447 | bool MissingImplicitThis = false); |
3448 | |
3449 | /// Find the failed Boolean condition within a given Boolean |
3450 | /// constant expression, and describe it with a string. |
3451 | std::pair<Expr *, std::string> findFailedBooleanCondition(Expr *Cond); |
3452 | |
3453 | /// Emit diagnostics for the diagnose_if attributes on Function, ignoring any |
3454 | /// non-ArgDependent DiagnoseIfAttrs. |
3455 | /// |
3456 | /// Argument-dependent diagnose_if attributes should be checked each time a |
3457 | /// function is used as a direct callee of a function call. |
3458 | /// |
3459 | /// Returns true if any errors were emitted. |
3460 | bool diagnoseArgDependentDiagnoseIfAttrs(const FunctionDecl *Function, |
3461 | const Expr *ThisArg, |
3462 | ArrayRef<const Expr *> Args, |
3463 | SourceLocation Loc); |
3464 | |
3465 | /// Emit diagnostics for the diagnose_if attributes on Function, ignoring any |
3466 | /// ArgDependent DiagnoseIfAttrs. |
3467 | /// |
3468 | /// Argument-independent diagnose_if attributes should be checked on every use |
3469 | /// of a function. |
3470 | /// |
3471 | /// Returns true if any errors were emitted. |
3472 | bool diagnoseArgIndependentDiagnoseIfAttrs(const NamedDecl *ND, |
3473 | SourceLocation Loc); |
3474 | |
3475 | /// Returns whether the given function's address can be taken or not, |
3476 | /// optionally emitting a diagnostic if the address can't be taken. |
3477 | /// |
3478 | /// Returns false if taking the address of the function is illegal. |
3479 | bool checkAddressOfFunctionIsAvailable(const FunctionDecl *Function, |
3480 | bool Complain = false, |
3481 | SourceLocation Loc = SourceLocation()); |
3482 | |
3483 | // [PossiblyAFunctionType] --> [Return] |
3484 | // NonFunctionType --> NonFunctionType |
3485 | // R (A) --> R(A) |
3486 | // R (*)(A) --> R (A) |
3487 | // R (&)(A) --> R (A) |
3488 | // R (S::*)(A) --> R (A) |
3489 | QualType ExtractUnqualifiedFunctionType(QualType PossiblyAFunctionType); |
3490 | |
3491 | FunctionDecl * |
3492 | ResolveAddressOfOverloadedFunction(Expr *AddressOfExpr, |
3493 | QualType TargetType, |
3494 | bool Complain, |
3495 | DeclAccessPair &Found, |
3496 | bool *pHadMultipleCandidates = nullptr); |
3497 | |
3498 | FunctionDecl * |
3499 | resolveAddressOfSingleOverloadCandidate(Expr *E, DeclAccessPair &FoundResult); |
3500 | |
3501 | bool resolveAndFixAddressOfSingleOverloadCandidate( |
3502 | ExprResult &SrcExpr, bool DoFunctionPointerConversion = false); |
3503 | |
3504 | FunctionDecl * |
3505 | ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl, |
3506 | bool Complain = false, |
3507 | DeclAccessPair *Found = nullptr); |
3508 | |
3509 | bool ResolveAndFixSingleFunctionTemplateSpecialization( |
3510 | ExprResult &SrcExpr, |
3511 | bool DoFunctionPointerConverion = false, |
3512 | bool Complain = false, |
3513 | SourceRange OpRangeForComplaining = SourceRange(), |
3514 | QualType DestTypeForComplaining = QualType(), |
3515 | unsigned DiagIDForComplaining = 0); |
3516 | |
3517 | |
3518 | Expr *FixOverloadedFunctionReference(Expr *E, |
3519 | DeclAccessPair FoundDecl, |
3520 | FunctionDecl *Fn); |
3521 | ExprResult FixOverloadedFunctionReference(ExprResult, |
3522 | DeclAccessPair FoundDecl, |
3523 | FunctionDecl *Fn); |
3524 | |
3525 | void AddOverloadedCallCandidates(UnresolvedLookupExpr *ULE, |
3526 | ArrayRef<Expr *> Args, |
3527 | OverloadCandidateSet &CandidateSet, |
3528 | bool PartialOverloading = false); |
3529 | |
3530 | // An enum used to represent the different possible results of building a |
3531 | // range-based for loop. |
3532 | enum ForRangeStatus { |
3533 | FRS_Success, |
3534 | FRS_NoViableFunction, |
3535 | FRS_DiagnosticIssued |
3536 | }; |
3537 | |
3538 | ForRangeStatus BuildForRangeBeginEndCall(SourceLocation Loc, |
3539 | SourceLocation RangeLoc, |
3540 | const DeclarationNameInfo &NameInfo, |
3541 | LookupResult &MemberLookup, |
3542 | OverloadCandidateSet *CandidateSet, |
3543 | Expr *Range, ExprResult *CallExpr); |
3544 | |
3545 | ExprResult BuildOverloadedCallExpr(Scope *S, Expr *Fn, |
3546 | UnresolvedLookupExpr *ULE, |
3547 | SourceLocation LParenLoc, |
3548 | MultiExprArg Args, |
3549 | SourceLocation RParenLoc, |
3550 | Expr *ExecConfig, |
3551 | bool AllowTypoCorrection=true, |
3552 | bool CalleesAddressIsTaken=false); |
3553 | |
3554 | bool buildOverloadedCallSet(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE, |
3555 | MultiExprArg Args, SourceLocation RParenLoc, |
3556 | OverloadCandidateSet *CandidateSet, |
3557 | ExprResult *Result); |
3558 | |
3559 | ExprResult CreateUnresolvedLookupExpr(CXXRecordDecl *NamingClass, |
3560 | NestedNameSpecifierLoc NNSLoc, |
3561 | DeclarationNameInfo DNI, |
3562 | const UnresolvedSetImpl &Fns, |
3563 | bool PerformADL = true); |
3564 | |
3565 | ExprResult CreateOverloadedUnaryOp(SourceLocation OpLoc, |
3566 | UnaryOperatorKind Opc, |
3567 | const UnresolvedSetImpl &Fns, |
3568 | Expr *input, bool RequiresADL = true); |
3569 | |
3570 | void LookupOverloadedBinOp(OverloadCandidateSet &CandidateSet, |
3571 | OverloadedOperatorKind Op, |
3572 | const UnresolvedSetImpl &Fns, |
3573 | ArrayRef<Expr *> Args, bool RequiresADL = true); |
3574 | ExprResult CreateOverloadedBinOp(SourceLocation OpLoc, |
3575 | BinaryOperatorKind Opc, |
3576 | const UnresolvedSetImpl &Fns, |
3577 | Expr *LHS, Expr *RHS, |
3578 | bool RequiresADL = true, |
3579 | bool AllowRewrittenCandidates = true, |
3580 | FunctionDecl *DefaultedFn = nullptr); |
3581 | ExprResult BuildSynthesizedThreeWayComparison(SourceLocation OpLoc, |
3582 | const UnresolvedSetImpl &Fns, |
3583 | Expr *LHS, Expr *RHS, |
3584 | FunctionDecl *DefaultedFn); |
3585 | |
3586 | ExprResult CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, |
3587 | SourceLocation RLoc, |
3588 | Expr *Base,Expr *Idx); |
3589 | |
3590 | ExprResult |
3591 | BuildCallToMemberFunction(Scope *S, Expr *MemExpr, |
3592 | SourceLocation LParenLoc, |
3593 | MultiExprArg Args, |
3594 | SourceLocation RParenLoc); |
3595 | ExprResult |
3596 | BuildCallToObjectOfClassType(Scope *S, Expr *Object, SourceLocation LParenLoc, |
3597 | MultiExprArg Args, |
3598 | SourceLocation RParenLoc); |
3599 | |
3600 | ExprResult BuildOverloadedArrowExpr(Scope *S, Expr *Base, |
3601 | SourceLocation OpLoc, |
3602 | bool *NoArrowOperatorFound = nullptr); |
3603 | |
3604 | /// CheckCallReturnType - Checks that a call expression's return type is |
3605 | /// complete. Returns true on failure. The location passed in is the location |
3606 | /// that best represents the call. |
3607 | bool CheckCallReturnType(QualType ReturnType, SourceLocation Loc, |
3608 | CallExpr *CE, FunctionDecl *FD); |
3609 | |
3610 | /// Helpers for dealing with blocks and functions. |
3611 | bool CheckParmsForFunctionDef(ArrayRef<ParmVarDecl *> Parameters, |
3612 | bool CheckParameterNames); |
3613 | void CheckCXXDefaultArguments(FunctionDecl *FD); |
3614 | void CheckExtraCXXDefaultArguments(Declarator &D); |
3615 | Scope *getNonFieldDeclScope(Scope *S); |
3616 | |
3617 | /// \name Name lookup |
3618 | /// |
3619 | /// These routines provide name lookup that is used during semantic |
3620 | /// analysis to resolve the various kinds of names (identifiers, |
3621 | /// overloaded operator names, constructor names, etc.) into zero or |
3622 | /// more declarations within a particular scope. The major entry |
3623 | /// points are LookupName, which performs unqualified name lookup, |
3624 | /// and LookupQualifiedName, which performs qualified name lookup. |
3625 | /// |
3626 | /// All name lookup is performed based on some specific criteria, |
3627 | /// which specify what names will be visible to name lookup and how |
3628 | /// far name lookup should work. These criteria are important both |
3629 | /// for capturing language semantics (certain lookups will ignore |
3630 | /// certain names, for example) and for performance, since name |
3631 | /// lookup is often a bottleneck in the compilation of C++. Name |
3632 | /// lookup criteria is specified via the LookupCriteria enumeration. |
3633 | /// |
3634 | /// The results of name lookup can vary based on the kind of name |
3635 | /// lookup performed, the current language, and the translation |
3636 | /// unit. In C, for example, name lookup will either return nothing |
3637 | /// (no entity found) or a single declaration. In C++, name lookup |
3638 | /// can additionally refer to a set of overloaded functions or |
3639 | /// result in an ambiguity. All of the possible results of name |
3640 | /// lookup are captured by the LookupResult class, which provides |
3641 | /// the ability to distinguish among them. |
3642 | //@{ |
3643 | |
3644 | /// Describes the kind of name lookup to perform. |
3645 | enum LookupNameKind { |
3646 | /// Ordinary name lookup, which finds ordinary names (functions, |
3647 | /// variables, typedefs, etc.) in C and most kinds of names |
3648 | /// (functions, variables, members, types, etc.) in C++. |
3649 | LookupOrdinaryName = 0, |
3650 | /// Tag name lookup, which finds the names of enums, classes, |
3651 | /// structs, and unions. |
3652 | LookupTagName, |
3653 | /// Label name lookup. |
3654 | LookupLabel, |
3655 | /// Member name lookup, which finds the names of |
3656 | /// class/struct/union members. |
3657 | LookupMemberName, |
3658 | /// Look up of an operator name (e.g., operator+) for use with |
3659 | /// operator overloading. This lookup is similar to ordinary name |
3660 | /// lookup, but will ignore any declarations that are class members. |
3661 | LookupOperatorName, |
3662 | /// Look up a name following ~ in a destructor name. This is an ordinary |
3663 | /// lookup, but prefers tags to typedefs. |
3664 | LookupDestructorName, |
3665 | /// Look up of a name that precedes the '::' scope resolution |
3666 | /// operator in C++. This lookup completely ignores operator, object, |
3667 | /// function, and enumerator names (C++ [basic.lookup.qual]p1). |
3668 | LookupNestedNameSpecifierName, |
3669 | /// Look up a namespace name within a C++ using directive or |
3670 | /// namespace alias definition, ignoring non-namespace names (C++ |
3671 | /// [basic.lookup.udir]p1). |
3672 | LookupNamespaceName, |
3673 | /// Look up all declarations in a scope with the given name, |
3674 | /// including resolved using declarations. This is appropriate |
3675 | /// for checking redeclarations for a using declaration. |
3676 | LookupUsingDeclName, |
3677 | /// Look up an ordinary name that is going to be redeclared as a |
3678 | /// name with linkage. This lookup ignores any declarations that |
3679 | /// are outside of the current scope unless they have linkage. See |
3680 | /// C99 6.2.2p4-5 and C++ [basic.link]p6. |
3681 | LookupRedeclarationWithLinkage, |
3682 | /// Look up a friend of a local class. This lookup does not look |
3683 | /// outside the innermost non-class scope. See C++11 [class.friend]p11. |
3684 | LookupLocalFriendName, |
3685 | /// Look up the name of an Objective-C protocol. |
3686 | LookupObjCProtocolName, |
3687 | /// Look up implicit 'self' parameter of an objective-c method. |
3688 | LookupObjCImplicitSelfParam, |
3689 | /// Look up the name of an OpenMP user-defined reduction operation. |
3690 | LookupOMPReductionName, |
3691 | /// Look up the name of an OpenMP user-defined mapper. |
3692 | LookupOMPMapperName, |
3693 | /// Look up any declaration with any name. |
3694 | LookupAnyName |
3695 | }; |
3696 | |
3697 | /// Specifies whether (or how) name lookup is being performed for a |
3698 | /// redeclaration (vs. a reference). |
3699 | enum RedeclarationKind { |
3700 | /// The lookup is a reference to this name that is not for the |
3701 | /// purpose of redeclaring the name. |
3702 | NotForRedeclaration = 0, |
3703 | /// The lookup results will be used for redeclaration of a name, |
3704 | /// if an entity by that name already exists and is visible. |
3705 | ForVisibleRedeclaration, |
3706 | /// The lookup results will be used for redeclaration of a name |
3707 | /// with external linkage; non-visible lookup results with external linkage |
3708 | /// may also be found. |
3709 | ForExternalRedeclaration |
3710 | }; |
3711 | |
3712 | RedeclarationKind forRedeclarationInCurContext() { |
3713 | // A declaration with an owning module for linkage can never link against |
3714 | // anything that is not visible. We don't need to check linkage here; if |
3715 | // the context has internal linkage, redeclaration lookup won't find things |
3716 | // from other TUs, and we can't safely compute linkage yet in general. |
3717 | if (cast<Decl>(CurContext) |
3718 | ->getOwningModuleForLinkage(/*IgnoreLinkage*/true)) |
3719 | return ForVisibleRedeclaration; |
3720 | return ForExternalRedeclaration; |
3721 | } |
3722 | |
3723 | /// The possible outcomes of name lookup for a literal operator. |
3724 | enum LiteralOperatorLookupResult { |
3725 | /// The lookup resulted in an error. |
3726 | LOLR_Error, |
3727 | /// The lookup found no match but no diagnostic was issued. |
3728 | LOLR_ErrorNoDiagnostic, |
3729 | /// The lookup found a single 'cooked' literal operator, which |
3730 | /// expects a normal literal to be built and passed to it. |
3731 | LOLR_Cooked, |
3732 | /// The lookup found a single 'raw' literal operator, which expects |
3733 | /// a string literal containing the spelling of the literal token. |
3734 | LOLR_Raw, |
3735 | /// The lookup found an overload set of literal operator templates, |
3736 | /// which expect the characters of the spelling of the literal token to be |
3737 | /// passed as a non-type template argument pack. |
3738 | LOLR_Template, |
3739 | /// The lookup found an overload set of literal operator templates, |
3740 | /// which expect the character type and characters of the spelling of the |
3741 | /// string literal token to be passed as template arguments. |
3742 | LOLR_StringTemplate |
3743 | }; |
3744 | |
3745 | SpecialMemberOverloadResult LookupSpecialMember(CXXRecordDecl *D, |
3746 | CXXSpecialMember SM, |
3747 | bool ConstArg, |
3748 | bool VolatileArg, |
3749 | bool RValueThis, |
3750 | bool ConstThis, |
3751 | bool VolatileThis); |
3752 | |
3753 | typedef std::function<void(const TypoCorrection &)> TypoDiagnosticGenerator; |
3754 | typedef std::function<ExprResult(Sema &, TypoExpr *, TypoCorrection)> |
3755 | TypoRecoveryCallback; |
3756 | |
3757 | private: |
3758 | bool CppLookupName(LookupResult &R, Scope *S); |
3759 | |
3760 | struct TypoExprState { |
3761 | std::unique_ptr<TypoCorrectionConsumer> Consumer; |
3762 | TypoDiagnosticGenerator DiagHandler; |
3763 | TypoRecoveryCallback RecoveryHandler; |
3764 | TypoExprState(); |
3765 | TypoExprState(TypoExprState &&other) noexcept; |
3766 | TypoExprState &operator=(TypoExprState &&other) noexcept; |
3767 | }; |
3768 | |
3769 | /// The set of unhandled TypoExprs and their associated state. |
3770 | llvm::MapVector<TypoExpr *, TypoExprState> DelayedTypos; |
3771 | |
3772 | /// Creates a new TypoExpr AST node. |
3773 | TypoExpr *createDelayedTypo(std::unique_ptr<TypoCorrectionConsumer> TCC, |
3774 | TypoDiagnosticGenerator TDG, |
3775 | TypoRecoveryCallback TRC, SourceLocation TypoLoc); |
3776 | |
3777 | // The set of known/encountered (unique, canonicalized) NamespaceDecls. |
3778 | // |
3779 | // The boolean value will be true to indicate that the namespace was loaded |
3780 | // from an AST/PCH file, or false otherwise. |
3781 | llvm::MapVector<NamespaceDecl*, bool> KnownNamespaces; |
3782 | |
3783 | /// Whether we have already loaded known namespaces from an extenal |
3784 | /// source. |
3785 | bool LoadedExternalKnownNamespaces; |
3786 | |
3787 | /// Helper for CorrectTypo and CorrectTypoDelayed used to create and |
3788 | /// populate a new TypoCorrectionConsumer. Returns nullptr if typo correction |
3789 | /// should be skipped entirely. |
3790 | std::unique_ptr<TypoCorrectionConsumer> |
3791 | makeTypoCorrectionConsumer(const DeclarationNameInfo &Typo, |
3792 | Sema::LookupNameKind LookupKind, Scope *S, |
3793 | CXXScopeSpec *SS, |
3794 | CorrectionCandidateCallback &CCC, |
3795 | DeclContext *MemberContext, bool EnteringContext, |
3796 | const ObjCObjectPointerType *OPT, |
3797 | bool ErrorRecovery); |
3798 | |
3799 | public: |
3800 | const TypoExprState &getTypoExprState(TypoExpr *TE) const; |
3801 | |
3802 | /// Clears the state of the given TypoExpr. |
3803 | void clearDelayedTypo(TypoExpr *TE); |
3804 | |
3805 | /// Look up a name, looking for a single declaration. Return |
3806 | /// null if the results were absent, ambiguous, or overloaded. |
3807 | /// |
3808 | /// It is preferable to use the elaborated form and explicitly handle |
3809 | /// ambiguity and overloaded. |
3810 | NamedDecl *LookupSingleName(Scope *S, DeclarationName Name, |
3811 | SourceLocation Loc, |
3812 | LookupNameKind NameKind, |
3813 | RedeclarationKind Redecl |
3814 | = NotForRedeclaration); |
3815 | bool LookupBuiltin(LookupResult &R); |
3816 | bool LookupName(LookupResult &R, Scope *S, |
3817 | bool AllowBuiltinCreation = false); |
3818 | bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, |
3819 | bool InUnqualifiedLookup = false); |
3820 | bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, |
3821 | CXXScopeSpec &SS); |
3822 | bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, |
3823 | bool AllowBuiltinCreation = false, |
3824 | bool EnteringContext = false); |
3825 | ObjCProtocolDecl *LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc, |
3826 | RedeclarationKind Redecl |
3827 | = NotForRedeclaration); |
3828 | bool LookupInSuper(LookupResult &R, CXXRecordDecl *Class); |
3829 | |
3830 | void LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S, |
3831 | UnresolvedSetImpl &Functions); |
3832 | |
3833 | LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc, |
3834 | SourceLocation GnuLabelLoc = SourceLocation()); |
3835 | |
3836 | DeclContextLookupResult LookupConstructors(CXXRecordDecl *Class); |
3837 | CXXConstructorDecl *LookupDefaultConstructor(CXXRecordDecl *Class); |
3838 | CXXConstructorDecl *LookupCopyingConstructor(CXXRecordDecl *Class, |
3839 | unsigned Quals); |
3840 | CXXMethodDecl *LookupCopyingAssignment(CXXRecordDecl *Class, unsigned Quals, |
3841 | bool RValueThis, unsigned ThisQuals); |
3842 | CXXConstructorDecl *LookupMovingConstructor(CXXRecordDecl *Class, |
3843 | unsigned Quals); |
3844 | CXXMethodDecl *LookupMovingAssignment(CXXRecordDecl *Class, unsigned Quals, |
3845 | bool RValueThis, unsigned ThisQuals); |
3846 | CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class); |
3847 | |
3848 | bool checkLiteralOperatorId(const CXXScopeSpec &SS, const UnqualifiedId &Id); |
3849 | LiteralOperatorLookupResult LookupLiteralOperator(Scope *S, LookupResult &R, |
3850 | ArrayRef<QualType> ArgTys, |
3851 | bool AllowRaw, |
3852 | bool AllowTemplate, |
3853 | bool AllowStringTemplate, |
3854 | bool DiagnoseMissing); |
3855 | bool isKnownName(StringRef name); |
3856 | |
3857 | /// Status of the function emission on the CUDA/HIP/OpenMP host/device attrs. |
3858 | enum class FunctionEmissionStatus { |
3859 | Emitted, |
3860 | CUDADiscarded, // Discarded due to CUDA/HIP hostness |
3861 | OMPDiscarded, // Discarded due to OpenMP hostness |
3862 | TemplateDiscarded, // Discarded due to uninstantiated templates |
3863 | Unknown, |
3864 | }; |
3865 | FunctionEmissionStatus getEmissionStatus(FunctionDecl *Decl, |
3866 | bool Final = false); |
3867 | |
3868 | // Whether the callee should be ignored in CUDA/HIP/OpenMP host/device check. |
3869 | bool shouldIgnoreInHostDeviceCheck(FunctionDecl *Callee); |
3870 | |
3871 | void ArgumentDependentLookup(DeclarationName Name, SourceLocation Loc, |
3872 | ArrayRef<Expr *> Args, ADLResult &Functions); |
3873 | |
3874 | void LookupVisibleDecls(Scope *S, LookupNameKind Kind, |
3875 | VisibleDeclConsumer &Consumer, |
3876 | bool IncludeGlobalScope = true, |
3877 | bool LoadExternal = true); |
3878 | void LookupVisibleDecls(DeclContext *Ctx, LookupNameKind Kind, |
3879 | VisibleDeclConsumer &Consumer, |
3880 | bool IncludeGlobalScope = true, |
3881 | bool IncludeDependentBases = false, |
3882 | bool LoadExternal = true); |
3883 | |
3884 | enum CorrectTypoKind { |
3885 | CTK_NonError, // CorrectTypo used in a non error recovery situation. |
3886 | CTK_ErrorRecovery // CorrectTypo used in normal error recovery. |
3887 | }; |
3888 | |
3889 | TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, |
3890 | Sema::LookupNameKind LookupKind, |
3891 | Scope *S, CXXScopeSpec *SS, |
3892 | CorrectionCandidateCallback &CCC, |
3893 | CorrectTypoKind Mode, |
3894 | DeclContext *MemberContext = nullptr, |
3895 | bool EnteringContext = false, |
3896 | const ObjCObjectPointerType *OPT = nullptr, |
3897 | bool RecordFailure = true); |
3898 | |
3899 | TypoExpr *CorrectTypoDelayed(const DeclarationNameInfo &Typo, |
3900 | Sema::LookupNameKind LookupKind, Scope *S, |
3901 | CXXScopeSpec *SS, |
3902 | CorrectionCandidateCallback &CCC, |
3903 | TypoDiagnosticGenerator TDG, |
3904 | TypoRecoveryCallback TRC, CorrectTypoKind Mode, |
3905 | DeclContext *MemberContext = nullptr, |
3906 | bool EnteringContext = false, |
3907 | const ObjCObjectPointerType *OPT = nullptr); |
3908 | |
3909 | /// Process any TypoExprs in the given Expr and its children, |
3910 | /// generating diagnostics as appropriate and returning a new Expr if there |
3911 | /// were typos that were all successfully corrected and ExprError if one or |
3912 | /// more typos could not be corrected. |
3913 | /// |
3914 | /// \param E The Expr to check for TypoExprs. |
3915 | /// |
3916 | /// \param InitDecl A VarDecl to avoid because the Expr being corrected is its |
3917 | /// initializer. |
3918 | /// |
3919 | /// \param RecoverUncorrectedTypos If true, when typo correction fails, it |
3920 | /// will rebuild the given Expr with all TypoExprs degraded to RecoveryExprs. |
3921 | /// |
3922 | /// \param Filter A function applied to a newly rebuilt Expr to determine if |
3923 | /// it is an acceptable/usable result from a single combination of typo |
3924 | /// corrections. As long as the filter returns ExprError, different |
3925 | /// combinations of corrections will be tried until all are exhausted. |
3926 | ExprResult CorrectDelayedTyposInExpr( |
3927 | Expr *E, VarDecl *InitDecl = nullptr, |
3928 | bool RecoverUncorrectedTypos = false, |
3929 | llvm::function_ref<ExprResult(Expr *)> Filter = |
3930 | [](Expr *E) -> ExprResult { return E; }); |
3931 | |
3932 | ExprResult CorrectDelayedTyposInExpr( |
3933 | ExprResult ER, VarDecl *InitDecl = nullptr, |
3934 | bool RecoverUncorrectedTypos = false, |
3935 | llvm::function_ref<ExprResult(Expr *)> Filter = |
3936 | [](Expr *E) -> ExprResult { return E; }) { |
3937 | return ER.isInvalid() |
3938 | ? ER |
3939 | : CorrectDelayedTyposInExpr(ER.get(), InitDecl, |
3940 | RecoverUncorrectedTypos, Filter); |
3941 | } |
3942 | |
3943 | void diagnoseTypo(const TypoCorrection &Correction, |
3944 | const PartialDiagnostic &TypoDiag, |
3945 | bool ErrorRecovery = true); |
3946 | |
3947 | void diagnoseTypo(const TypoCorrection &Correction, |
3948 | const PartialDiagnostic &TypoDiag, |
3949 | const PartialDiagnostic &PrevNote, |
3950 | bool ErrorRecovery = true); |
3951 | |
3952 | void MarkTypoCorrectedFunctionDefinition(const NamedDecl *F); |
3953 | |
3954 | void FindAssociatedClassesAndNamespaces(SourceLocation InstantiationLoc, |
3955 | ArrayRef<Expr *> Args, |
3956 | AssociatedNamespaceSet &AssociatedNamespaces, |
3957 | AssociatedClassSet &AssociatedClasses); |
3958 | |
3959 | void FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S, |
3960 | bool ConsiderLinkage, bool AllowInlineNamespace); |
3961 | |
3962 | bool CheckRedeclarationModuleOwnership(NamedDecl *New, NamedDecl *Old); |
3963 | |
3964 | void DiagnoseAmbiguousLookup(LookupResult &Result); |
3965 | //@} |
3966 | |
3967 | /// Attempts to produce a RecoveryExpr after some AST node cannot be created. |
3968 | ExprResult CreateRecoveryExpr(SourceLocation Begin, SourceLocation End, |
3969 | ArrayRef<Expr *> SubExprs, |
3970 | QualType T = QualType()); |
3971 | |
3972 | ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *&Id, |
3973 | SourceLocation IdLoc, |
3974 | bool TypoCorrection = false); |
3975 | NamedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID, |
3976 | Scope *S, bool ForRedeclaration, |
3977 | SourceLocation Loc); |
3978 | NamedDecl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II, |
3979 | Scope *S); |
3980 | void AddKnownFunctionAttributesForReplaceableGlobalAllocationFunction( |
3981 | FunctionDecl *FD); |
3982 | void AddKnownFunctionAttributes(FunctionDecl *FD); |
3983 | |
3984 | // More parsing and symbol table subroutines. |
3985 | |
3986 | void ProcessPragmaWeak(Scope *S, Decl *D); |
3987 | // Decl attributes - this routine is the top level dispatcher. |
3988 | void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD); |
3989 | // Helper for delayed processing of attributes. |
3990 | void ProcessDeclAttributeDelayed(Decl *D, |
3991 | const ParsedAttributesView &AttrList); |
3992 | void ProcessDeclAttributeList(Scope *S, Decl *D, const ParsedAttributesView &AL, |
3993 | bool IncludeCXX11Attributes = true); |
3994 | bool ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl, |
3995 | const ParsedAttributesView &AttrList); |
3996 | |
3997 | void checkUnusedDeclAttributes(Declarator &D); |
3998 | |
3999 | /// Determine if type T is a valid subject for a nonnull and similar |
4000 | /// attributes. By default, we look through references (the behavior used by |
4001 | /// nonnull), but if the second parameter is true, then we treat a reference |
4002 | /// type as valid. |
4003 | bool isValidPointerAttrType(QualType T, bool RefOkay = false); |
4004 | |
4005 | bool CheckRegparmAttr(const ParsedAttr &attr, unsigned &value); |
4006 | bool CheckCallingConvAttr(const ParsedAttr &attr, CallingConv &CC, |
4007 | const FunctionDecl *FD = nullptr); |
4008 | bool CheckAttrTarget(const ParsedAttr &CurrAttr); |
4009 | bool CheckAttrNoArgs(const ParsedAttr &CurrAttr); |
4010 | bool checkStringLiteralArgumentAttr(const ParsedAttr &Attr, unsigned ArgNum, |
4011 | StringRef &Str, |
4012 | SourceLocation *ArgLocation = nullptr); |
4013 | bool checkSectionName(SourceLocation LiteralLoc, StringRef Str); |
4014 | bool checkTargetAttr(SourceLocation LiteralLoc, StringRef Str); |
4015 | bool checkMSInheritanceAttrOnDefinition( |
4016 | CXXRecordDecl *RD, SourceRange Range, bool BestCase, |
4017 | MSInheritanceModel SemanticSpelling); |
4018 | |
4019 | void CheckAlignasUnderalignment(Decl *D); |
4020 | |
4021 | /// Adjust the calling convention of a method to be the ABI default if it |
4022 | /// wasn't specified explicitly. This handles method types formed from |
4023 | /// function type typedefs and typename template arguments. |
4024 | void adjustMemberFunctionCC(QualType &T, bool IsStatic, bool IsCtorOrDtor, |
4025 | SourceLocation Loc); |
4026 | |
4027 | // Check if there is an explicit attribute, but only look through parens. |
4028 | // The intent is to look for an attribute on the current declarator, but not |
4029 | // one that came from a typedef. |
4030 | bool hasExplicitCallingConv(QualType T); |
4031 | |
4032 | /// Get the outermost AttributedType node that sets a calling convention. |
4033 | /// Valid types should not have multiple attributes with different CCs. |
4034 | const AttributedType *getCallingConvAttributedType(QualType T) const; |
4035 | |
4036 | /// Stmt attributes - this routine is the top level dispatcher. |
4037 | StmtResult ProcessStmtAttributes(Stmt *Stmt, |
4038 | const ParsedAttributesView &Attrs, |
4039 | SourceRange Range); |
4040 | |
4041 | void WarnConflictingTypedMethods(ObjCMethodDecl *Method, |
4042 | ObjCMethodDecl *MethodDecl, |
4043 | bool IsProtocolMethodDecl); |
4044 | |
4045 | void CheckConflictingOverridingMethod(ObjCMethodDecl *Method, |
4046 | ObjCMethodDecl *Overridden, |
4047 | bool IsProtocolMethodDecl); |
4048 | |
4049 | /// WarnExactTypedMethods - This routine issues a warning if method |
4050 | /// implementation declaration matches exactly that of its declaration. |
4051 | void WarnExactTypedMethods(ObjCMethodDecl *Method, |
4052 | ObjCMethodDecl *MethodDecl, |
4053 | bool IsProtocolMethodDecl); |
4054 | |
4055 | typedef llvm::SmallPtrSet<Selector, 8> SelectorSet; |
4056 | |
4057 | /// CheckImplementationIvars - This routine checks if the instance variables |
4058 | /// listed in the implelementation match those listed in the interface. |
4059 | void CheckImplementationIvars(ObjCImplementationDecl *ImpDecl, |
4060 | ObjCIvarDecl **Fields, unsigned nIvars, |
4061 | SourceLocation Loc); |
4062 | |
4063 | /// ImplMethodsVsClassMethods - This is main routine to warn if any method |
4064 | /// remains unimplemented in the class or category \@implementation. |
4065 | void ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl, |
4066 | ObjCContainerDecl* IDecl, |
4067 | bool IncompleteImpl = false); |
4068 | |
4069 | /// DiagnoseUnimplementedProperties - This routine warns on those properties |
4070 | /// which must be implemented by this implementation. |
4071 | void DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl, |
4072 | ObjCContainerDecl *CDecl, |
4073 | bool SynthesizeProperties); |
4074 | |
4075 | /// Diagnose any null-resettable synthesized setters. |
4076 | void diagnoseNullResettableSynthesizedSetters(const ObjCImplDecl *impDecl); |
4077 | |
4078 | /// DefaultSynthesizeProperties - This routine default synthesizes all |
4079 | /// properties which must be synthesized in the class's \@implementation. |
4080 | void DefaultSynthesizeProperties(Scope *S, ObjCImplDecl *IMPDecl, |
4081 | ObjCInterfaceDecl *IDecl, |
4082 | SourceLocation AtEnd); |
4083 | void DefaultSynthesizeProperties(Scope *S, Decl *D, SourceLocation AtEnd); |
4084 | |
4085 | /// IvarBacksCurrentMethodAccessor - This routine returns 'true' if 'IV' is |
4086 | /// an ivar synthesized for 'Method' and 'Method' is a property accessor |
4087 | /// declared in class 'IFace'. |
4088 | bool IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace, |
4089 | ObjCMethodDecl *Method, ObjCIvarDecl *IV); |
4090 | |
4091 | /// DiagnoseUnusedBackingIvarInAccessor - Issue an 'unused' warning if ivar which |
4092 | /// backs the property is not used in the property's accessor. |
4093 | void DiagnoseUnusedBackingIvarInAccessor(Scope *S, |
4094 | const ObjCImplementationDecl *ImplD); |
4095 | |
4096 | /// GetIvarBackingPropertyAccessor - If method is a property setter/getter and |
4097 | /// it property has a backing ivar, returns this ivar; otherwise, returns NULL. |
4098 | /// It also returns ivar's property on success. |
4099 | ObjCIvarDecl *GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method, |
4100 | const ObjCPropertyDecl *&PDecl) const; |
4101 | |
4102 | /// Called by ActOnProperty to handle \@property declarations in |
4103 | /// class extensions. |
4104 | ObjCPropertyDecl *HandlePropertyInClassExtension(Scope *S, |
4105 | SourceLocation AtLoc, |
4106 | SourceLocation LParenLoc, |
4107 | FieldDeclarator &FD, |
4108 | Selector GetterSel, |
4109 | SourceLocation GetterNameLoc, |
4110 | Selector SetterSel, |
4111 | SourceLocation SetterNameLoc, |
4112 | const bool isReadWrite, |
4113 | unsigned &Attributes, |
4114 | const unsigned AttributesAsWritten, |
4115 | QualType T, |
4116 | TypeSourceInfo *TSI, |
4117 | tok::ObjCKeywordKind MethodImplKind); |
4118 | |
4119 | /// Called by ActOnProperty and HandlePropertyInClassExtension to |
4120 | /// handle creating the ObjcPropertyDecl for a category or \@interface. |
4121 | ObjCPropertyDecl *CreatePropertyDecl(Scope *S, |
4122 | ObjCContainerDecl *CDecl, |
4123 | SourceLocation AtLoc, |
4124 | SourceLocation LParenLoc, |
4125 | FieldDeclarator &FD, |
4126 | Selector GetterSel, |
4127 | SourceLocation GetterNameLoc, |
4128 | Selector SetterSel, |
4129 | SourceLocation SetterNameLoc, |
4130 | const bool isReadWrite, |
4131 | const unsigned Attributes, |
4132 | const unsigned AttributesAsWritten, |
4133 | QualType T, |
4134 | TypeSourceInfo *TSI, |
4135 | tok::ObjCKeywordKind MethodImplKind, |
4136 | DeclContext *lexicalDC = nullptr); |
4137 | |
4138 | /// AtomicPropertySetterGetterRules - This routine enforces the rule (via |
4139 | /// warning) when atomic property has one but not the other user-declared |
4140 | /// setter or getter. |
4141 | void AtomicPropertySetterGetterRules(ObjCImplDecl* IMPDecl, |
4142 | ObjCInterfaceDecl* IDecl); |
4143 | |
4144 | void DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D); |
4145 | |
4146 | void DiagnoseMissingDesignatedInitOverrides( |
4147 | const ObjCImplementationDecl *ImplD, |
4148 | const ObjCInterfaceDecl *IFD); |
4149 | |
4150 | void DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, ObjCInterfaceDecl *SID); |
4151 | |
4152 | enum MethodMatchStrategy { |
4153 | MMS_loose, |
4154 | MMS_strict |
4155 | }; |
4156 | |
4157 | /// MatchTwoMethodDeclarations - Checks if two methods' type match and returns |
4158 | /// true, or false, accordingly. |
4159 | bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method, |
4160 | const ObjCMethodDecl *PrevMethod, |
4161 | MethodMatchStrategy strategy = MMS_strict); |
4162 | |
4163 | /// MatchAllMethodDeclarations - Check methods declaraed in interface or |
4164 | /// or protocol against those declared in their implementations. |
4165 | void MatchAllMethodDeclarations(const SelectorSet &InsMap, |
4166 | const SelectorSet &ClsMap, |
4167 | SelectorSet &InsMapSeen, |
4168 | SelectorSet &ClsMapSeen, |
4169 | ObjCImplDecl* IMPDecl, |
4170 | ObjCContainerDecl* IDecl, |
4171 | bool &IncompleteImpl, |
4172 | bool ImmediateClass, |
4173 | bool WarnCategoryMethodImpl=false); |
4174 | |
4175 | /// CheckCategoryVsClassMethodMatches - Checks that methods implemented in |
4176 | /// category matches with those implemented in its primary class and |
4177 | /// warns each time an exact match is found. |
4178 | void CheckCategoryVsClassMethodMatches(ObjCCategoryImplDecl *CatIMP); |
4179 | |
4180 | /// Add the given method to the list of globally-known methods. |
4181 | void addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method); |
4182 | |
4183 | /// Returns default addr space for method qualifiers. |
4184 | LangAS getDefaultCXXMethodAddrSpace() const; |
4185 | |
4186 | private: |
4187 | /// AddMethodToGlobalPool - Add an instance or factory method to the global |
4188 | /// pool. See descriptoin of AddInstanceMethodToGlobalPool. |
4189 | void AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl, bool instance); |
4190 | |
4191 | /// LookupMethodInGlobalPool - Returns the instance or factory method and |
4192 | /// optionally warns if there are multiple signatures. |
4193 | ObjCMethodDecl *LookupMethodInGlobalPool(Selector Sel, SourceRange R, |
4194 | bool receiverIdOrClass, |
4195 | bool instance); |
4196 | |
4197 | public: |
4198 | /// - Returns instance or factory methods in global method pool for |
4199 | /// given selector. It checks the desired kind first, if none is found, and |
4200 | /// parameter checkTheOther is set, it then checks the other kind. If no such |
4201 | /// method or only one method is found, function returns false; otherwise, it |
4202 | /// returns true. |
4203 | bool |
4204 | CollectMultipleMethodsInGlobalPool(Selector Sel, |
4205 | SmallVectorImpl<ObjCMethodDecl*>& Methods, |
4206 | bool InstanceFirst, bool CheckTheOther, |
4207 | const ObjCObjectType *TypeBound = nullptr); |
4208 | |
4209 | bool |
4210 | AreMultipleMethodsInGlobalPool(Selector Sel, ObjCMethodDecl *BestMethod, |
4211 | SourceRange R, bool receiverIdOrClass, |
4212 | SmallVectorImpl<ObjCMethodDecl*>& Methods); |
4213 | |
4214 | void |
4215 | DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl<ObjCMethodDecl*> &Methods, |
4216 | Selector Sel, SourceRange R, |
4217 | bool receiverIdOrClass); |
4218 | |
4219 | private: |
4220 | /// - Returns a selector which best matches given argument list or |
4221 | /// nullptr if none could be found |
4222 | ObjCMethodDecl *SelectBestMethod(Selector Sel, MultiExprArg Args, |
4223 | bool IsInstance, |
4224 | SmallVectorImpl<ObjCMethodDecl*>& Methods); |
4225 | |
4226 | |
4227 | /// Record the typo correction failure and return an empty correction. |
4228 | TypoCorrection FailedCorrection(IdentifierInfo *Typo, SourceLocation TypoLoc, |
4229 | bool RecordFailure = true) { |
4230 | if (RecordFailure) |
4231 | TypoCorrectionFailures[Typo].insert(TypoLoc); |
4232 | return TypoCorrection(); |
4233 | } |
4234 | |
4235 | public: |
4236 | /// AddInstanceMethodToGlobalPool - All instance methods in a translation |
4237 | /// unit are added to a global pool. This allows us to efficiently associate |
4238 | /// a selector with a method declaraation for purposes of typechecking |
4239 | /// messages sent to "id" (where the class of the object is unknown). |
4240 | void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false) { |
4241 | AddMethodToGlobalPool(Method, impl, /*instance*/true); |
4242 | } |
4243 | |
4244 | /// AddFactoryMethodToGlobalPool - Same as above, but for factory methods. |
4245 | void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false) { |
4246 | AddMethodToGlobalPool(Method, impl, /*instance*/false); |
4247 | } |
4248 | |
4249 | /// AddAnyMethodToGlobalPool - Add any method, instance or factory to global |
4250 | /// pool. |
4251 | void AddAnyMethodToGlobalPool(Decl *D); |
4252 | |
4253 | /// LookupInstanceMethodInGlobalPool - Returns the method and warns if |
4254 | /// there are multiple signatures. |
4255 | ObjCMethodDecl *LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R, |
4256 | bool receiverIdOrClass=false) { |
4257 | return LookupMethodInGlobalPool(Sel, R, receiverIdOrClass, |
4258 | /*instance*/true); |
4259 | } |
4260 | |
4261 | /// LookupFactoryMethodInGlobalPool - Returns the method and warns if |
4262 | /// there are multiple signatures. |
4263 | ObjCMethodDecl *LookupFactoryMethodInGlobalPool(Selector Sel, SourceRange R, |
4264 | bool receiverIdOrClass=false) { |
4265 | return LookupMethodInGlobalPool(Sel, R, receiverIdOrClass, |
4266 | /*instance*/false); |
4267 | } |
4268 | |
4269 | const ObjCMethodDecl *SelectorsForTypoCorrection(Selector Sel, |
4270 | QualType ObjectType=QualType()); |
4271 | /// LookupImplementedMethodInGlobalPool - Returns the method which has an |
4272 | /// implementation. |
4273 | ObjCMethodDecl *LookupImplementedMethodInGlobalPool(Selector Sel); |
4274 | |
4275 | /// CollectIvarsToConstructOrDestruct - Collect those ivars which require |
4276 | /// initialization. |
4277 | void CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI, |
4278 | SmallVectorImpl<ObjCIvarDecl*> &Ivars); |
4279 | |
4280 | //===--------------------------------------------------------------------===// |
4281 | // Statement Parsing Callbacks: SemaStmt.cpp. |
4282 | public: |
4283 | class FullExprArg { |
4284 | public: |
4285 | FullExprArg() : E(nullptr) { } |
4286 | FullExprArg(Sema &actions) : E(nullptr) { } |
4287 | |
4288 | ExprResult release() { |
4289 | return E; |
4290 | } |
4291 | |
4292 | Expr *get() const { return E; } |
4293 | |
4294 | Expr *operator->() { |
4295 | return E; |
4296 | } |
4297 | |
4298 | private: |
4299 | // FIXME: No need to make the entire Sema class a friend when it's just |
4300 | // Sema::MakeFullExpr that needs access to the constructor below. |
4301 | friend class Sema; |
4302 | |
4303 | explicit FullExprArg(Expr *expr) : E(expr) {} |
4304 | |
4305 | Expr *E; |
4306 | }; |
4307 | |
4308 | FullExprArg MakeFullExpr(Expr *Arg) { |
4309 | return MakeFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation()); |
4310 | } |
4311 | FullExprArg MakeFullExpr(Expr *Arg, SourceLocation CC) { |
4312 | return FullExprArg( |
4313 | ActOnFinishFullExpr(Arg, CC, /*DiscardedValue*/ false).get()); |
4314 | } |
4315 | FullExprArg MakeFullDiscardedValueExpr(Expr *Arg) { |
4316 | ExprResult FE = |
4317 | ActOnFinishFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation(), |
4318 | /*DiscardedValue*/ true); |
4319 | return FullExprArg(FE.get()); |
4320 | } |
4321 | |
4322 | StmtResult ActOnExprStmt(ExprResult Arg, bool DiscardedValue = true); |
4323 | StmtResult ActOnExprStmtError(); |
4324 | |
4325 | StmtResult ActOnNullStmt(SourceLocation SemiLoc, |
4326 | bool HasLeadingEmptyMacro = false); |
4327 | |
4328 | void ActOnStartOfCompoundStmt(bool IsStmtExpr); |
4329 | void ActOnFinishOfCompoundStmt(); |
4330 | StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, |
4331 | ArrayRef<Stmt *> Elts, bool isStmtExpr); |
4332 | |
4333 | /// A RAII object to enter scope of a compound statement. |
4334 | class CompoundScopeRAII { |
4335 | public: |
4336 | CompoundScopeRAII(Sema &S, bool IsStmtExpr = false) : S(S) { |
4337 | S.ActOnStartOfCompoundStmt(IsStmtExpr); |
4338 | } |
4339 | |
4340 | ~CompoundScopeRAII() { |
4341 | S.ActOnFinishOfCompoundStmt(); |
4342 | } |
4343 | |
4344 | private: |
4345 | Sema &S; |
4346 | }; |
4347 | |
4348 | /// An RAII helper that pops function a function scope on exit. |
4349 | struct FunctionScopeRAII { |
4350 | Sema &S; |
4351 | bool Active; |
4352 | FunctionScopeRAII(Sema &S) : S(S), Active(true) {} |
4353 | ~FunctionScopeRAII() { |
4354 | if (Active) |
4355 | S.PopFunctionScopeInfo(); |
4356 | } |
4357 | void disable() { Active = false; } |
4358 | }; |
4359 | |
4360 | StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, |
4361 | SourceLocation StartLoc, |
4362 | SourceLocation EndLoc); |
4363 | void ActOnForEachDeclStmt(DeclGroupPtrTy Decl); |
4364 | StmtResult ActOnForEachLValueExpr(Expr *E); |
4365 | ExprResult ActOnCaseExpr(SourceLocation CaseLoc, ExprResult Val); |
4366 | StmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprResult LHS, |
4367 | SourceLocation DotDotDotLoc, ExprResult RHS, |
4368 | SourceLocation ColonLoc); |
4369 | void ActOnCaseStmtBody(Stmt *CaseStmt, Stmt *SubStmt); |
4370 | |
4371 | StmtResult ActOnDefaultStmt(SourceLocation DefaultLoc, |
4372 | SourceLocation ColonLoc, |
4373 | Stmt *SubStmt, Scope *CurScope); |
4374 | StmtResult ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl, |
4375 | SourceLocation ColonLoc, Stmt *SubStmt); |
4376 | |
4377 | StmtResult ActOnAttributedStmt(SourceLocation AttrLoc, |
4378 | ArrayRef<const Attr*> Attrs, |
4379 | Stmt *SubStmt); |
4380 | |
4381 | class ConditionResult; |
4382 | StmtResult ActOnIfStmt(SourceLocation IfLoc, bool IsConstexpr, |
4383 | SourceLocation LParenLoc, Stmt *InitStmt, |
4384 | ConditionResult Cond, SourceLocation RParenLoc, |
4385 | Stmt *ThenVal, SourceLocation ElseLoc, Stmt *ElseVal); |
4386 | StmtResult BuildIfStmt(SourceLocation IfLoc, bool IsConstexpr, |
4387 | SourceLocation LParenLoc, Stmt *InitStmt, |
4388 | ConditionResult Cond, SourceLocation RParenLoc, |
4389 | Stmt *ThenVal, SourceLocation ElseLoc, Stmt *ElseVal); |
4390 | StmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, |
4391 | SourceLocation LParenLoc, Stmt *InitStmt, |
4392 | ConditionResult Cond, |
4393 | SourceLocation RParenLoc); |
4394 | StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc, |
4395 | Stmt *Switch, Stmt *Body); |
4396 | StmtResult ActOnWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc, |
4397 | ConditionResult Cond, SourceLocation RParenLoc, |
4398 | Stmt *Body); |
4399 | StmtResult ActOnDoStmt(SourceLocation DoLoc, Stmt *Body, |
4400 | SourceLocation WhileLoc, SourceLocation CondLParen, |
4401 | Expr *Cond, SourceLocation CondRParen); |
4402 | |
4403 | StmtResult ActOnForStmt(SourceLocation ForLoc, |
4404 | SourceLocation LParenLoc, |
4405 | Stmt *First, |
4406 | ConditionResult Second, |
4407 | FullExprArg Third, |
4408 | SourceLocation RParenLoc, |
4409 | Stmt *Body); |
4410 | ExprResult CheckObjCForCollectionOperand(SourceLocation forLoc, |
4411 | Expr *collection); |
4412 | StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc, |
4413 | Stmt *First, Expr *collection, |
4414 | SourceLocation RParenLoc); |
4415 | StmtResult FinishObjCForCollectionStmt(Stmt *ForCollection, Stmt *Body); |
4416 | |
4417 | enum BuildForRangeKind { |
4418 | /// Initial building of a for-range statement. |
4419 | BFRK_Build, |
4420 | /// Instantiation or recovery rebuild of a for-range statement. Don't |
4421 | /// attempt any typo-correction. |
4422 | BFRK_Rebuild, |
4423 | /// Determining whether a for-range statement could be built. Avoid any |
4424 | /// unnecessary or irreversible actions. |
4425 | BFRK_Check |
4426 | }; |
4427 | |
4428 | StmtResult ActOnCXXForRangeStmt(Scope *S, SourceLocation ForLoc, |
4429 | SourceLocation CoawaitLoc, |
4430 | Stmt *InitStmt, |
4431 | Stmt *LoopVar, |
4432 | SourceLocation ColonLoc, Expr *Collection, |
4433 | SourceLocation RParenLoc, |
4434 | BuildForRangeKind Kind); |
4435 | StmtResult BuildCXXForRangeStmt(SourceLocation ForLoc, |
4436 | SourceLocation CoawaitLoc, |
4437 | Stmt *InitStmt, |
4438 | SourceLocation ColonLoc, |
4439 | Stmt *RangeDecl, Stmt *Begin, Stmt *End, |
4440 | Expr *Cond, Expr *Inc, |
4441 | Stmt *LoopVarDecl, |
4442 | SourceLocation RParenLoc, |
4443 | BuildForRangeKind Kind); |
4444 | StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body); |
4445 | |
4446 | StmtResult ActOnGotoStmt(SourceLocation GotoLoc, |
4447 | SourceLocation LabelLoc, |
4448 | LabelDecl *TheDecl); |
4449 | StmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc, |
4450 | SourceLocation StarLoc, |
4451 | Expr *DestExp); |
4452 | StmtResult ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope); |
4453 | StmtResult ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope); |
4454 | |
4455 | void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, |
4456 | CapturedRegionKind Kind, unsigned NumParams); |
4457 | typedef std::pair<StringRef, QualType> CapturedParamNameType; |
4458 | void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, |
4459 | CapturedRegionKind Kind, |
4460 | ArrayRef<CapturedParamNameType> Params, |
4461 | unsigned OpenMPCaptureLevel = 0); |
4462 | StmtResult ActOnCapturedRegionEnd(Stmt *S); |
4463 | void ActOnCapturedRegionError(); |
4464 | RecordDecl *CreateCapturedStmtRecordDecl(CapturedDecl *&CD, |
4465 | SourceLocation Loc, |
4466 | unsigned NumParams); |
4467 | |
4468 | enum CopyElisionSemanticsKind { |
4469 | CES_Strict = 0, |
4470 | CES_AllowParameters = 1, |
4471 | CES_AllowDifferentTypes = 2, |
4472 | CES_AllowExceptionVariables = 4, |
4473 | CES_FormerDefault = (CES_AllowParameters), |
4474 | CES_Default = (CES_AllowParameters | CES_AllowDifferentTypes), |
4475 | CES_AsIfByStdMove = (CES_AllowParameters | CES_AllowDifferentTypes | |
4476 | CES_AllowExceptionVariables), |
4477 | }; |
4478 | |
4479 | VarDecl *getCopyElisionCandidate(QualType ReturnType, Expr *E, |
4480 | CopyElisionSemanticsKind CESK); |
4481 | bool isCopyElisionCandidate(QualType ReturnType, const VarDecl *VD, |
4482 | CopyElisionSemanticsKind CESK); |
4483 | |
4484 | StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, |
4485 | Scope *CurScope); |
4486 | StmtResult BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp); |
4487 | StmtResult ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp); |
4488 | |
4489 | StmtResult ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, |
4490 | bool IsVolatile, unsigned NumOutputs, |
4491 | unsigned NumInputs, IdentifierInfo **Names, |
4492 | MultiExprArg Constraints, MultiExprArg Exprs, |
4493 | Expr *AsmString, MultiExprArg Clobbers, |
4494 | unsigned NumLabels, |
4495 | SourceLocation RParenLoc); |
4496 | |
4497 | void FillInlineAsmIdentifierInfo(Expr *Res, |
4498 | llvm::InlineAsmIdentifierInfo &Info); |
4499 | ExprResult LookupInlineAsmIdentifier(CXXScopeSpec &SS, |
4500 | SourceLocation TemplateKWLoc, |
4501 | UnqualifiedId &Id, |
4502 | bool IsUnevaluatedContext); |
4503 | bool LookupInlineAsmField(StringRef Base, StringRef Member, |
4504 | unsigned &Offset, SourceLocation AsmLoc); |
4505 | ExprResult LookupInlineAsmVarDeclField(Expr *RefExpr, StringRef Member, |
4506 | SourceLocation AsmLoc); |
4507 | StmtResult ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc, |
4508 | ArrayRef<Token> AsmToks, |
4509 | StringRef AsmString, |
4510 | unsigned NumOutputs, unsigned NumInputs, |
4511 | ArrayRef<StringRef> Constraints, |
4512 | ArrayRef<StringRef> Clobbers, |
4513 | ArrayRef<Expr*> Exprs, |
4514 | SourceLocation EndLoc); |
4515 | LabelDecl *GetOrCreateMSAsmLabel(StringRef ExternalLabelName, |
4516 | SourceLocation Location, |
4517 | bool AlwaysCreate); |
4518 | |
4519 | VarDecl *BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType ExceptionType, |
4520 | SourceLocation StartLoc, |
4521 | SourceLocation IdLoc, IdentifierInfo *Id, |
4522 | bool Invalid = false); |
4523 | |
4524 | Decl *ActOnObjCExceptionDecl(Scope *S, Declarator &D); |
4525 | |
4526 | StmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc, SourceLocation RParen, |
4527 | Decl *Parm, Stmt *Body); |
4528 | |
4529 | StmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body); |
4530 | |
4531 | StmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try, |
4532 | MultiStmtArg Catch, Stmt *Finally); |
4533 | |
4534 | StmtResult BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw); |
4535 | StmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw, |
4536 | Scope *CurScope); |
4537 | ExprResult ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, |
4538 | Expr *operand); |
4539 | StmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, |
4540 | Expr *SynchExpr, |
4541 | Stmt *SynchBody); |
4542 | |
4543 | StmtResult ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body); |
4544 | |
4545 | VarDecl *BuildExceptionDeclaration(Scope *S, TypeSourceInfo *TInfo, |
4546 | SourceLocation StartLoc, |
4547 | SourceLocation IdLoc, |
4548 | IdentifierInfo *Id); |
4549 | |
4550 | Decl *ActOnExceptionDeclarator(Scope *S, Declarator &D); |
4551 | |
4552 | StmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc, |
4553 | Decl *ExDecl, Stmt *HandlerBlock); |
4554 | StmtResult ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, |
4555 | ArrayRef<Stmt *> Handlers); |
4556 | |
4557 | StmtResult ActOnSEHTryBlock(bool IsCXXTry, // try (true) or __try (false) ? |
4558 | SourceLocation TryLoc, Stmt *TryBlock, |
4559 | Stmt *Handler); |
4560 | StmtResult ActOnSEHExceptBlock(SourceLocation Loc, |
4561 | Expr *FilterExpr, |
4562 | Stmt *Block); |
4563 | void ActOnStartSEHFinallyBlock(); |
4564 | void ActOnAbortSEHFinallyBlock(); |
4565 | StmtResult ActOnFinishSEHFinallyBlock(SourceLocation Loc, Stmt *Block); |
4566 | StmtResult ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope); |
4567 | |
4568 | void DiagnoseReturnInConstructorExceptionHandler(CXXTryStmt *TryBlock); |
4569 | |
4570 | bool ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const; |
4571 | |
4572 | /// If it's a file scoped decl that must warn if not used, keep track |
4573 | /// of it. |
4574 | void MarkUnusedFileScopedDecl(const DeclaratorDecl *D); |
4575 | |
4576 | /// DiagnoseUnusedExprResult - If the statement passed in is an expression |
4577 | /// whose result is unused, warn. |
4578 | void DiagnoseUnusedExprResult(const Stmt *S); |
4579 | void DiagnoseUnusedNestedTypedefs(const RecordDecl *D); |
4580 | void DiagnoseUnusedDecl(const NamedDecl *ND); |
4581 | |
4582 | /// Emit \p DiagID if statement located on \p StmtLoc has a suspicious null |
4583 | /// statement as a \p Body, and it is located on the same line. |
4584 | /// |
4585 | /// This helps prevent bugs due to typos, such as: |
4586 | /// if (condition); |
4587 | /// do_stuff(); |
4588 | void DiagnoseEmptyStmtBody(SourceLocation StmtLoc, |
4589 | const Stmt *Body, |
4590 | unsigned DiagID); |
4591 | |
4592 | /// Warn if a for/while loop statement \p S, which is followed by |
4593 | /// \p PossibleBody, has a suspicious null statement as a body. |
4594 | void DiagnoseEmptyLoopBody(const Stmt *S, |
4595 | const Stmt *PossibleBody); |
4596 | |
4597 | /// Warn if a value is moved to itself. |
4598 | void DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, |
4599 | SourceLocation OpLoc); |
4600 | |
4601 | /// Warn if we're implicitly casting from a _Nullable pointer type to a |
4602 | /// _Nonnull one. |
4603 | void diagnoseNullableToNonnullConversion(QualType DstType, QualType SrcType, |
4604 | SourceLocation Loc); |
4605 | |
4606 | /// Warn when implicitly casting 0 to nullptr. |
4607 | void diagnoseZeroToNullptrConversion(CastKind Kind, const Expr *E); |
4608 | |
4609 | ParsingDeclState PushParsingDeclaration(sema::DelayedDiagnosticPool &pool) { |
4610 | return DelayedDiagnostics.push(pool); |
4611 | } |
4612 | void PopParsingDeclaration(ParsingDeclState state, Decl *decl); |
4613 | |
4614 | typedef ProcessingContextState ParsingClassState; |
4615 | ParsingClassState PushParsingClass() { |
4616 | ParsingClassDepth++; |
4617 | return DelayedDiagnostics.pushUndelayed(); |
4618 | } |
4619 | void PopParsingClass(ParsingClassState state) { |
4620 | ParsingClassDepth--; |
4621 | DelayedDiagnostics.popUndelayed(state); |
4622 | } |
4623 | |
4624 | void redelayDiagnostics(sema::DelayedDiagnosticPool &pool); |
4625 | |
4626 | void DiagnoseAvailabilityOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs, |
4627 | const ObjCInterfaceDecl *UnknownObjCClass, |
4628 | bool ObjCPropertyAccess, |
4629 | bool AvoidPartialAvailabilityChecks = false, |
4630 | ObjCInterfaceDecl *ClassReceiver = nullptr); |
4631 | |
4632 | bool makeUnavailableInSystemHeader(SourceLocation loc, |
4633 | UnavailableAttr::ImplicitReason reason); |
4634 | |
4635 | /// Issue any -Wunguarded-availability warnings in \c FD |
4636 | void DiagnoseUnguardedAvailabilityViolations(Decl *FD); |
4637 | |
4638 | void handleDelayedAvailabilityCheck(sema::DelayedDiagnostic &DD, Decl *Ctx); |
4639 | |
4640 | //===--------------------------------------------------------------------===// |
4641 | // Expression Parsing Callbacks: SemaExpr.cpp. |
4642 | |
4643 | bool CanUseDecl(NamedDecl *D, bool TreatUnavailableAsInvalid); |
4644 | bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs, |
4645 | const ObjCInterfaceDecl *UnknownObjCClass = nullptr, |
4646 | bool ObjCPropertyAccess = false, |
4647 | bool AvoidPartialAvailabilityChecks = false, |
4648 | ObjCInterfaceDecl *ClassReciever = nullptr); |
4649 | void NoteDeletedFunction(FunctionDecl *FD); |
4650 | void NoteDeletedInheritingConstructor(CXXConstructorDecl *CD); |
4651 | bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD, |
4652 | ObjCMethodDecl *Getter, |
4653 | SourceLocation Loc); |
4654 | void DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc, |
4655 | ArrayRef<Expr *> Args); |
4656 | |
4657 | void PushExpressionEvaluationContext( |
4658 | ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl = nullptr, |
4659 | ExpressionEvaluationContextRecord::ExpressionKind Type = |
4660 | ExpressionEvaluationContextRecord::EK_Other); |
4661 | enum ReuseLambdaContextDecl_t { ReuseLambdaContextDecl }; |
4662 | void PushExpressionEvaluationContext( |
4663 | ExpressionEvaluationContext NewContext, ReuseLambdaContextDecl_t, |
4664 | ExpressionEvaluationContextRecord::ExpressionKind Type = |
4665 | ExpressionEvaluationContextRecord::EK_Other); |
4666 | void PopExpressionEvaluationContext(); |
4667 | |
4668 | void DiscardCleanupsInEvaluationContext(); |
4669 | |
4670 | ExprResult TransformToPotentiallyEvaluated(Expr *E); |
4671 | ExprResult HandleExprEvaluationContextForTypeof(Expr *E); |
4672 | |
4673 | ExprResult CheckUnevaluatedOperand(Expr *E); |
4674 | void CheckUnusedVolatileAssignment(Expr *E); |
4675 | |
4676 | ExprResult ActOnConstantExpression(ExprResult Res); |
4677 | |
4678 | // Functions for marking a declaration referenced. These functions also |
4679 | // contain the relevant logic for marking if a reference to a function or |
4680 | // variable is an odr-use (in the C++11 sense). There are separate variants |
4681 | // for expressions referring to a decl; these exist because odr-use marking |
4682 | // needs to be delayed for some constant variables when we build one of the |
4683 | // named expressions. |
4684 | // |
4685 | // MightBeOdrUse indicates whether the use could possibly be an odr-use, and |
4686 | // should usually be true. This only needs to be set to false if the lack of |
4687 | // odr-use cannot be determined from the current context (for instance, |
4688 | // because the name denotes a virtual function and was written without an |
4689 | // explicit nested-name-specifier). |
4690 | void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool MightBeOdrUse); |
4691 | void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, |
4692 | bool MightBeOdrUse = true); |
4693 | void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var); |
4694 | void MarkDeclRefReferenced(DeclRefExpr *E, const Expr *Base = nullptr); |
4695 | void MarkMemberReferenced(MemberExpr *E); |
4696 | void MarkFunctionParmPackReferenced(FunctionParmPackExpr *E); |
4697 | void MarkCaptureUsedInEnclosingContext(VarDecl *Capture, SourceLocation Loc, |
4698 | unsigned CapturingScopeIndex); |
4699 | |
4700 | ExprResult CheckLValueToRValueConversionOperand(Expr *E); |
4701 | void CleanupVarDeclMarking(); |
4702 | |
4703 | enum TryCaptureKind { |
4704 | TryCapture_Implicit, TryCapture_ExplicitByVal, TryCapture_ExplicitByRef |
4705 | }; |
4706 | |
4707 | /// Try to capture the given variable. |
4708 | /// |
4709 | /// \param Var The variable to capture. |
4710 | /// |
4711 | /// \param Loc The location at which the capture occurs. |
4712 | /// |
4713 | /// \param Kind The kind of capture, which may be implicit (for either a |
4714 | /// block or a lambda), or explicit by-value or by-reference (for a lambda). |
4715 | /// |
4716 | /// \param EllipsisLoc The location of the ellipsis, if one is provided in |
4717 | /// an explicit lambda capture. |
4718 | /// |
4719 | /// \param BuildAndDiagnose Whether we are actually supposed to add the |
4720 | /// captures or diagnose errors. If false, this routine merely check whether |
4721 | /// the capture can occur without performing the capture itself or complaining |
4722 | /// if the variable cannot be captured. |
4723 | /// |
4724 | /// \param CaptureType Will be set to the type of the field used to capture |
4725 | /// this variable in the innermost block or lambda. Only valid when the |
4726 | /// variable can be captured. |
4727 | /// |
4728 | /// \param DeclRefType Will be set to the type of a reference to the capture |
4729 | /// from within the current scope. Only valid when the variable can be |
4730 | /// captured. |
4731 | /// |
4732 | /// \param FunctionScopeIndexToStopAt If non-null, it points to the index |
4733 | /// of the FunctionScopeInfo stack beyond which we do not attempt to capture. |
4734 | /// This is useful when enclosing lambdas must speculatively capture |
4735 | /// variables that may or may not be used in certain specializations of |
4736 | /// a nested generic lambda. |
4737 | /// |
4738 | /// \returns true if an error occurred (i.e., the variable cannot be |
4739 | /// captured) and false if the capture succeeded. |
4740 | bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc, TryCaptureKind Kind, |
4741 | SourceLocation EllipsisLoc, bool BuildAndDiagnose, |
4742 | QualType &CaptureType, |
4743 | QualType &DeclRefType, |
4744 | const unsigned *const FunctionScopeIndexToStopAt); |
4745 | |
4746 | /// Try to capture the given variable. |
4747 | bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc, |
4748 | TryCaptureKind Kind = TryCapture_Implicit, |
4749 | SourceLocation EllipsisLoc = SourceLocation()); |
4750 | |
4751 | /// Checks if the variable must be captured. |
4752 | bool NeedToCaptureVariable(VarDecl *Var, SourceLocation Loc); |
4753 | |
4754 | /// Given a variable, determine the type that a reference to that |
4755 | /// variable will have in the given scope. |
4756 | QualType getCapturedDeclRefType(VarDecl *Var, SourceLocation Loc); |
4757 | |
4758 | /// Mark all of the declarations referenced within a particular AST node as |
4759 | /// referenced. Used when template instantiation instantiates a non-dependent |
4760 | /// type -- entities referenced by the type are now referenced. |
4761 | void MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T); |
4762 | void MarkDeclarationsReferencedInExpr(Expr *E, |
4763 | bool SkipLocalVariables = false); |
4764 | |
4765 | /// Try to recover by turning the given expression into a |
4766 | /// call. Returns true if recovery was attempted or an error was |
4767 | /// emitted; this may also leave the ExprResult invalid. |
4768 | bool tryToRecoverWithCall(ExprResult &E, const PartialDiagnostic &PD, |
4769 | bool ForceComplain = false, |
4770 | bool (*IsPlausibleResult)(QualType) = nullptr); |
4771 | |
4772 | /// Figure out if an expression could be turned into a call. |
4773 | bool tryExprAsCall(Expr &E, QualType &ZeroArgCallReturnTy, |
4774 | UnresolvedSetImpl &NonTemplateOverloads); |
4775 | |
4776 | /// Try to convert an expression \p E to type \p Ty. Returns the result of the |
4777 | /// conversion. |
4778 | ExprResult tryConvertExprToType(Expr *E, QualType Ty); |
4779 | |
4780 | /// Conditionally issue a diagnostic based on the current |
4781 | /// evaluation context. |
4782 | /// |
4783 | /// \param Statement If Statement is non-null, delay reporting the |
4784 | /// diagnostic until the function body is parsed, and then do a basic |
4785 | /// reachability analysis to determine if the statement is reachable. |
4786 | /// If it is unreachable, the diagnostic will not be emitted. |
4787 | bool DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement, |
4788 | const PartialDiagnostic &PD); |
4789 | /// Similar, but diagnostic is only produced if all the specified statements |
4790 | /// are reachable. |
4791 | bool DiagRuntimeBehavior(SourceLocation Loc, ArrayRef<const Stmt*> Stmts, |
4792 | const PartialDiagnostic &PD); |
4793 | |
4794 | // Primary Expressions. |
4795 | SourceRange getExprRange(Expr *E) const; |
4796 | |
4797 | ExprResult ActOnIdExpression( |
4798 | Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, |
4799 | UnqualifiedId &Id, bool HasTrailingLParen, bool IsAddressOfOperand, |
4800 | CorrectionCandidateCallback *CCC = nullptr, |
4801 | bool IsInlineAsmIdentifier = false, Token *KeywordReplacement = nullptr); |
4802 | |
4803 | void DecomposeUnqualifiedId(const UnqualifiedId &Id, |
4804 | TemplateArgumentListInfo &Buffer, |
4805 | DeclarationNameInfo &NameInfo, |
4806 | const TemplateArgumentListInfo *&TemplateArgs); |
4807 | |
4808 | bool |
4809 | DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, |
4810 | CorrectionCandidateCallback &CCC, |
4811 | TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr, |
4812 | ArrayRef<Expr *> Args = None, TypoExpr **Out = nullptr); |
4813 | |
4814 | DeclResult LookupIvarInObjCMethod(LookupResult &Lookup, Scope *S, |
4815 | IdentifierInfo *II); |
4816 | ExprResult BuildIvarRefExpr(Scope *S, SourceLocation Loc, ObjCIvarDecl *IV); |
4817 | |
4818 | ExprResult LookupInObjCMethod(LookupResult &LookUp, Scope *S, |
4819 | IdentifierInfo *II, |
4820 | bool AllowBuiltinCreation=false); |
4821 | |
4822 | ExprResult ActOnDependentIdExpression(const CXXScopeSpec &SS, |
4823 | SourceLocation TemplateKWLoc, |
4824 | const DeclarationNameInfo &NameInfo, |
4825 | bool isAddressOfOperand, |
4826 | const TemplateArgumentListInfo *TemplateArgs); |
4827 | |
4828 | /// If \p D cannot be odr-used in the current expression evaluation context, |
4829 | /// return a reason explaining why. Otherwise, return NOUR_None. |
4830 | NonOdrUseReason getNonOdrUseReasonInCurrentContext(ValueDecl *D); |
4831 | |
4832 | DeclRefExpr *BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, |
4833 | SourceLocation Loc, |
4834 | const CXXScopeSpec *SS = nullptr); |
4835 | DeclRefExpr * |
4836 | BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, |
4837 | const DeclarationNameInfo &NameInfo, |
4838 | const CXXScopeSpec *SS = nullptr, |
4839 | NamedDecl *FoundD = nullptr, |
4840 | SourceLocation TemplateKWLoc = SourceLocation(), |
4841 | const TemplateArgumentListInfo *TemplateArgs = nullptr); |
4842 | DeclRefExpr * |
4843 | BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, |
4844 | const DeclarationNameInfo &NameInfo, |
4845 | NestedNameSpecifierLoc NNS, |
4846 | NamedDecl *FoundD = nullptr, |
4847 | SourceLocation TemplateKWLoc = SourceLocation(), |
4848 | const TemplateArgumentListInfo *TemplateArgs = nullptr); |
4849 | |
4850 | ExprResult |
4851 | BuildAnonymousStructUnionMemberReference( |
4852 | const CXXScopeSpec &SS, |
4853 | SourceLocation nameLoc, |
4854 | IndirectFieldDecl *indirectField, |
4855 | DeclAccessPair FoundDecl = DeclAccessPair::make(nullptr, AS_none), |
4856 | Expr *baseObjectExpr = nullptr, |
4857 | SourceLocation opLoc = SourceLocation()); |
4858 | |
4859 | ExprResult BuildPossibleImplicitMemberExpr( |
4860 | const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, LookupResult &R, |
4861 | const TemplateArgumentListInfo *TemplateArgs, const Scope *S, |
4862 | UnresolvedLookupExpr *AsULE = nullptr); |
4863 | ExprResult BuildImplicitMemberExpr(const CXXScopeSpec &SS, |
4864 | SourceLocation TemplateKWLoc, |
4865 | LookupResult &R, |
4866 | const TemplateArgumentListInfo *TemplateArgs, |
4867 | bool IsDefiniteInstance, |
4868 | const Scope *S); |
4869 | bool UseArgumentDependentLookup(const CXXScopeSpec &SS, |
4870 | const LookupResult &R, |
4871 | bool HasTrailingLParen); |
4872 | |
4873 | ExprResult |
4874 | BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS, |
4875 | const DeclarationNameInfo &NameInfo, |
4876 | bool IsAddressOfOperand, const Scope *S, |
4877 | TypeSourceInfo **RecoveryTSI = nullptr); |
4878 | |
4879 | ExprResult BuildDependentDeclRefExpr(const CXXScopeSpec &SS, |
4880 | SourceLocation TemplateKWLoc, |
4881 | const DeclarationNameInfo &NameInfo, |
4882 | const TemplateArgumentListInfo *TemplateArgs); |
4883 | |
4884 | ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS, |
4885 | LookupResult &R, |
4886 | bool NeedsADL, |
4887 | bool AcceptInvalidDecl = false); |
4888 | ExprResult BuildDeclarationNameExpr( |
4889 | const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, NamedDecl *D, |
4890 | NamedDecl *FoundD = nullptr, |
4891 | const TemplateArgumentListInfo *TemplateArgs = nullptr, |
4892 | bool AcceptInvalidDecl = false); |
4893 | |
4894 | ExprResult BuildLiteralOperatorCall(LookupResult &R, |
4895 | DeclarationNameInfo &SuffixInfo, |
4896 | ArrayRef<Expr *> Args, |
4897 | SourceLocation LitEndLoc, |
4898 | TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr); |
4899 | |
4900 | ExprResult BuildPredefinedExpr(SourceLocation Loc, |
4901 | PredefinedExpr::IdentKind IK); |
4902 | ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind); |
4903 | ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val); |
4904 | |
4905 | ExprResult BuildUniqueStableName(SourceLocation Loc, TypeSourceInfo *Operand); |
4906 | ExprResult BuildUniqueStableName(SourceLocation Loc, Expr *E); |
4907 | ExprResult ActOnUniqueStableNameExpr(SourceLocation OpLoc, |
4908 | SourceLocation LParen, |
4909 | SourceLocation RParen, ParsedType Ty); |
4910 | ExprResult ActOnUniqueStableNameExpr(SourceLocation OpLoc, |
4911 | SourceLocation LParen, |
4912 | SourceLocation RParen, Expr *E); |
4913 | |
4914 | bool CheckLoopHintExpr(Expr *E, SourceLocation Loc); |
4915 | |
4916 | ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope = nullptr); |
4917 | ExprResult ActOnCharacterConstant(const Token &Tok, |
4918 | Scope *UDLScope = nullptr); |
4919 | ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E); |
4920 | ExprResult ActOnParenListExpr(SourceLocation L, |
4921 | SourceLocation R, |
4922 | MultiExprArg Val); |
4923 | |
4924 | /// ActOnStringLiteral - The specified tokens were lexed as pasted string |
4925 | /// fragments (e.g. "foo" "bar" L"baz"). |
4926 | ExprResult ActOnStringLiteral(ArrayRef<Token> StringToks, |
4927 | Scope *UDLScope = nullptr); |
4928 | |
4929 | ExprResult ActOnGenericSelectionExpr(SourceLocation KeyLoc, |
4930 | SourceLocation DefaultLoc, |
4931 | SourceLocation RParenLoc, |
4932 | Expr *ControllingExpr, |
4933 | ArrayRef<ParsedType> ArgTypes, |
4934 | ArrayRef<Expr *> ArgExprs); |
4935 | ExprResult CreateGenericSelectionExpr(SourceLocation KeyLoc, |
4936 | SourceLocation DefaultLoc, |
4937 | SourceLocation RParenLoc, |
4938 | Expr *ControllingExpr, |
4939 | ArrayRef<TypeSourceInfo *> Types, |
4940 | ArrayRef<Expr *> Exprs); |
4941 | |
4942 | // Binary/Unary Operators. 'Tok' is the token for the operator. |
4943 | ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, |
4944 | Expr *InputExpr); |
4945 | ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, |
4946 | UnaryOperatorKind Opc, Expr *Input); |
4947 | ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, |
4948 | tok::TokenKind Op, Expr *Input); |
4949 | |
4950 | bool isQualifiedMemberAccess(Expr *E); |
4951 | QualType CheckAddressOfOperand(ExprResult &Operand, SourceLocation OpLoc); |
4952 | |
4953 | ExprResult CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo, |
4954 | SourceLocation OpLoc, |
4955 | UnaryExprOrTypeTrait ExprKind, |
4956 | SourceRange R); |
4957 | ExprResult CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc, |
4958 | UnaryExprOrTypeTrait ExprKind); |
4959 | ExprResult |
4960 | ActOnUnaryExprOrTypeTraitExpr(SourceLocation OpLoc, |
4961 | UnaryExprOrTypeTrait ExprKind, |
4962 | bool IsType, void *TyOrEx, |
4963 | SourceRange ArgRange); |
4964 | |
4965 | ExprResult CheckPlaceholderExpr(Expr *E); |
4966 | bool CheckVecStepExpr(Expr *E); |
4967 | |
4968 | bool CheckUnaryExprOrTypeTraitOperand(Expr *E, UnaryExprOrTypeTrait ExprKind); |
4969 | bool CheckUnaryExprOrTypeTraitOperand(QualType ExprType, SourceLocation OpLoc, |
4970 | SourceRange ExprRange, |
4971 | UnaryExprOrTypeTrait ExprKind); |
4972 | ExprResult ActOnSizeofParameterPackExpr(Scope *S, |
4973 | SourceLocation OpLoc, |
4974 | IdentifierInfo &Name, |
4975 | SourceLocation NameLoc, |
4976 | SourceLocation RParenLoc); |
4977 | ExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc, |
4978 | tok::TokenKind Kind, Expr *Input); |
4979 | |
4980 | ExprResult ActOnArraySubscriptExpr(Scope *S, Expr *Base, SourceLocation LLoc, |
4981 | Expr *Idx, SourceLocation RLoc); |
4982 | ExprResult CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, |
4983 | Expr *Idx, SourceLocation RLoc); |
4984 | |
4985 | ExprResult CreateBuiltinMatrixSubscriptExpr(Expr *Base, Expr *RowIdx, |
4986 | Expr *ColumnIdx, |
4987 | SourceLocation RBLoc); |
4988 | |
4989 | ExprResult ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, |
4990 | Expr *LowerBound, |
4991 | SourceLocation ColonLocFirst, |
4992 | SourceLocation ColonLocSecond, |
4993 | Expr *Length, Expr *Stride, |
4994 | SourceLocation RBLoc); |
4995 | ExprResult ActOnOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc, |
4996 | SourceLocation RParenLoc, |
4997 | ArrayRef<Expr *> Dims, |
4998 | ArrayRef<SourceRange> Brackets); |
4999 | |
5000 | /// Data structure for iterator expression. |
5001 | struct OMPIteratorData { |
5002 | IdentifierInfo *DeclIdent = nullptr; |
5003 | SourceLocation DeclIdentLoc; |
5004 | ParsedType Type; |
5005 | OMPIteratorExpr::IteratorRange Range; |
5006 | SourceLocation AssignLoc; |
5007 | SourceLocation ColonLoc; |
5008 | SourceLocation SecColonLoc; |
5009 | }; |
5010 | |
5011 | ExprResult ActOnOMPIteratorExpr(Scope *S, SourceLocation IteratorKwLoc, |
5012 | SourceLocation LLoc, SourceLocation RLoc, |
5013 | ArrayRef<OMPIteratorData> Data); |
5014 | |
5015 | // This struct is for use by ActOnMemberAccess to allow |
5016 | // BuildMemberReferenceExpr to be able to reinvoke ActOnMemberAccess after |
5017 | // changing the access operator from a '.' to a '->' (to see if that is the |
5018 | // change needed to fix an error about an unknown member, e.g. when the class |
5019 | // defines a custom operator->). |
5020 | struct ActOnMemberAccessExtraArgs { |
5021 | Scope *S; |
5022 | UnqualifiedId &Id; |
5023 | Decl *ObjCImpDecl; |
5024 | }; |
5025 | |
5026 | ExprResult BuildMemberReferenceExpr( |
5027 | Expr *Base, QualType BaseType, SourceLocation OpLoc, bool IsArrow, |
5028 | CXXScopeSpec &SS, SourceLocation TemplateKWLoc, |
5029 | NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo, |
5030 | const TemplateArgumentListInfo *TemplateArgs, |
5031 | const Scope *S, |
5032 | ActOnMemberAccessExtraArgs *ExtraArgs = nullptr); |
5033 | |
5034 | ExprResult |
5035 | BuildMemberReferenceExpr(Expr *Base, QualType BaseType, SourceLocation OpLoc, |
5036 | bool IsArrow, const CXXScopeSpec &SS, |
5037 | SourceLocation TemplateKWLoc, |
5038 | NamedDecl *FirstQualifierInScope, LookupResult &R, |
5039 | const TemplateArgumentListInfo *TemplateArgs, |
5040 | const Scope *S, |
5041 | bool SuppressQualifierCheck = false, |
5042 | ActOnMemberAccessExtraArgs *ExtraArgs = nullptr); |
5043 | |
5044 | ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, |
5045 | SourceLocation OpLoc, |
5046 | const CXXScopeSpec &SS, FieldDecl *Field, |
5047 | DeclAccessPair FoundDecl, |
5048 | const DeclarationNameInfo &MemberNameInfo); |
5049 | |
5050 | ExprResult PerformMemberExprBaseConversion(Expr *Base, bool IsArrow); |
5051 | |
5052 | bool CheckQualifiedMemberReference(Expr *BaseExpr, QualType BaseType, |
5053 | const CXXScopeSpec &SS, |
5054 | const LookupResult &R); |
5055 | |
5056 | ExprResult ActOnDependentMemberExpr(Expr *Base, QualType BaseType, |
5057 | bool IsArrow, SourceLocation OpLoc, |
5058 | const CXXScopeSpec &SS, |
5059 | SourceLocation TemplateKWLoc, |
5060 | NamedDecl *FirstQualifierInScope, |
5061 | const DeclarationNameInfo &NameInfo, |
5062 | const TemplateArgumentListInfo *TemplateArgs); |
5063 | |
5064 | ExprResult ActOnMemberAccessExpr(Scope *S, Expr *Base, |
5065 | SourceLocation OpLoc, |
5066 | tok::TokenKind OpKind, |
5067 | CXXScopeSpec &SS, |
5068 | SourceLocation TemplateKWLoc, |
5069 | UnqualifiedId &Member, |
5070 | Decl *ObjCImpDecl); |
5071 | |
5072 | MemberExpr * |
5073 | BuildMemberExpr(Expr *Base, bool IsArrow, SourceLocation OpLoc, |
5074 | const CXXScopeSpec *SS, SourceLocation TemplateKWLoc, |
5075 | ValueDecl *Member, DeclAccessPair FoundDecl, |
5076 | bool HadMultipleCandidates, |
5077 | const DeclarationNameInfo &MemberNameInfo, QualType Ty, |
5078 | ExprValueKind VK, ExprObjectKind OK, |
5079 | const TemplateArgumentListInfo *TemplateArgs = nullptr); |
5080 | MemberExpr * |
5081 | BuildMemberExpr(Expr *Base, bool IsArrow, SourceLocation OpLoc, |
5082 | NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc, |
5083 | ValueDecl *Member, DeclAccessPair FoundDecl, |
5084 | bool HadMultipleCandidates, |
5085 | const DeclarationNameInfo &MemberNameInfo, QualType Ty, |
5086 | ExprValueKind VK, ExprObjectKind OK, |
5087 | const TemplateArgumentListInfo *TemplateArgs = nullptr); |
5088 | |
5089 | void ActOnDefaultCtorInitializers(Decl *CDtorDecl); |
5090 | bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, |
5091 | FunctionDecl *FDecl, |
5092 | const FunctionProtoType *Proto, |
5093 | ArrayRef<Expr *> Args, |
5094 | SourceLocation RParenLoc, |
5095 | bool ExecConfig = false); |
5096 | void CheckStaticArrayArgument(SourceLocation CallLoc, |
5097 | ParmVarDecl *Param, |
5098 | const Expr *ArgExpr); |
5099 | |
5100 | /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments. |
5101 | /// This provides the location of the left/right parens and a list of comma |
5102 | /// locations. |
5103 | ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, |
5104 | MultiExprArg ArgExprs, SourceLocation RParenLoc, |
5105 | Expr *ExecConfig = nullptr); |
5106 | ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, |
5107 | MultiExprArg ArgExprs, SourceLocation RParenLoc, |
5108 | Expr *ExecConfig = nullptr, |
5109 | bool IsExecConfig = false); |
5110 | enum class AtomicArgumentOrder { API, AST }; |
5111 | ExprResult |
5112 | BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, |
5113 | SourceLocation RParenLoc, MultiExprArg Args, |
5114 | AtomicExpr::AtomicOp Op, |
5115 | AtomicArgumentOrder ArgOrder = AtomicArgumentOrder::API); |
5116 | ExprResult |
5117 | BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, SourceLocation LParenLoc, |
5118 | ArrayRef<Expr *> Arg, SourceLocation RParenLoc, |
5119 | Expr *Config = nullptr, bool IsExecConfig = false, |
5120 | ADLCallKind UsesADL = ADLCallKind::NotADL); |
5121 | |
5122 | ExprResult ActOnCUDAExecConfigExpr(Scope *S, SourceLocation LLLLoc, |
5123 | MultiExprArg ExecConfig, |
5124 | SourceLocation GGGLoc); |
5125 | |
5126 | ExprResult ActOnCastExpr(Scope *S, SourceLocation LParenLoc, |
5127 | Declarator &D, ParsedType &Ty, |
5128 | SourceLocation RParenLoc, Expr *CastExpr); |
5129 | ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, |
5130 | TypeSourceInfo *Ty, |
5131 | SourceLocation RParenLoc, |
5132 | Expr *Op); |
5133 | CastKind PrepareScalarCast(ExprResult &src, QualType destType); |
5134 | |
5135 | /// Build an altivec or OpenCL literal. |
5136 | ExprResult BuildVectorLiteral(SourceLocation LParenLoc, |
5137 | SourceLocation RParenLoc, Expr *E, |
5138 | TypeSourceInfo *TInfo); |
5139 | |
5140 | ExprResult MaybeConvertParenListExprToParenExpr(Scope *S, Expr *ME); |
5141 | |
5142 | ExprResult ActOnCompoundLiteral(SourceLocation LParenLoc, |
5143 | ParsedType Ty, |
5144 | SourceLocation RParenLoc, |
5145 | Expr *InitExpr); |
5146 | |
5147 | ExprResult BuildCompoundLiteralExpr(SourceLocation LParenLoc, |
5148 | TypeSourceInfo *TInfo, |
5149 | SourceLocation RParenLoc, |
5150 | Expr *LiteralExpr); |
5151 | |
5152 | ExprResult ActOnInitList(SourceLocation LBraceLoc, |
5153 | MultiExprArg InitArgList, |
5154 | SourceLocation RBraceLoc); |
5155 | |
5156 | ExprResult BuildInitList(SourceLocation LBraceLoc, |
5157 | MultiExprArg InitArgList, |
5158 | SourceLocation RBraceLoc); |
5159 | |
5160 | ExprResult ActOnDesignatedInitializer(Designation &Desig, |
5161 | SourceLocation EqualOrColonLoc, |
5162 | bool GNUSyntax, |
5163 | ExprResult Init); |
5164 | |
5165 | private: |
5166 | static BinaryOperatorKind ConvertTokenKindToBinaryOpcode(tok::TokenKind Kind); |
5167 | |
5168 | public: |
5169 | ExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc, |
5170 | tok::TokenKind Kind, Expr *LHSExpr, Expr *RHSExpr); |
5171 | ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, |
5172 | BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr); |
5173 | ExprResult CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, |
5174 | Expr *LHSExpr, Expr *RHSExpr); |
5175 | void LookupBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, |
5176 | UnresolvedSetImpl &Functions); |
5177 | |
5178 | void DiagnoseCommaOperator(const Expr *LHS, SourceLocation Loc); |
5179 | |
5180 | /// ActOnConditionalOp - Parse a ?: operation. Note that 'LHS' may be null |
5181 | /// in the case of a the GNU conditional expr extension. |
5182 | ExprResult ActOnConditionalOp(SourceLocation QuestionLoc, |
5183 | SourceLocation ColonLoc, |
5184 | Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr); |
5185 | |
5186 | /// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo". |
5187 | ExprResult ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc, |
5188 | LabelDecl *TheDecl); |
5189 | |
5190 | void ActOnStartStmtExpr(); |
5191 | ExprResult ActOnStmtExpr(Scope *S, SourceLocation LPLoc, Stmt *SubStmt, |
5192 | SourceLocation RPLoc); |
5193 | ExprResult BuildStmtExpr(SourceLocation LPLoc, Stmt *SubStmt, |
5194 | SourceLocation RPLoc, unsigned TemplateDepth); |
5195 | // Handle the final expression in a statement expression. |
5196 | ExprResult ActOnStmtExprResult(ExprResult E); |
5197 | void ActOnStmtExprError(); |
5198 | |
5199 | // __builtin_offsetof(type, identifier(.identifier|[expr])*) |
5200 | struct OffsetOfComponent { |
5201 | SourceLocation LocStart, LocEnd; |
5202 | bool isBrackets; // true if [expr], false if .ident |
5203 | union { |
5204 | IdentifierInfo *IdentInfo; |
5205 | Expr *E; |
5206 | } U; |
5207 | }; |
5208 | |
5209 | /// __builtin_offsetof(type, a.b[123][456].c) |
5210 | ExprResult BuildBuiltinOffsetOf(SourceLocation BuiltinLoc, |
5211 | TypeSourceInfo *TInfo, |
5212 | ArrayRef<OffsetOfComponent> Components, |
5213 | SourceLocation RParenLoc); |
5214 | ExprResult ActOnBuiltinOffsetOf(Scope *S, |
5215 | SourceLocation BuiltinLoc, |
5216 | SourceLocation TypeLoc, |
5217 | ParsedType ParsedArgTy, |
5218 | ArrayRef<OffsetOfComponent> Components, |
5219 | SourceLocation RParenLoc); |
5220 | |
5221 | // __builtin_choose_expr(constExpr, expr1, expr2) |
5222 | ExprResult ActOnChooseExpr(SourceLocation BuiltinLoc, |
5223 | Expr *CondExpr, Expr *LHSExpr, |
5224 | Expr *RHSExpr, SourceLocation RPLoc); |
5225 | |
5226 | // __builtin_va_arg(expr, type) |
5227 | ExprResult ActOnVAArg(SourceLocation BuiltinLoc, Expr *E, ParsedType Ty, |
5228 | SourceLocation RPLoc); |
5229 | ExprResult BuildVAArgExpr(SourceLocation BuiltinLoc, Expr *E, |
5230 | TypeSourceInfo *TInfo, SourceLocation RPLoc); |
5231 | |
5232 | // __builtin_LINE(), __builtin_FUNCTION(), __builtin_FILE(), |
5233 | // __builtin_COLUMN() |
5234 | ExprResult ActOnSourceLocExpr(SourceLocExpr::IdentKind Kind, |
5235 | SourceLocation BuiltinLoc, |
5236 | SourceLocation RPLoc); |
5237 | |
5238 | // Build a potentially resolved SourceLocExpr. |
5239 | ExprResult BuildSourceLocExpr(SourceLocExpr::IdentKind Kind, |
5240 | SourceLocation BuiltinLoc, SourceLocation RPLoc, |
5241 | DeclContext *ParentContext); |
5242 | |
5243 | // __null |
5244 | ExprResult ActOnGNUNullExpr(SourceLocation TokenLoc); |
5245 | |
5246 | bool CheckCaseExpression(Expr *E); |
5247 | |
5248 | /// Describes the result of an "if-exists" condition check. |
5249 | enum IfExistsResult { |
5250 | /// The symbol exists. |
5251 | IER_Exists, |
5252 | |
5253 | /// The symbol does not exist. |
5254 | IER_DoesNotExist, |
5255 | |
5256 | /// The name is a dependent name, so the results will differ |
5257 | /// from one instantiation to the next. |
5258 | IER_Dependent, |
5259 | |
5260 | /// An error occurred. |
5261 | IER_Error |
5262 | }; |
5263 | |
5264 | IfExistsResult |
5265 | CheckMicrosoftIfExistsSymbol(Scope *S, CXXScopeSpec &SS, |
5266 | const DeclarationNameInfo &TargetNameInfo); |
5267 | |
5268 | IfExistsResult |
5269 | CheckMicrosoftIfExistsSymbol(Scope *S, SourceLocation KeywordLoc, |
5270 | bool IsIfExists, CXXScopeSpec &SS, |
5271 | UnqualifiedId &Name); |
5272 | |
5273 | StmtResult BuildMSDependentExistsStmt(SourceLocation KeywordLoc, |
5274 | bool IsIfExists, |
5275 | NestedNameSpecifierLoc QualifierLoc, |
5276 | DeclarationNameInfo NameInfo, |
5277 | Stmt *Nested); |
5278 | StmtResult ActOnMSDependentExistsStmt(SourceLocation KeywordLoc, |
5279 | bool IsIfExists, |
5280 | CXXScopeSpec &SS, UnqualifiedId &Name, |
5281 | Stmt *Nested); |
5282 | |
5283 | //===------------------------- "Block" Extension ------------------------===// |
5284 | |
5285 | /// ActOnBlockStart - This callback is invoked when a block literal is |
5286 | /// started. |
5287 | void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope); |
5288 | |
5289 | /// ActOnBlockArguments - This callback allows processing of block arguments. |
5290 | /// If there are no arguments, this is still invoked. |
5291 | void ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo, |
5292 | Scope *CurScope); |
5293 | |
5294 | /// ActOnBlockError - If there is an error parsing a block, this callback |
5295 | /// is invoked to pop the information about the block from the action impl. |
5296 | void ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope); |
5297 | |
5298 | /// ActOnBlockStmtExpr - This is called when the body of a block statement |
5299 | /// literal was successfully completed. ^(int x){...} |
5300 | ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc, Stmt *Body, |
5301 | Scope *CurScope); |
5302 | |
5303 | //===---------------------------- Clang Extensions ----------------------===// |
5304 | |
5305 | /// __builtin_convertvector(...) |
5306 | ExprResult ActOnConvertVectorExpr(Expr *E, ParsedType ParsedDestTy, |
5307 | SourceLocation BuiltinLoc, |
5308 | SourceLocation RParenLoc); |
5309 | |
5310 | //===---------------------------- OpenCL Features -----------------------===// |
5311 | |
5312 | /// __builtin_astype(...) |
5313 | ExprResult ActOnAsTypeExpr(Expr *E, ParsedType ParsedDestTy, |
5314 | SourceLocation BuiltinLoc, |
5315 | SourceLocation RParenLoc); |
5316 | |
5317 | //===---------------------------- C++ Features --------------------------===// |
5318 | |
5319 | // Act on C++ namespaces |
5320 | Decl *ActOnStartNamespaceDef(Scope *S, SourceLocation InlineLoc, |
5321 | SourceLocation NamespaceLoc, |
5322 | SourceLocation IdentLoc, IdentifierInfo *Ident, |
5323 | SourceLocation LBrace, |
5324 | const ParsedAttributesView &AttrList, |
5325 | UsingDirectiveDecl *&UsingDecl); |
5326 | void ActOnFinishNamespaceDef(Decl *Dcl, SourceLocation RBrace); |
5327 | |
5328 | NamespaceDecl *getStdNamespace() const; |
5329 | NamespaceDecl *getOrCreateStdNamespace(); |
5330 | |
5331 | NamespaceDecl *lookupStdExperimentalNamespace(); |
5332 | |
5333 | CXXRecordDecl *getStdBadAlloc() const; |
5334 | EnumDecl *getStdAlignValT() const; |
5335 | |
5336 | private: |
5337 | // A cache representing if we've fully checked the various comparison category |
5338 | // types stored in ASTContext. The bit-index corresponds to the integer value |
5339 | // of a ComparisonCategoryType enumerator. |
5340 | llvm::SmallBitVector FullyCheckedComparisonCategories; |
5341 | |
5342 | ValueDecl *tryLookupCtorInitMemberDecl(CXXRecordDecl *ClassDecl, |
5343 | CXXScopeSpec &SS, |
5344 | ParsedType TemplateTypeTy, |
5345 | IdentifierInfo *MemberOrBase); |
5346 | |
5347 | public: |
5348 | enum class ComparisonCategoryUsage { |
5349 | /// The '<=>' operator was used in an expression and a builtin operator |
5350 | /// was selected. |
5351 | OperatorInExpression, |
5352 | /// A defaulted 'operator<=>' needed the comparison category. This |
5353 | /// typically only applies to 'std::strong_ordering', due to the implicit |
5354 | /// fallback return value. |
5355 | DefaultedOperator, |
5356 | }; |
5357 | |
5358 | /// Lookup the specified comparison category types in the standard |
5359 | /// library, an check the VarDecls possibly returned by the operator<=> |
5360 | /// builtins for that type. |
5361 | /// |
5362 | /// \return The type of the comparison category type corresponding to the |
5363 | /// specified Kind, or a null type if an error occurs |
5364 | QualType CheckComparisonCategoryType(ComparisonCategoryType Kind, |
5365 | SourceLocation Loc, |
5366 | ComparisonCategoryUsage Usage); |
5367 | |
5368 | /// Tests whether Ty is an instance of std::initializer_list and, if |
5369 | /// it is and Element is not NULL, assigns the element type to Element. |
5370 | bool isStdInitializerList(QualType Ty, QualType *Element); |
5371 | |
5372 | /// Looks for the std::initializer_list template and instantiates it |
5373 | /// with Element, or emits an error if it's not found. |
5374 | /// |
5375 | /// \returns The instantiated template, or null on error. |
5376 | QualType BuildStdInitializerList(QualType Element, SourceLocation Loc); |
5377 | |
5378 | /// Determine whether Ctor is an initializer-list constructor, as |
5379 | /// defined in [dcl.init.list]p2. |
5380 | bool isInitListConstructor(const FunctionDecl *Ctor); |
5381 | |
5382 | Decl *ActOnUsingDirective(Scope *CurScope, SourceLocation UsingLoc, |
5383 | SourceLocation NamespcLoc, CXXScopeSpec &SS, |
5384 | SourceLocation IdentLoc, |
5385 | IdentifierInfo *NamespcName, |
5386 | const ParsedAttributesView &AttrList); |
5387 | |
5388 | void PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir); |
5389 | |
5390 | Decl *ActOnNamespaceAliasDef(Scope *CurScope, |
5391 | SourceLocation NamespaceLoc, |
5392 | SourceLocation AliasLoc, |
5393 | IdentifierInfo *Alias, |
5394 | CXXScopeSpec &SS, |
5395 | SourceLocation IdentLoc, |
5396 | IdentifierInfo *Ident); |
5397 | |
5398 | void HideUsingShadowDecl(Scope *S, UsingShadowDecl *Shadow); |
5399 | bool CheckUsingShadowDecl(UsingDecl *UD, NamedDecl *Target, |
5400 | const LookupResult &PreviousDecls, |
5401 | UsingShadowDecl *&PrevShadow); |
5402 | UsingShadowDecl *BuildUsingShadowDecl(Scope *S, UsingDecl *UD, |
5403 | NamedDecl *Target, |
5404 | UsingShadowDecl *PrevDecl); |
5405 | |
5406 | bool CheckUsingDeclRedeclaration(SourceLocation UsingLoc, |
5407 | bool HasTypenameKeyword, |
5408 | const CXXScopeSpec &SS, |
5409 | SourceLocation NameLoc, |
5410 | const LookupResult &Previous); |
5411 | bool CheckUsingDeclQualifier(SourceLocation UsingLoc, |
5412 | bool HasTypename, |
5413 | const CXXScopeSpec &SS, |
5414 | const DeclarationNameInfo &NameInfo, |
5415 | SourceLocation NameLoc); |
5416 | |
5417 | NamedDecl *BuildUsingDeclaration( |
5418 | Scope *S, AccessSpecifier AS, SourceLocation UsingLoc, |
5419 | bool HasTypenameKeyword, SourceLocation TypenameLoc, CXXScopeSpec &SS, |
5420 | DeclarationNameInfo NameInfo, SourceLocation EllipsisLoc, |
5421 | const ParsedAttributesView &AttrList, bool IsInstantiation); |
5422 | NamedDecl *BuildUsingPackDecl(NamedDecl *InstantiatedFrom, |
5423 | ArrayRef<NamedDecl *> Expansions); |
5424 | |
5425 | bool CheckInheritingConstructorUsingDecl(UsingDecl *UD); |
5426 | |
5427 | /// Given a derived-class using shadow declaration for a constructor and the |
5428 | /// correspnding base class constructor, find or create the implicit |
5429 | /// synthesized derived class constructor to use for this initialization. |
5430 | CXXConstructorDecl * |
5431 | findInheritingConstructor(SourceLocation Loc, CXXConstructorDecl *BaseCtor, |
5432 | ConstructorUsingShadowDecl *DerivedShadow); |
5433 | |
5434 | Decl *ActOnUsingDeclaration(Scope *CurScope, AccessSpecifier AS, |
5435 | SourceLocation UsingLoc, |
5436 | SourceLocation TypenameLoc, CXXScopeSpec &SS, |
5437 | UnqualifiedId &Name, SourceLocation EllipsisLoc, |
5438 | const ParsedAttributesView &AttrList); |
5439 | Decl *ActOnAliasDeclaration(Scope *CurScope, AccessSpecifier AS, |
5440 | MultiTemplateParamsArg TemplateParams, |
5441 | SourceLocation UsingLoc, UnqualifiedId &Name, |
5442 | const ParsedAttributesView &AttrList, |
5443 | TypeResult Type, Decl *DeclFromDeclSpec); |
5444 | |
5445 | /// BuildCXXConstructExpr - Creates a complete call to a constructor, |
5446 | /// including handling of its default argument expressions. |
5447 | /// |
5448 | /// \param ConstructKind - a CXXConstructExpr::ConstructionKind |
5449 | ExprResult |
5450 | BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, |
5451 | NamedDecl *FoundDecl, |
5452 | CXXConstructorDecl *Constructor, MultiExprArg Exprs, |
5453 | bool HadMultipleCandidates, bool IsListInitialization, |
5454 | bool IsStdInitListInitialization, |
5455 | bool RequiresZeroInit, unsigned ConstructKind, |
5456 | SourceRange ParenRange); |
5457 | |
5458 | /// Build a CXXConstructExpr whose constructor has already been resolved if |
5459 | /// it denotes an inherited constructor. |
5460 | ExprResult |
5461 | BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, |
5462 | CXXConstructorDecl *Constructor, bool Elidable, |
5463 | MultiExprArg Exprs, |
5464 | bool HadMultipleCandidates, bool IsListInitialization, |
5465 | bool IsStdInitListInitialization, |
5466 | bool RequiresZeroInit, unsigned ConstructKind, |
5467 | SourceRange ParenRange); |
5468 | |
5469 | // FIXME: Can we remove this and have the above BuildCXXConstructExpr check if |
5470 | // the constructor can be elidable? |
5471 | ExprResult |
5472 | BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, |
5473 | NamedDecl *FoundDecl, |
5474 | CXXConstructorDecl *Constructor, bool Elidable, |
5475 | MultiExprArg Exprs, bool HadMultipleCandidates, |
5476 | bool IsListInitialization, |
5477 | bool IsStdInitListInitialization, bool RequiresZeroInit, |
5478 | unsigned ConstructKind, SourceRange ParenRange); |
5479 | |
5480 | ExprResult BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field); |
5481 | |
5482 | |
5483 | /// Instantiate or parse a C++ default argument expression as necessary. |
5484 | /// Return true on error. |
5485 | bool CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD, |
5486 | ParmVarDecl *Param); |
5487 | |
5488 | /// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating |
5489 | /// the default expr if needed. |
5490 | ExprResult BuildCXXDefaultArgExpr(SourceLocation CallLoc, |
5491 | FunctionDecl *FD, |
5492 | ParmVarDecl *Param); |
5493 | |
5494 | /// FinalizeVarWithDestructor - Prepare for calling destructor on the |
5495 | /// constructed variable. |
5496 | void FinalizeVarWithDestructor(VarDecl *VD, const RecordType *DeclInitType); |
5497 | |
5498 | /// Helper class that collects exception specifications for |
5499 | /// implicitly-declared special member functions. |
5500 | class ImplicitExceptionSpecification { |
5501 | // Pointer to allow copying |
5502 | Sema *Self; |
5503 | // We order exception specifications thus: |
5504 | // noexcept is the most restrictive, but is only used in C++11. |
5505 | // throw() comes next. |
5506 | // Then a throw(collected exceptions) |
5507 | // Finally no specification, which is expressed as noexcept(false). |
5508 | // throw(...) is used instead if any called function uses it. |
5509 | ExceptionSpecificationType ComputedEST; |
5510 | llvm::SmallPtrSet<CanQualType, 4> ExceptionsSeen; |
5511 | SmallVector<QualType, 4> Exceptions; |
5512 | |
5513 | void ClearExceptions() { |
5514 | ExceptionsSeen.clear(); |
5515 | Exceptions.clear(); |
5516 | } |
5517 | |
5518 | public: |
5519 | explicit ImplicitExceptionSpecification(Sema &Self) |
5520 | : Self(&Self), ComputedEST(EST_BasicNoexcept) { |
5521 | if (!Self.getLangOpts().CPlusPlus11) |
5522 | ComputedEST = EST_DynamicNone; |
5523 | } |
5524 | |
5525 | /// Get the computed exception specification type. |
5526 | ExceptionSpecificationType getExceptionSpecType() const { |
5527 | assert(!isComputedNoexcept(ComputedEST) &&((!isComputedNoexcept(ComputedEST) && "noexcept(expr) should not be a possible result" ) ? static_cast<void> (0) : __assert_fail ("!isComputedNoexcept(ComputedEST) && \"noexcept(expr) should not be a possible result\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 5528, __PRETTY_FUNCTION__)) |
5528 | "noexcept(expr) should not be a possible result")((!isComputedNoexcept(ComputedEST) && "noexcept(expr) should not be a possible result" ) ? static_cast<void> (0) : __assert_fail ("!isComputedNoexcept(ComputedEST) && \"noexcept(expr) should not be a possible result\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 5528, __PRETTY_FUNCTION__)); |
5529 | return ComputedEST; |
5530 | } |
5531 | |
5532 | /// The number of exceptions in the exception specification. |
5533 | unsigned size() const { return Exceptions.size(); } |
5534 | |
5535 | /// The set of exceptions in the exception specification. |
5536 | const QualType *data() const { return Exceptions.data(); } |
5537 | |
5538 | /// Integrate another called method into the collected data. |
5539 | void CalledDecl(SourceLocation CallLoc, const CXXMethodDecl *Method); |
5540 | |
5541 | /// Integrate an invoked expression into the collected data. |
5542 | void CalledExpr(Expr *E) { CalledStmt(E); } |
5543 | |
5544 | /// Integrate an invoked statement into the collected data. |
5545 | void CalledStmt(Stmt *S); |
5546 | |
5547 | /// Overwrite an EPI's exception specification with this |
5548 | /// computed exception specification. |
5549 | FunctionProtoType::ExceptionSpecInfo getExceptionSpec() const { |
5550 | FunctionProtoType::ExceptionSpecInfo ESI; |
5551 | ESI.Type = getExceptionSpecType(); |
5552 | if (ESI.Type == EST_Dynamic) { |
5553 | ESI.Exceptions = Exceptions; |
5554 | } else if (ESI.Type == EST_None) { |
5555 | /// C++11 [except.spec]p14: |
5556 | /// The exception-specification is noexcept(false) if the set of |
5557 | /// potential exceptions of the special member function contains "any" |
5558 | ESI.Type = EST_NoexceptFalse; |
5559 | ESI.NoexceptExpr = Self->ActOnCXXBoolLiteral(SourceLocation(), |
5560 | tok::kw_false).get(); |
5561 | } |
5562 | return ESI; |
5563 | } |
5564 | }; |
5565 | |
5566 | /// Determine what sort of exception specification a defaulted |
5567 | /// copy constructor of a class will have. |
5568 | ImplicitExceptionSpecification |
5569 | ComputeDefaultedDefaultCtorExceptionSpec(SourceLocation Loc, |
5570 | CXXMethodDecl *MD); |
5571 | |
5572 | /// Determine what sort of exception specification a defaulted |
5573 | /// default constructor of a class will have, and whether the parameter |
5574 | /// will be const. |
5575 | ImplicitExceptionSpecification |
5576 | ComputeDefaultedCopyCtorExceptionSpec(CXXMethodDecl *MD); |
5577 | |
5578 | /// Determine what sort of exception specification a defaulted |
5579 | /// copy assignment operator of a class will have, and whether the |
5580 | /// parameter will be const. |
5581 | ImplicitExceptionSpecification |
5582 | ComputeDefaultedCopyAssignmentExceptionSpec(CXXMethodDecl *MD); |
5583 | |
5584 | /// Determine what sort of exception specification a defaulted move |
5585 | /// constructor of a class will have. |
5586 | ImplicitExceptionSpecification |
5587 | ComputeDefaultedMoveCtorExceptionSpec(CXXMethodDecl *MD); |
5588 | |
5589 | /// Determine what sort of exception specification a defaulted move |
5590 | /// assignment operator of a class will have. |
5591 | ImplicitExceptionSpecification |
5592 | ComputeDefaultedMoveAssignmentExceptionSpec(CXXMethodDecl *MD); |
5593 | |
5594 | /// Determine what sort of exception specification a defaulted |
5595 | /// destructor of a class will have. |
5596 | ImplicitExceptionSpecification |
5597 | ComputeDefaultedDtorExceptionSpec(CXXMethodDecl *MD); |
5598 | |
5599 | /// Determine what sort of exception specification an inheriting |
5600 | /// constructor of a class will have. |
5601 | ImplicitExceptionSpecification |
5602 | ComputeInheritingCtorExceptionSpec(SourceLocation Loc, |
5603 | CXXConstructorDecl *CD); |
5604 | |
5605 | /// Evaluate the implicit exception specification for a defaulted |
5606 | /// special member function. |
5607 | void EvaluateImplicitExceptionSpec(SourceLocation Loc, FunctionDecl *FD); |
5608 | |
5609 | /// Check the given noexcept-specifier, convert its expression, and compute |
5610 | /// the appropriate ExceptionSpecificationType. |
5611 | ExprResult ActOnNoexceptSpec(SourceLocation NoexceptLoc, Expr *NoexceptExpr, |
5612 | ExceptionSpecificationType &EST); |
5613 | |
5614 | /// Check the given exception-specification and update the |
5615 | /// exception specification information with the results. |
5616 | void checkExceptionSpecification(bool IsTopLevel, |
5617 | ExceptionSpecificationType EST, |
5618 | ArrayRef<ParsedType> DynamicExceptions, |
5619 | ArrayRef<SourceRange> DynamicExceptionRanges, |
5620 | Expr *NoexceptExpr, |
5621 | SmallVectorImpl<QualType> &Exceptions, |
5622 | FunctionProtoType::ExceptionSpecInfo &ESI); |
5623 | |
5624 | /// Determine if we're in a case where we need to (incorrectly) eagerly |
5625 | /// parse an exception specification to work around a libstdc++ bug. |
5626 | bool isLibstdcxxEagerExceptionSpecHack(const Declarator &D); |
5627 | |
5628 | /// Add an exception-specification to the given member function |
5629 | /// (or member function template). The exception-specification was parsed |
5630 | /// after the method itself was declared. |
5631 | void actOnDelayedExceptionSpecification(Decl *Method, |
5632 | ExceptionSpecificationType EST, |
5633 | SourceRange SpecificationRange, |
5634 | ArrayRef<ParsedType> DynamicExceptions, |
5635 | ArrayRef<SourceRange> DynamicExceptionRanges, |
5636 | Expr *NoexceptExpr); |
5637 | |
5638 | class InheritedConstructorInfo; |
5639 | |
5640 | /// Determine if a special member function should have a deleted |
5641 | /// definition when it is defaulted. |
5642 | bool ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM, |
5643 | InheritedConstructorInfo *ICI = nullptr, |
5644 | bool Diagnose = false); |
5645 | |
5646 | /// Produce notes explaining why a defaulted function was defined as deleted. |
5647 | void DiagnoseDeletedDefaultedFunction(FunctionDecl *FD); |
5648 | |
5649 | /// Declare the implicit default constructor for the given class. |
5650 | /// |
5651 | /// \param ClassDecl The class declaration into which the implicit |
5652 | /// default constructor will be added. |
5653 | /// |
5654 | /// \returns The implicitly-declared default constructor. |
5655 | CXXConstructorDecl *DeclareImplicitDefaultConstructor( |
5656 | CXXRecordDecl *ClassDecl); |
5657 | |
5658 | /// DefineImplicitDefaultConstructor - Checks for feasibility of |
5659 | /// defining this constructor as the default constructor. |
5660 | void DefineImplicitDefaultConstructor(SourceLocation CurrentLocation, |
5661 | CXXConstructorDecl *Constructor); |
5662 | |
5663 | /// Declare the implicit destructor for the given class. |
5664 | /// |
5665 | /// \param ClassDecl The class declaration into which the implicit |
5666 | /// destructor will be added. |
5667 | /// |
5668 | /// \returns The implicitly-declared destructor. |
5669 | CXXDestructorDecl *DeclareImplicitDestructor(CXXRecordDecl *ClassDecl); |
5670 | |
5671 | /// DefineImplicitDestructor - Checks for feasibility of |
5672 | /// defining this destructor as the default destructor. |
5673 | void DefineImplicitDestructor(SourceLocation CurrentLocation, |
5674 | CXXDestructorDecl *Destructor); |
5675 | |
5676 | /// Build an exception spec for destructors that don't have one. |
5677 | /// |
5678 | /// C++11 says that user-defined destructors with no exception spec get one |
5679 | /// that looks as if the destructor was implicitly declared. |
5680 | void AdjustDestructorExceptionSpec(CXXDestructorDecl *Destructor); |
5681 | |
5682 | /// Define the specified inheriting constructor. |
5683 | void DefineInheritingConstructor(SourceLocation UseLoc, |
5684 | CXXConstructorDecl *Constructor); |
5685 | |
5686 | /// Declare the implicit copy constructor for the given class. |
5687 | /// |
5688 | /// \param ClassDecl The class declaration into which the implicit |
5689 | /// copy constructor will be added. |
5690 | /// |
5691 | /// \returns The implicitly-declared copy constructor. |
5692 | CXXConstructorDecl *DeclareImplicitCopyConstructor(CXXRecordDecl *ClassDecl); |
5693 | |
5694 | /// DefineImplicitCopyConstructor - Checks for feasibility of |
5695 | /// defining this constructor as the copy constructor. |
5696 | void DefineImplicitCopyConstructor(SourceLocation CurrentLocation, |
5697 | CXXConstructorDecl *Constructor); |
5698 | |
5699 | /// Declare the implicit move constructor for the given class. |
5700 | /// |
5701 | /// \param ClassDecl The Class declaration into which the implicit |
5702 | /// move constructor will be added. |
5703 | /// |
5704 | /// \returns The implicitly-declared move constructor, or NULL if it wasn't |
5705 | /// declared. |
5706 | CXXConstructorDecl *DeclareImplicitMoveConstructor(CXXRecordDecl *ClassDecl); |
5707 | |
5708 | /// DefineImplicitMoveConstructor - Checks for feasibility of |
5709 | /// defining this constructor as the move constructor. |
5710 | void DefineImplicitMoveConstructor(SourceLocation CurrentLocation, |
5711 | CXXConstructorDecl *Constructor); |
5712 | |
5713 | /// Declare the implicit copy assignment operator for the given class. |
5714 | /// |
5715 | /// \param ClassDecl The class declaration into which the implicit |
5716 | /// copy assignment operator will be added. |
5717 | /// |
5718 | /// \returns The implicitly-declared copy assignment operator. |
5719 | CXXMethodDecl *DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl); |
5720 | |
5721 | /// Defines an implicitly-declared copy assignment operator. |
5722 | void DefineImplicitCopyAssignment(SourceLocation CurrentLocation, |
5723 | CXXMethodDecl *MethodDecl); |
5724 | |
5725 | /// Declare the implicit move assignment operator for the given class. |
5726 | /// |
5727 | /// \param ClassDecl The Class declaration into which the implicit |
5728 | /// move assignment operator will be added. |
5729 | /// |
5730 | /// \returns The implicitly-declared move assignment operator, or NULL if it |
5731 | /// wasn't declared. |
5732 | CXXMethodDecl *DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl); |
5733 | |
5734 | /// Defines an implicitly-declared move assignment operator. |
5735 | void DefineImplicitMoveAssignment(SourceLocation CurrentLocation, |
5736 | CXXMethodDecl *MethodDecl); |
5737 | |
5738 | /// Force the declaration of any implicitly-declared members of this |
5739 | /// class. |
5740 | void ForceDeclarationOfImplicitMembers(CXXRecordDecl *Class); |
5741 | |
5742 | /// Check a completed declaration of an implicit special member. |
5743 | void CheckImplicitSpecialMemberDeclaration(Scope *S, FunctionDecl *FD); |
5744 | |
5745 | /// Determine whether the given function is an implicitly-deleted |
5746 | /// special member function. |
5747 | bool isImplicitlyDeleted(FunctionDecl *FD); |
5748 | |
5749 | /// Check whether 'this' shows up in the type of a static member |
5750 | /// function after the (naturally empty) cv-qualifier-seq would be. |
5751 | /// |
5752 | /// \returns true if an error occurred. |
5753 | bool checkThisInStaticMemberFunctionType(CXXMethodDecl *Method); |
5754 | |
5755 | /// Whether this' shows up in the exception specification of a static |
5756 | /// member function. |
5757 | bool checkThisInStaticMemberFunctionExceptionSpec(CXXMethodDecl *Method); |
5758 | |
5759 | /// Check whether 'this' shows up in the attributes of the given |
5760 | /// static member function. |
5761 | /// |
5762 | /// \returns true if an error occurred. |
5763 | bool checkThisInStaticMemberFunctionAttributes(CXXMethodDecl *Method); |
5764 | |
5765 | /// MaybeBindToTemporary - If the passed in expression has a record type with |
5766 | /// a non-trivial destructor, this will return CXXBindTemporaryExpr. Otherwise |
5767 | /// it simply returns the passed in expression. |
5768 | ExprResult MaybeBindToTemporary(Expr *E); |
5769 | |
5770 | /// Wrap the expression in a ConstantExpr if it is a potential immediate |
5771 | /// invocation. |
5772 | ExprResult CheckForImmediateInvocation(ExprResult E, FunctionDecl *Decl); |
5773 | |
5774 | bool CompleteConstructorCall(CXXConstructorDecl *Constructor, |
5775 | MultiExprArg ArgsPtr, |
5776 | SourceLocation Loc, |
5777 | SmallVectorImpl<Expr*> &ConvertedArgs, |
5778 | bool AllowExplicit = false, |
5779 | bool IsListInitialization = false); |
5780 | |
5781 | ParsedType getInheritingConstructorName(CXXScopeSpec &SS, |
5782 | SourceLocation NameLoc, |
5783 | IdentifierInfo &Name); |
5784 | |
5785 | ParsedType getConstructorName(IdentifierInfo &II, SourceLocation NameLoc, |
5786 | Scope *S, CXXScopeSpec &SS, |
5787 | bool EnteringContext); |
5788 | ParsedType getDestructorName(SourceLocation TildeLoc, |
5789 | IdentifierInfo &II, SourceLocation NameLoc, |
5790 | Scope *S, CXXScopeSpec &SS, |
5791 | ParsedType ObjectType, |
5792 | bool EnteringContext); |
5793 | |
5794 | ParsedType getDestructorTypeForDecltype(const DeclSpec &DS, |
5795 | ParsedType ObjectType); |
5796 | |
5797 | // Checks that reinterpret casts don't have undefined behavior. |
5798 | void CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType, |
5799 | bool IsDereference, SourceRange Range); |
5800 | |
5801 | /// ActOnCXXNamedCast - Parse |
5802 | /// {dynamic,static,reinterpret,const,addrspace}_cast's. |
5803 | ExprResult ActOnCXXNamedCast(SourceLocation OpLoc, |
5804 | tok::TokenKind Kind, |
5805 | SourceLocation LAngleBracketLoc, |
5806 | Declarator &D, |
5807 | SourceLocation RAngleBracketLoc, |
5808 | SourceLocation LParenLoc, |
5809 | Expr *E, |
5810 | SourceLocation RParenLoc); |
5811 | |
5812 | ExprResult BuildCXXNamedCast(SourceLocation OpLoc, |
5813 | tok::TokenKind Kind, |
5814 | TypeSourceInfo *Ty, |
5815 | Expr *E, |
5816 | SourceRange AngleBrackets, |
5817 | SourceRange Parens); |
5818 | |
5819 | ExprResult ActOnBuiltinBitCastExpr(SourceLocation KWLoc, Declarator &Dcl, |
5820 | ExprResult Operand, |
5821 | SourceLocation RParenLoc); |
5822 | |
5823 | ExprResult BuildBuiltinBitCastExpr(SourceLocation KWLoc, TypeSourceInfo *TSI, |
5824 | Expr *Operand, SourceLocation RParenLoc); |
5825 | |
5826 | ExprResult BuildCXXTypeId(QualType TypeInfoType, |
5827 | SourceLocation TypeidLoc, |
5828 | TypeSourceInfo *Operand, |
5829 | SourceLocation RParenLoc); |
5830 | ExprResult BuildCXXTypeId(QualType TypeInfoType, |
5831 | SourceLocation TypeidLoc, |
5832 | Expr *Operand, |
5833 | SourceLocation RParenLoc); |
5834 | |
5835 | /// ActOnCXXTypeid - Parse typeid( something ). |
5836 | ExprResult ActOnCXXTypeid(SourceLocation OpLoc, |
5837 | SourceLocation LParenLoc, bool isType, |
5838 | void *TyOrExpr, |
5839 | SourceLocation RParenLoc); |
5840 | |
5841 | ExprResult BuildCXXUuidof(QualType TypeInfoType, |
5842 | SourceLocation TypeidLoc, |
5843 | TypeSourceInfo *Operand, |
5844 | SourceLocation RParenLoc); |
5845 | ExprResult BuildCXXUuidof(QualType TypeInfoType, |
5846 | SourceLocation TypeidLoc, |
5847 | Expr *Operand, |
5848 | SourceLocation RParenLoc); |
5849 | |
5850 | /// ActOnCXXUuidof - Parse __uuidof( something ). |
5851 | ExprResult ActOnCXXUuidof(SourceLocation OpLoc, |
5852 | SourceLocation LParenLoc, bool isType, |
5853 | void *TyOrExpr, |
5854 | SourceLocation RParenLoc); |
5855 | |
5856 | /// Handle a C++1z fold-expression: ( expr op ... op expr ). |
5857 | ExprResult ActOnCXXFoldExpr(Scope *S, SourceLocation LParenLoc, Expr *LHS, |
5858 | tok::TokenKind Operator, |
5859 | SourceLocation EllipsisLoc, Expr *RHS, |
5860 | SourceLocation RParenLoc); |
5861 | ExprResult BuildCXXFoldExpr(UnresolvedLookupExpr *Callee, |
5862 | SourceLocation LParenLoc, Expr *LHS, |
5863 | BinaryOperatorKind Operator, |
5864 | SourceLocation EllipsisLoc, Expr *RHS, |
5865 | SourceLocation RParenLoc, |
5866 | Optional<unsigned> NumExpansions); |
5867 | ExprResult BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc, |
5868 | BinaryOperatorKind Operator); |
5869 | |
5870 | //// ActOnCXXThis - Parse 'this' pointer. |
5871 | ExprResult ActOnCXXThis(SourceLocation loc); |
5872 | |
5873 | /// Build a CXXThisExpr and mark it referenced in the current context. |
5874 | Expr *BuildCXXThisExpr(SourceLocation Loc, QualType Type, bool IsImplicit); |
5875 | void MarkThisReferenced(CXXThisExpr *This); |
5876 | |
5877 | /// Try to retrieve the type of the 'this' pointer. |
5878 | /// |
5879 | /// \returns The type of 'this', if possible. Otherwise, returns a NULL type. |
5880 | QualType getCurrentThisType(); |
5881 | |
5882 | /// When non-NULL, the C++ 'this' expression is allowed despite the |
5883 | /// current context not being a non-static member function. In such cases, |
5884 | /// this provides the type used for 'this'. |
5885 | QualType CXXThisTypeOverride; |
5886 | |
5887 | /// RAII object used to temporarily allow the C++ 'this' expression |
5888 | /// to be used, with the given qualifiers on the current class type. |
5889 | class CXXThisScopeRAII { |
5890 | Sema &S; |
5891 | QualType OldCXXThisTypeOverride; |
5892 | bool Enabled; |
5893 | |
5894 | public: |
5895 | /// Introduce a new scope where 'this' may be allowed (when enabled), |
5896 | /// using the given declaration (which is either a class template or a |
5897 | /// class) along with the given qualifiers. |
5898 | /// along with the qualifiers placed on '*this'. |
5899 | CXXThisScopeRAII(Sema &S, Decl *ContextDecl, Qualifiers CXXThisTypeQuals, |
5900 | bool Enabled = true); |
5901 | |
5902 | ~CXXThisScopeRAII(); |
5903 | }; |
5904 | |
5905 | /// Make sure the value of 'this' is actually available in the current |
5906 | /// context, if it is a potentially evaluated context. |
5907 | /// |
5908 | /// \param Loc The location at which the capture of 'this' occurs. |
5909 | /// |
5910 | /// \param Explicit Whether 'this' is explicitly captured in a lambda |
5911 | /// capture list. |
5912 | /// |
5913 | /// \param FunctionScopeIndexToStopAt If non-null, it points to the index |
5914 | /// of the FunctionScopeInfo stack beyond which we do not attempt to capture. |
5915 | /// This is useful when enclosing lambdas must speculatively capture |
5916 | /// 'this' that may or may not be used in certain specializations of |
5917 | /// a nested generic lambda (depending on whether the name resolves to |
5918 | /// a non-static member function or a static function). |
5919 | /// \return returns 'true' if failed, 'false' if success. |
5920 | bool CheckCXXThisCapture(SourceLocation Loc, bool Explicit = false, |
5921 | bool BuildAndDiagnose = true, |
5922 | const unsigned *const FunctionScopeIndexToStopAt = nullptr, |
5923 | bool ByCopy = false); |
5924 | |
5925 | /// Determine whether the given type is the type of *this that is used |
5926 | /// outside of the body of a member function for a type that is currently |
5927 | /// being defined. |
5928 | bool isThisOutsideMemberFunctionBody(QualType BaseType); |
5929 | |
5930 | /// ActOnCXXBoolLiteral - Parse {true,false} literals. |
5931 | ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind); |
5932 | |
5933 | |
5934 | /// ActOnObjCBoolLiteral - Parse {__objc_yes,__objc_no} literals. |
5935 | ExprResult ActOnObjCBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind); |
5936 | |
5937 | ExprResult |
5938 | ActOnObjCAvailabilityCheckExpr(llvm::ArrayRef<AvailabilitySpec> AvailSpecs, |
5939 | SourceLocation AtLoc, SourceLocation RParen); |
5940 | |
5941 | /// ActOnCXXNullPtrLiteral - Parse 'nullptr'. |
5942 | ExprResult ActOnCXXNullPtrLiteral(SourceLocation Loc); |
5943 | |
5944 | //// ActOnCXXThrow - Parse throw expressions. |
5945 | ExprResult ActOnCXXThrow(Scope *S, SourceLocation OpLoc, Expr *expr); |
5946 | ExprResult BuildCXXThrow(SourceLocation OpLoc, Expr *Ex, |
5947 | bool IsThrownVarInScope); |
5948 | bool CheckCXXThrowOperand(SourceLocation ThrowLoc, QualType ThrowTy, Expr *E); |
5949 | |
5950 | /// ActOnCXXTypeConstructExpr - Parse construction of a specified type. |
5951 | /// Can be interpreted either as function-style casting ("int(x)") |
5952 | /// or class type construction ("ClassType(x,y,z)") |
5953 | /// or creation of a value-initialized type ("int()"). |
5954 | ExprResult ActOnCXXTypeConstructExpr(ParsedType TypeRep, |
5955 | SourceLocation LParenOrBraceLoc, |
5956 | MultiExprArg Exprs, |
5957 | SourceLocation RParenOrBraceLoc, |
5958 | bool ListInitialization); |
5959 | |
5960 | ExprResult BuildCXXTypeConstructExpr(TypeSourceInfo *Type, |
5961 | SourceLocation LParenLoc, |
5962 | MultiExprArg Exprs, |
5963 | SourceLocation RParenLoc, |
5964 | bool ListInitialization); |
5965 | |
5966 | /// ActOnCXXNew - Parsed a C++ 'new' expression. |
5967 | ExprResult ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, |
5968 | SourceLocation PlacementLParen, |
5969 | MultiExprArg PlacementArgs, |
5970 | SourceLocation PlacementRParen, |
5971 | SourceRange TypeIdParens, Declarator &D, |
5972 | Expr *Initializer); |
5973 | ExprResult BuildCXXNew(SourceRange Range, bool UseGlobal, |
5974 | SourceLocation PlacementLParen, |
5975 | MultiExprArg PlacementArgs, |
5976 | SourceLocation PlacementRParen, |
5977 | SourceRange TypeIdParens, |
5978 | QualType AllocType, |
5979 | TypeSourceInfo *AllocTypeInfo, |
5980 | Optional<Expr *> ArraySize, |
5981 | SourceRange DirectInitRange, |
5982 | Expr *Initializer); |
5983 | |
5984 | /// Determine whether \p FD is an aligned allocation or deallocation |
5985 | /// function that is unavailable. |
5986 | bool isUnavailableAlignedAllocationFunction(const FunctionDecl &FD) const; |
5987 | |
5988 | /// Produce diagnostics if \p FD is an aligned allocation or deallocation |
5989 | /// function that is unavailable. |
5990 | void diagnoseUnavailableAlignedAllocation(const FunctionDecl &FD, |
5991 | SourceLocation Loc); |
5992 | |
5993 | bool CheckAllocatedType(QualType AllocType, SourceLocation Loc, |
5994 | SourceRange R); |
5995 | |
5996 | /// The scope in which to find allocation functions. |
5997 | enum AllocationFunctionScope { |
5998 | /// Only look for allocation functions in the global scope. |
5999 | AFS_Global, |
6000 | /// Only look for allocation functions in the scope of the |
6001 | /// allocated class. |
6002 | AFS_Class, |
6003 | /// Look for allocation functions in both the global scope |
6004 | /// and in the scope of the allocated class. |
6005 | AFS_Both |
6006 | }; |
6007 | |
6008 | /// Finds the overloads of operator new and delete that are appropriate |
6009 | /// for the allocation. |
6010 | bool FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, |
6011 | AllocationFunctionScope NewScope, |
6012 | AllocationFunctionScope DeleteScope, |
6013 | QualType AllocType, bool IsArray, |
6014 | bool &PassAlignment, MultiExprArg PlaceArgs, |
6015 | FunctionDecl *&OperatorNew, |
6016 | FunctionDecl *&OperatorDelete, |
6017 | bool Diagnose = true); |
6018 | void DeclareGlobalNewDelete(); |
6019 | void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return, |
6020 | ArrayRef<QualType> Params); |
6021 | |
6022 | bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD, |
6023 | DeclarationName Name, FunctionDecl* &Operator, |
6024 | bool Diagnose = true); |
6025 | FunctionDecl *FindUsualDeallocationFunction(SourceLocation StartLoc, |
6026 | bool CanProvideSize, |
6027 | bool Overaligned, |
6028 | DeclarationName Name); |
6029 | FunctionDecl *FindDeallocationFunctionForDestructor(SourceLocation StartLoc, |
6030 | CXXRecordDecl *RD); |
6031 | |
6032 | /// ActOnCXXDelete - Parsed a C++ 'delete' expression |
6033 | ExprResult ActOnCXXDelete(SourceLocation StartLoc, |
6034 | bool UseGlobal, bool ArrayForm, |
6035 | Expr *Operand); |
6036 | void CheckVirtualDtorCall(CXXDestructorDecl *dtor, SourceLocation Loc, |
6037 | bool IsDelete, bool CallCanBeVirtual, |
6038 | bool WarnOnNonAbstractTypes, |
6039 | SourceLocation DtorLoc); |
6040 | |
6041 | ExprResult ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation LParen, |
6042 | Expr *Operand, SourceLocation RParen); |
6043 | ExprResult BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand, |
6044 | SourceLocation RParen); |
6045 | |
6046 | /// Parsed one of the type trait support pseudo-functions. |
6047 | ExprResult ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc, |
6048 | ArrayRef<ParsedType> Args, |
6049 | SourceLocation RParenLoc); |
6050 | ExprResult BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc, |
6051 | ArrayRef<TypeSourceInfo *> Args, |
6052 | SourceLocation RParenLoc); |
6053 | |
6054 | /// ActOnArrayTypeTrait - Parsed one of the binary type trait support |
6055 | /// pseudo-functions. |
6056 | ExprResult ActOnArrayTypeTrait(ArrayTypeTrait ATT, |
6057 | SourceLocation KWLoc, |
6058 | ParsedType LhsTy, |
6059 | Expr *DimExpr, |
6060 | SourceLocation RParen); |
6061 | |
6062 | ExprResult BuildArrayTypeTrait(ArrayTypeTrait ATT, |
6063 | SourceLocation KWLoc, |
6064 | TypeSourceInfo *TSInfo, |
6065 | Expr *DimExpr, |
6066 | SourceLocation RParen); |
6067 | |
6068 | /// ActOnExpressionTrait - Parsed one of the unary type trait support |
6069 | /// pseudo-functions. |
6070 | ExprResult ActOnExpressionTrait(ExpressionTrait OET, |
6071 | SourceLocation KWLoc, |
6072 | Expr *Queried, |
6073 | SourceLocation RParen); |
6074 | |
6075 | ExprResult BuildExpressionTrait(ExpressionTrait OET, |
6076 | SourceLocation KWLoc, |
6077 | Expr *Queried, |
6078 | SourceLocation RParen); |
6079 | |
6080 | ExprResult ActOnStartCXXMemberReference(Scope *S, |
6081 | Expr *Base, |
6082 | SourceLocation OpLoc, |
6083 | tok::TokenKind OpKind, |
6084 | ParsedType &ObjectType, |
6085 | bool &MayBePseudoDestructor); |
6086 | |
6087 | ExprResult BuildPseudoDestructorExpr(Expr *Base, |
6088 | SourceLocation OpLoc, |
6089 | tok::TokenKind OpKind, |
6090 | const CXXScopeSpec &SS, |
6091 | TypeSourceInfo *ScopeType, |
6092 | SourceLocation CCLoc, |
6093 | SourceLocation TildeLoc, |
6094 | PseudoDestructorTypeStorage DestroyedType); |
6095 | |
6096 | ExprResult ActOnPseudoDestructorExpr(Scope *S, Expr *Base, |
6097 | SourceLocation OpLoc, |
6098 | tok::TokenKind OpKind, |
6099 | CXXScopeSpec &SS, |
6100 | UnqualifiedId &FirstTypeName, |
6101 | SourceLocation CCLoc, |
6102 | SourceLocation TildeLoc, |
6103 | UnqualifiedId &SecondTypeName); |
6104 | |
6105 | ExprResult ActOnPseudoDestructorExpr(Scope *S, Expr *Base, |
6106 | SourceLocation OpLoc, |
6107 | tok::TokenKind OpKind, |
6108 | SourceLocation TildeLoc, |
6109 | const DeclSpec& DS); |
6110 | |
6111 | /// MaybeCreateExprWithCleanups - If the current full-expression |
6112 | /// requires any cleanups, surround it with a ExprWithCleanups node. |
6113 | /// Otherwise, just returns the passed-in expression. |
6114 | Expr *MaybeCreateExprWithCleanups(Expr *SubExpr); |
6115 | Stmt *MaybeCreateStmtWithCleanups(Stmt *SubStmt); |
6116 | ExprResult MaybeCreateExprWithCleanups(ExprResult SubExpr); |
6117 | |
6118 | MaterializeTemporaryExpr * |
6119 | CreateMaterializeTemporaryExpr(QualType T, Expr *Temporary, |
6120 | bool BoundToLvalueReference); |
6121 | |
6122 | ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue) { |
6123 | return ActOnFinishFullExpr( |
6124 | Expr, Expr ? Expr->getExprLoc() : SourceLocation(), DiscardedValue); |
6125 | } |
6126 | ExprResult ActOnFinishFullExpr(Expr *Expr, SourceLocation CC, |
6127 | bool DiscardedValue, bool IsConstexpr = false); |
6128 | StmtResult ActOnFinishFullStmt(Stmt *Stmt); |
6129 | |
6130 | // Marks SS invalid if it represents an incomplete type. |
6131 | bool RequireCompleteDeclContext(CXXScopeSpec &SS, DeclContext *DC); |
6132 | |
6133 | DeclContext *computeDeclContext(QualType T); |
6134 | DeclContext *computeDeclContext(const CXXScopeSpec &SS, |
6135 | bool EnteringContext = false); |
6136 | bool isDependentScopeSpecifier(const CXXScopeSpec &SS); |
6137 | CXXRecordDecl *getCurrentInstantiationOf(NestedNameSpecifier *NNS); |
6138 | |
6139 | /// The parser has parsed a global nested-name-specifier '::'. |
6140 | /// |
6141 | /// \param CCLoc The location of the '::'. |
6142 | /// |
6143 | /// \param SS The nested-name-specifier, which will be updated in-place |
6144 | /// to reflect the parsed nested-name-specifier. |
6145 | /// |
6146 | /// \returns true if an error occurred, false otherwise. |
6147 | bool ActOnCXXGlobalScopeSpecifier(SourceLocation CCLoc, CXXScopeSpec &SS); |
6148 | |
6149 | /// The parser has parsed a '__super' nested-name-specifier. |
6150 | /// |
6151 | /// \param SuperLoc The location of the '__super' keyword. |
6152 | /// |
6153 | /// \param ColonColonLoc The location of the '::'. |
6154 | /// |
6155 | /// \param SS The nested-name-specifier, which will be updated in-place |
6156 | /// to reflect the parsed nested-name-specifier. |
6157 | /// |
6158 | /// \returns true if an error occurred, false otherwise. |
6159 | bool ActOnSuperScopeSpecifier(SourceLocation SuperLoc, |
6160 | SourceLocation ColonColonLoc, CXXScopeSpec &SS); |
6161 | |
6162 | bool isAcceptableNestedNameSpecifier(const NamedDecl *SD, |
6163 | bool *CanCorrect = nullptr); |
6164 | NamedDecl *FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS); |
6165 | |
6166 | /// Keeps information about an identifier in a nested-name-spec. |
6167 | /// |
6168 | struct NestedNameSpecInfo { |
6169 | /// The type of the object, if we're parsing nested-name-specifier in |
6170 | /// a member access expression. |
6171 | ParsedType ObjectType; |
6172 | |
6173 | /// The identifier preceding the '::'. |
6174 | IdentifierInfo *Identifier; |
6175 | |
6176 | /// The location of the identifier. |
6177 | SourceLocation IdentifierLoc; |
6178 | |
6179 | /// The location of the '::'. |
6180 | SourceLocation CCLoc; |
6181 | |
6182 | /// Creates info object for the most typical case. |
6183 | NestedNameSpecInfo(IdentifierInfo *II, SourceLocation IdLoc, |
6184 | SourceLocation ColonColonLoc, ParsedType ObjectType = ParsedType()) |
6185 | : ObjectType(ObjectType), Identifier(II), IdentifierLoc(IdLoc), |
6186 | CCLoc(ColonColonLoc) { |
6187 | } |
6188 | |
6189 | NestedNameSpecInfo(IdentifierInfo *II, SourceLocation IdLoc, |
6190 | SourceLocation ColonColonLoc, QualType ObjectType) |
6191 | : ObjectType(ParsedType::make(ObjectType)), Identifier(II), |
6192 | IdentifierLoc(IdLoc), CCLoc(ColonColonLoc) { |
6193 | } |
6194 | }; |
6195 | |
6196 | bool isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS, |
6197 | NestedNameSpecInfo &IdInfo); |
6198 | |
6199 | bool BuildCXXNestedNameSpecifier(Scope *S, |
6200 | NestedNameSpecInfo &IdInfo, |
6201 | bool EnteringContext, |
6202 | CXXScopeSpec &SS, |
6203 | NamedDecl *ScopeLookupResult, |
6204 | bool ErrorRecoveryLookup, |
6205 | bool *IsCorrectedToColon = nullptr, |
6206 | bool OnlyNamespace = false); |
6207 | |
6208 | /// The parser has parsed a nested-name-specifier 'identifier::'. |
6209 | /// |
6210 | /// \param S The scope in which this nested-name-specifier occurs. |
6211 | /// |
6212 | /// \param IdInfo Parser information about an identifier in the |
6213 | /// nested-name-spec. |
6214 | /// |
6215 | /// \param EnteringContext Whether we're entering the context nominated by |
6216 | /// this nested-name-specifier. |
6217 | /// |
6218 | /// \param SS The nested-name-specifier, which is both an input |
6219 | /// parameter (the nested-name-specifier before this type) and an |
6220 | /// output parameter (containing the full nested-name-specifier, |
6221 | /// including this new type). |
6222 | /// |
6223 | /// \param ErrorRecoveryLookup If true, then this method is called to improve |
6224 | /// error recovery. In this case do not emit error message. |
6225 | /// |
6226 | /// \param IsCorrectedToColon If not null, suggestions to replace '::' -> ':' |
6227 | /// are allowed. The bool value pointed by this parameter is set to 'true' |
6228 | /// if the identifier is treated as if it was followed by ':', not '::'. |
6229 | /// |
6230 | /// \param OnlyNamespace If true, only considers namespaces in lookup. |
6231 | /// |
6232 | /// \returns true if an error occurred, false otherwise. |
6233 | bool ActOnCXXNestedNameSpecifier(Scope *S, |
6234 | NestedNameSpecInfo &IdInfo, |
6235 | bool EnteringContext, |
6236 | CXXScopeSpec &SS, |
6237 | bool ErrorRecoveryLookup = false, |
6238 | bool *IsCorrectedToColon = nullptr, |
6239 | bool OnlyNamespace = false); |
6240 | |
6241 | ExprResult ActOnDecltypeExpression(Expr *E); |
6242 | |
6243 | bool ActOnCXXNestedNameSpecifierDecltype(CXXScopeSpec &SS, |
6244 | const DeclSpec &DS, |
6245 | SourceLocation ColonColonLoc); |
6246 | |
6247 | bool IsInvalidUnlessNestedName(Scope *S, CXXScopeSpec &SS, |
6248 | NestedNameSpecInfo &IdInfo, |
6249 | bool EnteringContext); |
6250 | |
6251 | /// The parser has parsed a nested-name-specifier |
6252 | /// 'template[opt] template-name < template-args >::'. |
6253 | /// |
6254 | /// \param S The scope in which this nested-name-specifier occurs. |
6255 | /// |
6256 | /// \param SS The nested-name-specifier, which is both an input |
6257 | /// parameter (the nested-name-specifier before this type) and an |
6258 | /// output parameter (containing the full nested-name-specifier, |
6259 | /// including this new type). |
6260 | /// |
6261 | /// \param TemplateKWLoc the location of the 'template' keyword, if any. |
6262 | /// \param TemplateName the template name. |
6263 | /// \param TemplateNameLoc The location of the template name. |
6264 | /// \param LAngleLoc The location of the opening angle bracket ('<'). |
6265 | /// \param TemplateArgs The template arguments. |
6266 | /// \param RAngleLoc The location of the closing angle bracket ('>'). |
6267 | /// \param CCLoc The location of the '::'. |
6268 | /// |
6269 | /// \param EnteringContext Whether we're entering the context of the |
6270 | /// nested-name-specifier. |
6271 | /// |
6272 | /// |
6273 | /// \returns true if an error occurred, false otherwise. |
6274 | bool ActOnCXXNestedNameSpecifier(Scope *S, |
6275 | CXXScopeSpec &SS, |
6276 | SourceLocation TemplateKWLoc, |
6277 | TemplateTy TemplateName, |
6278 | SourceLocation TemplateNameLoc, |
6279 | SourceLocation LAngleLoc, |
6280 | ASTTemplateArgsPtr TemplateArgs, |
6281 | SourceLocation RAngleLoc, |
6282 | SourceLocation CCLoc, |
6283 | bool EnteringContext); |
6284 | |
6285 | /// Given a C++ nested-name-specifier, produce an annotation value |
6286 | /// that the parser can use later to reconstruct the given |
6287 | /// nested-name-specifier. |
6288 | /// |
6289 | /// \param SS A nested-name-specifier. |
6290 | /// |
6291 | /// \returns A pointer containing all of the information in the |
6292 | /// nested-name-specifier \p SS. |
6293 | void *SaveNestedNameSpecifierAnnotation(CXXScopeSpec &SS); |
6294 | |
6295 | /// Given an annotation pointer for a nested-name-specifier, restore |
6296 | /// the nested-name-specifier structure. |
6297 | /// |
6298 | /// \param Annotation The annotation pointer, produced by |
6299 | /// \c SaveNestedNameSpecifierAnnotation(). |
6300 | /// |
6301 | /// \param AnnotationRange The source range corresponding to the annotation. |
6302 | /// |
6303 | /// \param SS The nested-name-specifier that will be updated with the contents |
6304 | /// of the annotation pointer. |
6305 | void RestoreNestedNameSpecifierAnnotation(void *Annotation, |
6306 | SourceRange AnnotationRange, |
6307 | CXXScopeSpec &SS); |
6308 | |
6309 | bool ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS); |
6310 | |
6311 | /// ActOnCXXEnterDeclaratorScope - Called when a C++ scope specifier (global |
6312 | /// scope or nested-name-specifier) is parsed, part of a declarator-id. |
6313 | /// After this method is called, according to [C++ 3.4.3p3], names should be |
6314 | /// looked up in the declarator-id's scope, until the declarator is parsed and |
6315 | /// ActOnCXXExitDeclaratorScope is called. |
6316 | /// The 'SS' should be a non-empty valid CXXScopeSpec. |
6317 | bool ActOnCXXEnterDeclaratorScope(Scope *S, CXXScopeSpec &SS); |
6318 | |
6319 | /// ActOnCXXExitDeclaratorScope - Called when a declarator that previously |
6320 | /// invoked ActOnCXXEnterDeclaratorScope(), is finished. 'SS' is the same |
6321 | /// CXXScopeSpec that was passed to ActOnCXXEnterDeclaratorScope as well. |
6322 | /// Used to indicate that names should revert to being looked up in the |
6323 | /// defining scope. |
6324 | void ActOnCXXExitDeclaratorScope(Scope *S, const CXXScopeSpec &SS); |
6325 | |
6326 | /// ActOnCXXEnterDeclInitializer - Invoked when we are about to parse an |
6327 | /// initializer for the declaration 'Dcl'. |
6328 | /// After this method is called, according to [C++ 3.4.1p13], if 'Dcl' is a |
6329 | /// static data member of class X, names should be looked up in the scope of |
6330 | /// class X. |
6331 | void ActOnCXXEnterDeclInitializer(Scope *S, Decl *Dcl); |
6332 | |
6333 | /// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an |
6334 | /// initializer for the declaration 'Dcl'. |
6335 | void ActOnCXXExitDeclInitializer(Scope *S, Decl *Dcl); |
6336 | |
6337 | /// Create a new lambda closure type. |
6338 | CXXRecordDecl *createLambdaClosureType(SourceRange IntroducerRange, |
6339 | TypeSourceInfo *Info, |
6340 | bool KnownDependent, |
6341 | LambdaCaptureDefault CaptureDefault); |
6342 | |
6343 | /// Start the definition of a lambda expression. |
6344 | CXXMethodDecl *startLambdaDefinition(CXXRecordDecl *Class, |
6345 | SourceRange IntroducerRange, |
6346 | TypeSourceInfo *MethodType, |
6347 | SourceLocation EndLoc, |
6348 | ArrayRef<ParmVarDecl *> Params, |
6349 | ConstexprSpecKind ConstexprKind, |
6350 | Expr *TrailingRequiresClause); |
6351 | |
6352 | /// Number lambda for linkage purposes if necessary. |
6353 | void handleLambdaNumbering( |
6354 | CXXRecordDecl *Class, CXXMethodDecl *Method, |
6355 | Optional<std::tuple<unsigned, bool, Decl *>> Mangling = None); |
6356 | |
6357 | /// Endow the lambda scope info with the relevant properties. |
6358 | void buildLambdaScope(sema::LambdaScopeInfo *LSI, |
6359 | CXXMethodDecl *CallOperator, |
6360 | SourceRange IntroducerRange, |
6361 | LambdaCaptureDefault CaptureDefault, |
6362 | SourceLocation CaptureDefaultLoc, |
6363 | bool ExplicitParams, |
6364 | bool ExplicitResultType, |
6365 | bool Mutable); |
6366 | |
6367 | /// Perform initialization analysis of the init-capture and perform |
6368 | /// any implicit conversions such as an lvalue-to-rvalue conversion if |
6369 | /// not being used to initialize a reference. |
6370 | ParsedType actOnLambdaInitCaptureInitialization( |
6371 | SourceLocation Loc, bool ByRef, SourceLocation EllipsisLoc, |
6372 | IdentifierInfo *Id, LambdaCaptureInitKind InitKind, Expr *&Init) { |
6373 | return ParsedType::make(buildLambdaInitCaptureInitialization( |
6374 | Loc, ByRef, EllipsisLoc, None, Id, |
6375 | InitKind != LambdaCaptureInitKind::CopyInit, Init)); |
6376 | } |
6377 | QualType buildLambdaInitCaptureInitialization( |
6378 | SourceLocation Loc, bool ByRef, SourceLocation EllipsisLoc, |
6379 | Optional<unsigned> NumExpansions, IdentifierInfo *Id, bool DirectInit, |
6380 | Expr *&Init); |
6381 | |
6382 | /// Create a dummy variable within the declcontext of the lambda's |
6383 | /// call operator, for name lookup purposes for a lambda init capture. |
6384 | /// |
6385 | /// CodeGen handles emission of lambda captures, ignoring these dummy |
6386 | /// variables appropriately. |
6387 | VarDecl *createLambdaInitCaptureVarDecl(SourceLocation Loc, |
6388 | QualType InitCaptureType, |
6389 | SourceLocation EllipsisLoc, |
6390 | IdentifierInfo *Id, |
6391 | unsigned InitStyle, Expr *Init); |
6392 | |
6393 | /// Add an init-capture to a lambda scope. |
6394 | void addInitCapture(sema::LambdaScopeInfo *LSI, VarDecl *Var); |
6395 | |
6396 | /// Note that we have finished the explicit captures for the |
6397 | /// given lambda. |
6398 | void finishLambdaExplicitCaptures(sema::LambdaScopeInfo *LSI); |
6399 | |
6400 | /// \brief This is called after parsing the explicit template parameter list |
6401 | /// on a lambda (if it exists) in C++2a. |
6402 | void ActOnLambdaExplicitTemplateParameterList(SourceLocation LAngleLoc, |
6403 | ArrayRef<NamedDecl *> TParams, |
6404 | SourceLocation RAngleLoc); |
6405 | |
6406 | /// Introduce the lambda parameters into scope. |
6407 | void addLambdaParameters( |
6408 | ArrayRef<LambdaIntroducer::LambdaCapture> Captures, |
6409 | CXXMethodDecl *CallOperator, Scope *CurScope); |
6410 | |
6411 | /// Deduce a block or lambda's return type based on the return |
6412 | /// statements present in the body. |
6413 | void deduceClosureReturnType(sema::CapturingScopeInfo &CSI); |
6414 | |
6415 | /// ActOnStartOfLambdaDefinition - This is called just before we start |
6416 | /// parsing the body of a lambda; it analyzes the explicit captures and |
6417 | /// arguments, and sets up various data-structures for the body of the |
6418 | /// lambda. |
6419 | void ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, |
6420 | Declarator &ParamInfo, Scope *CurScope); |
6421 | |
6422 | /// ActOnLambdaError - If there is an error parsing a lambda, this callback |
6423 | /// is invoked to pop the information about the lambda. |
6424 | void ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope, |
6425 | bool IsInstantiation = false); |
6426 | |
6427 | /// ActOnLambdaExpr - This is called when the body of a lambda expression |
6428 | /// was successfully completed. |
6429 | ExprResult ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body, |
6430 | Scope *CurScope); |
6431 | |
6432 | /// Does copying/destroying the captured variable have side effects? |
6433 | bool CaptureHasSideEffects(const sema::Capture &From); |
6434 | |
6435 | /// Diagnose if an explicit lambda capture is unused. Returns true if a |
6436 | /// diagnostic is emitted. |
6437 | bool DiagnoseUnusedLambdaCapture(SourceRange CaptureRange, |
6438 | const sema::Capture &From); |
6439 | |
6440 | /// Build a FieldDecl suitable to hold the given capture. |
6441 | FieldDecl *BuildCaptureField(RecordDecl *RD, const sema::Capture &Capture); |
6442 | |
6443 | /// Initialize the given capture with a suitable expression. |
6444 | ExprResult BuildCaptureInit(const sema::Capture &Capture, |
6445 | SourceLocation ImplicitCaptureLoc, |
6446 | bool IsOpenMPMapping = false); |
6447 | |
6448 | /// Complete a lambda-expression having processed and attached the |
6449 | /// lambda body. |
6450 | ExprResult BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc, |
6451 | sema::LambdaScopeInfo *LSI); |
6452 | |
6453 | /// Get the return type to use for a lambda's conversion function(s) to |
6454 | /// function pointer type, given the type of the call operator. |
6455 | QualType |
6456 | getLambdaConversionFunctionResultType(const FunctionProtoType *CallOpType); |
6457 | |
6458 | /// Define the "body" of the conversion from a lambda object to a |
6459 | /// function pointer. |
6460 | /// |
6461 | /// This routine doesn't actually define a sensible body; rather, it fills |
6462 | /// in the initialization expression needed to copy the lambda object into |
6463 | /// the block, and IR generation actually generates the real body of the |
6464 | /// block pointer conversion. |
6465 | void DefineImplicitLambdaToFunctionPointerConversion( |
6466 | SourceLocation CurrentLoc, CXXConversionDecl *Conv); |
6467 | |
6468 | /// Define the "body" of the conversion from a lambda object to a |
6469 | /// block pointer. |
6470 | /// |
6471 | /// This routine doesn't actually define a sensible body; rather, it fills |
6472 | /// in the initialization expression needed to copy the lambda object into |
6473 | /// the block, and IR generation actually generates the real body of the |
6474 | /// block pointer conversion. |
6475 | void DefineImplicitLambdaToBlockPointerConversion(SourceLocation CurrentLoc, |
6476 | CXXConversionDecl *Conv); |
6477 | |
6478 | ExprResult BuildBlockForLambdaConversion(SourceLocation CurrentLocation, |
6479 | SourceLocation ConvLocation, |
6480 | CXXConversionDecl *Conv, |
6481 | Expr *Src); |
6482 | |
6483 | /// Check whether the given expression is a valid constraint expression. |
6484 | /// A diagnostic is emitted if it is not, false is returned, and |
6485 | /// PossibleNonPrimary will be set to true if the failure might be due to a |
6486 | /// non-primary expression being used as an atomic constraint. |
6487 | bool CheckConstraintExpression(const Expr *CE, Token NextToken = Token(), |
6488 | bool *PossibleNonPrimary = nullptr, |
6489 | bool IsTrailingRequiresClause = false); |
6490 | |
6491 | private: |
6492 | /// Caches pairs of template-like decls whose associated constraints were |
6493 | /// checked for subsumption and whether or not the first's constraints did in |
6494 | /// fact subsume the second's. |
6495 | llvm::DenseMap<std::pair<NamedDecl *, NamedDecl *>, bool> SubsumptionCache; |
6496 | /// Caches the normalized associated constraints of declarations (concepts or |
6497 | /// constrained declarations). If an error occurred while normalizing the |
6498 | /// associated constraints of the template or concept, nullptr will be cached |
6499 | /// here. |
6500 | llvm::DenseMap<NamedDecl *, NormalizedConstraint *> |
6501 | NormalizationCache; |
6502 | |
6503 | llvm::ContextualFoldingSet<ConstraintSatisfaction, const ASTContext &> |
6504 | SatisfactionCache; |
6505 | |
6506 | public: |
6507 | const NormalizedConstraint * |
6508 | getNormalizedAssociatedConstraints( |
6509 | NamedDecl *ConstrainedDecl, ArrayRef<const Expr *> AssociatedConstraints); |
6510 | |
6511 | /// \brief Check whether the given declaration's associated constraints are |
6512 | /// at least as constrained than another declaration's according to the |
6513 | /// partial ordering of constraints. |
6514 | /// |
6515 | /// \param Result If no error occurred, receives the result of true if D1 is |
6516 | /// at least constrained than D2, and false otherwise. |
6517 | /// |
6518 | /// \returns true if an error occurred, false otherwise. |
6519 | bool IsAtLeastAsConstrained(NamedDecl *D1, ArrayRef<const Expr *> AC1, |
6520 | NamedDecl *D2, ArrayRef<const Expr *> AC2, |
6521 | bool &Result); |
6522 | |
6523 | /// If D1 was not at least as constrained as D2, but would've been if a pair |
6524 | /// of atomic constraints involved had been declared in a concept and not |
6525 | /// repeated in two separate places in code. |
6526 | /// \returns true if such a diagnostic was emitted, false otherwise. |
6527 | bool MaybeEmitAmbiguousAtomicConstraintsDiagnostic(NamedDecl *D1, |
6528 | ArrayRef<const Expr *> AC1, NamedDecl *D2, ArrayRef<const Expr *> AC2); |
6529 | |
6530 | /// \brief Check whether the given list of constraint expressions are |
6531 | /// satisfied (as if in a 'conjunction') given template arguments. |
6532 | /// \param Template the template-like entity that triggered the constraints |
6533 | /// check (either a concept or a constrained entity). |
6534 | /// \param ConstraintExprs a list of constraint expressions, treated as if |
6535 | /// they were 'AND'ed together. |
6536 | /// \param TemplateArgs the list of template arguments to substitute into the |
6537 | /// constraint expression. |
6538 | /// \param TemplateIDRange The source range of the template id that |
6539 | /// caused the constraints check. |
6540 | /// \param Satisfaction if true is returned, will contain details of the |
6541 | /// satisfaction, with enough information to diagnose an unsatisfied |
6542 | /// expression. |
6543 | /// \returns true if an error occurred and satisfaction could not be checked, |
6544 | /// false otherwise. |
6545 | bool CheckConstraintSatisfaction( |
6546 | const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs, |
6547 | ArrayRef<TemplateArgument> TemplateArgs, |
6548 | SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction); |
6549 | |
6550 | /// \brief Check whether the given non-dependent constraint expression is |
6551 | /// satisfied. Returns false and updates Satisfaction with the satisfaction |
6552 | /// verdict if successful, emits a diagnostic and returns true if an error |
6553 | /// occured and satisfaction could not be determined. |
6554 | /// |
6555 | /// \returns true if an error occurred, false otherwise. |
6556 | bool CheckConstraintSatisfaction(const Expr *ConstraintExpr, |
6557 | ConstraintSatisfaction &Satisfaction); |
6558 | |
6559 | /// Check whether the given function decl's trailing requires clause is |
6560 | /// satisfied, if any. Returns false and updates Satisfaction with the |
6561 | /// satisfaction verdict if successful, emits a diagnostic and returns true if |
6562 | /// an error occured and satisfaction could not be determined. |
6563 | /// |
6564 | /// \returns true if an error occurred, false otherwise. |
6565 | bool CheckFunctionConstraints(const FunctionDecl *FD, |
6566 | ConstraintSatisfaction &Satisfaction, |
6567 | SourceLocation UsageLoc = SourceLocation()); |
6568 | |
6569 | |
6570 | /// \brief Ensure that the given template arguments satisfy the constraints |
6571 | /// associated with the given template, emitting a diagnostic if they do not. |
6572 | /// |
6573 | /// \param Template The template to which the template arguments are being |
6574 | /// provided. |
6575 | /// |
6576 | /// \param TemplateArgs The converted, canonicalized template arguments. |
6577 | /// |
6578 | /// \param TemplateIDRange The source range of the template id that |
6579 | /// caused the constraints check. |
6580 | /// |
6581 | /// \returns true if the constrains are not satisfied or could not be checked |
6582 | /// for satisfaction, false if the constraints are satisfied. |
6583 | bool EnsureTemplateArgumentListConstraints(TemplateDecl *Template, |
6584 | ArrayRef<TemplateArgument> TemplateArgs, |
6585 | SourceRange TemplateIDRange); |
6586 | |
6587 | /// \brief Emit diagnostics explaining why a constraint expression was deemed |
6588 | /// unsatisfied. |
6589 | /// \param First whether this is the first time an unsatisfied constraint is |
6590 | /// diagnosed for this error. |
6591 | void |
6592 | DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction &Satisfaction, |
6593 | bool First = true); |
6594 | |
6595 | /// \brief Emit diagnostics explaining why a constraint expression was deemed |
6596 | /// unsatisfied. |
6597 | void |
6598 | DiagnoseUnsatisfiedConstraint(const ASTConstraintSatisfaction &Satisfaction, |
6599 | bool First = true); |
6600 | |
6601 | /// \brief Emit diagnostics explaining why a constraint expression was deemed |
6602 | /// unsatisfied because it was ill-formed. |
6603 | void DiagnoseUnsatisfiedIllFormedConstraint(SourceLocation DiagnosticLocation, |
6604 | StringRef Diagnostic); |
6605 | |
6606 | void DiagnoseRedeclarationConstraintMismatch(SourceLocation Old, |
6607 | SourceLocation New); |
6608 | |
6609 | // ParseObjCStringLiteral - Parse Objective-C string literals. |
6610 | ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs, |
6611 | ArrayRef<Expr *> Strings); |
6612 | |
6613 | ExprResult BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S); |
6614 | |
6615 | /// BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the |
6616 | /// numeric literal expression. Type of the expression will be "NSNumber *" |
6617 | /// or "id" if NSNumber is unavailable. |
6618 | ExprResult BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number); |
6619 | ExprResult ActOnObjCBoolLiteral(SourceLocation AtLoc, SourceLocation ValueLoc, |
6620 | bool Value); |
6621 | ExprResult BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements); |
6622 | |
6623 | /// BuildObjCBoxedExpr - builds an ObjCBoxedExpr AST node for the |
6624 | /// '@' prefixed parenthesized expression. The type of the expression will |
6625 | /// either be "NSNumber *", "NSString *" or "NSValue *" depending on the type |
6626 | /// of ValueType, which is allowed to be a built-in numeric type, "char *", |
6627 | /// "const char *" or C structure with attribute 'objc_boxable'. |
6628 | ExprResult BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr); |
6629 | |
6630 | ExprResult BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr, |
6631 | Expr *IndexExpr, |
6632 | ObjCMethodDecl *getterMethod, |
6633 | ObjCMethodDecl *setterMethod); |
6634 | |
6635 | ExprResult BuildObjCDictionaryLiteral(SourceRange SR, |
6636 | MutableArrayRef<ObjCDictionaryElement> Elements); |
6637 | |
6638 | ExprResult BuildObjCEncodeExpression(SourceLocation AtLoc, |
6639 | TypeSourceInfo *EncodedTypeInfo, |
6640 | SourceLocation RParenLoc); |
6641 | ExprResult BuildCXXMemberCallExpr(Expr *Exp, NamedDecl *FoundDecl, |
6642 | CXXConversionDecl *Method, |
6643 | bool HadMultipleCandidates); |
6644 | |
6645 | ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc, |
6646 | SourceLocation EncodeLoc, |
6647 | SourceLocation LParenLoc, |
6648 | ParsedType Ty, |
6649 | SourceLocation RParenLoc); |
6650 | |
6651 | /// ParseObjCSelectorExpression - Build selector expression for \@selector |
6652 | ExprResult ParseObjCSelectorExpression(Selector Sel, |
6653 | SourceLocation AtLoc, |
6654 | SourceLocation SelLoc, |
6655 | SourceLocation LParenLoc, |
6656 | SourceLocation RParenLoc, |
6657 | bool WarnMultipleSelectors); |
6658 | |
6659 | /// ParseObjCProtocolExpression - Build protocol expression for \@protocol |
6660 | ExprResult ParseObjCProtocolExpression(IdentifierInfo * ProtocolName, |
6661 | SourceLocation AtLoc, |
6662 | SourceLocation ProtoLoc, |
6663 | SourceLocation LParenLoc, |
6664 | SourceLocation ProtoIdLoc, |
6665 | SourceLocation RParenLoc); |
6666 | |
6667 | //===--------------------------------------------------------------------===// |
6668 | // C++ Declarations |
6669 | // |
6670 | Decl *ActOnStartLinkageSpecification(Scope *S, |
6671 | SourceLocation ExternLoc, |
6672 | Expr *LangStr, |
6673 | SourceLocation LBraceLoc); |
6674 | Decl *ActOnFinishLinkageSpecification(Scope *S, |
6675 | Decl *LinkageSpec, |
6676 | SourceLocation RBraceLoc); |
6677 | |
6678 | |
6679 | //===--------------------------------------------------------------------===// |
6680 | // C++ Classes |
6681 | // |
6682 | CXXRecordDecl *getCurrentClass(Scope *S, const CXXScopeSpec *SS); |
6683 | bool isCurrentClassName(const IdentifierInfo &II, Scope *S, |
6684 | const CXXScopeSpec *SS = nullptr); |
6685 | bool isCurrentClassNameTypo(IdentifierInfo *&II, const CXXScopeSpec *SS); |
6686 | |
6687 | bool ActOnAccessSpecifier(AccessSpecifier Access, SourceLocation ASLoc, |
6688 | SourceLocation ColonLoc, |
6689 | const ParsedAttributesView &Attrs); |
6690 | |
6691 | NamedDecl *ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, |
6692 | Declarator &D, |
6693 | MultiTemplateParamsArg TemplateParameterLists, |
6694 | Expr *BitfieldWidth, const VirtSpecifiers &VS, |
6695 | InClassInitStyle InitStyle); |
6696 | |
6697 | void ActOnStartCXXInClassMemberInitializer(); |
6698 | void ActOnFinishCXXInClassMemberInitializer(Decl *VarDecl, |
6699 | SourceLocation EqualLoc, |
6700 | Expr *Init); |
6701 | |
6702 | MemInitResult ActOnMemInitializer(Decl *ConstructorD, |
6703 | Scope *S, |
6704 | CXXScopeSpec &SS, |
6705 | IdentifierInfo *MemberOrBase, |
6706 | ParsedType TemplateTypeTy, |
6707 | const DeclSpec &DS, |
6708 | SourceLocation IdLoc, |
6709 | SourceLocation LParenLoc, |
6710 | ArrayRef<Expr *> Args, |
6711 | SourceLocation RParenLoc, |
6712 | SourceLocation EllipsisLoc); |
6713 | |
6714 | MemInitResult ActOnMemInitializer(Decl *ConstructorD, |
6715 | Scope *S, |
6716 | CXXScopeSpec &SS, |
6717 | IdentifierInfo *MemberOrBase, |
6718 | ParsedType TemplateTypeTy, |
6719 | const DeclSpec &DS, |
6720 | SourceLocation IdLoc, |
6721 | Expr *InitList, |
6722 | SourceLocation EllipsisLoc); |
6723 | |
6724 | MemInitResult BuildMemInitializer(Decl *ConstructorD, |
6725 | Scope *S, |
6726 | CXXScopeSpec &SS, |
6727 | IdentifierInfo *MemberOrBase, |
6728 | ParsedType TemplateTypeTy, |
6729 | const DeclSpec &DS, |
6730 | SourceLocation IdLoc, |
6731 | Expr *Init, |
6732 | SourceLocation EllipsisLoc); |
6733 | |
6734 | MemInitResult BuildMemberInitializer(ValueDecl *Member, |
6735 | Expr *Init, |
6736 | SourceLocation IdLoc); |
6737 | |
6738 | MemInitResult BuildBaseInitializer(QualType BaseType, |
6739 | TypeSourceInfo *BaseTInfo, |
6740 | Expr *Init, |
6741 | CXXRecordDecl *ClassDecl, |
6742 | SourceLocation EllipsisLoc); |
6743 | |
6744 | MemInitResult BuildDelegatingInitializer(TypeSourceInfo *TInfo, |
6745 | Expr *Init, |
6746 | CXXRecordDecl *ClassDecl); |
6747 | |
6748 | bool SetDelegatingInitializer(CXXConstructorDecl *Constructor, |
6749 | CXXCtorInitializer *Initializer); |
6750 | |
6751 | bool SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors, |
6752 | ArrayRef<CXXCtorInitializer *> Initializers = None); |
6753 | |
6754 | void SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation); |
6755 | |
6756 | |
6757 | /// MarkBaseAndMemberDestructorsReferenced - Given a record decl, |
6758 | /// mark all the non-trivial destructors of its members and bases as |
6759 | /// referenced. |
6760 | void MarkBaseAndMemberDestructorsReferenced(SourceLocation Loc, |
6761 | CXXRecordDecl *Record); |
6762 | |
6763 | /// Mark destructors of virtual bases of this class referenced. In the Itanium |
6764 | /// C++ ABI, this is done when emitting a destructor for any non-abstract |
6765 | /// class. In the Microsoft C++ ABI, this is done any time a class's |
6766 | /// destructor is referenced. |
6767 | void MarkVirtualBaseDestructorsReferenced( |
6768 | SourceLocation Location, CXXRecordDecl *ClassDecl, |
6769 | llvm::SmallPtrSetImpl<const RecordType *> *DirectVirtualBases = nullptr); |
6770 | |
6771 | /// Do semantic checks to allow the complete destructor variant to be emitted |
6772 | /// when the destructor is defined in another translation unit. In the Itanium |
6773 | /// C++ ABI, destructor variants are emitted together. In the MS C++ ABI, they |
6774 | /// can be emitted in separate TUs. To emit the complete variant, run a subset |
6775 | /// of the checks performed when emitting a regular destructor. |
6776 | void CheckCompleteDestructorVariant(SourceLocation CurrentLocation, |
6777 | CXXDestructorDecl *Dtor); |
6778 | |
6779 | /// The list of classes whose vtables have been used within |
6780 | /// this translation unit, and the source locations at which the |
6781 | /// first use occurred. |
6782 | typedef std::pair<CXXRecordDecl*, SourceLocation> VTableUse; |
6783 | |
6784 | /// The list of vtables that are required but have not yet been |
6785 | /// materialized. |
6786 | SmallVector<VTableUse, 16> VTableUses; |
6787 | |
6788 | /// The set of classes whose vtables have been used within |
6789 | /// this translation unit, and a bit that will be true if the vtable is |
6790 | /// required to be emitted (otherwise, it should be emitted only if needed |
6791 | /// by code generation). |
6792 | llvm::DenseMap<CXXRecordDecl *, bool> VTablesUsed; |
6793 | |
6794 | /// Load any externally-stored vtable uses. |
6795 | void LoadExternalVTableUses(); |
6796 | |
6797 | /// Note that the vtable for the given class was used at the |
6798 | /// given location. |
6799 | void MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class, |
6800 | bool DefinitionRequired = false); |
6801 | |
6802 | /// Mark the exception specifications of all virtual member functions |
6803 | /// in the given class as needed. |
6804 | void MarkVirtualMemberExceptionSpecsNeeded(SourceLocation Loc, |
6805 | const CXXRecordDecl *RD); |
6806 | |
6807 | /// MarkVirtualMembersReferenced - Will mark all members of the given |
6808 | /// CXXRecordDecl referenced. |
6809 | void MarkVirtualMembersReferenced(SourceLocation Loc, const CXXRecordDecl *RD, |
6810 | bool ConstexprOnly = false); |
6811 | |
6812 | /// Define all of the vtables that have been used in this |
6813 | /// translation unit and reference any virtual members used by those |
6814 | /// vtables. |
6815 | /// |
6816 | /// \returns true if any work was done, false otherwise. |
6817 | bool DefineUsedVTables(); |
6818 | |
6819 | void AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl); |
6820 | |
6821 | void ActOnMemInitializers(Decl *ConstructorDecl, |
6822 | SourceLocation ColonLoc, |
6823 | ArrayRef<CXXCtorInitializer*> MemInits, |
6824 | bool AnyErrors); |
6825 | |
6826 | /// Check class-level dllimport/dllexport attribute. The caller must |
6827 | /// ensure that referenceDLLExportedClassMethods is called some point later |
6828 | /// when all outer classes of Class are complete. |
6829 | void checkClassLevelDLLAttribute(CXXRecordDecl *Class); |
6830 | void checkClassLevelCodeSegAttribute(CXXRecordDecl *Class); |
6831 | |
6832 | void referenceDLLExportedClassMethods(); |
6833 | |
6834 | void propagateDLLAttrToBaseClassTemplate( |
6835 | CXXRecordDecl *Class, Attr *ClassAttr, |
6836 | ClassTemplateSpecializationDecl *BaseTemplateSpec, |
6837 | SourceLocation BaseLoc); |
6838 | |
6839 | /// Add gsl::Pointer attribute to std::container::iterator |
6840 | /// \param ND The declaration that introduces the name |
6841 | /// std::container::iterator. \param UnderlyingRecord The record named by ND. |
6842 | void inferGslPointerAttribute(NamedDecl *ND, CXXRecordDecl *UnderlyingRecord); |
6843 | |
6844 | /// Add [[gsl::Owner]] and [[gsl::Pointer]] attributes for std:: types. |
6845 | void inferGslOwnerPointerAttribute(CXXRecordDecl *Record); |
6846 | |
6847 | /// Add [[gsl::Pointer]] attributes for std:: types. |
6848 | void inferGslPointerAttribute(TypedefNameDecl *TD); |
6849 | |
6850 | void CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record); |
6851 | |
6852 | /// Check that the C++ class annoated with "trivial_abi" satisfies all the |
6853 | /// conditions that are needed for the attribute to have an effect. |
6854 | void checkIllFormedTrivialABIStruct(CXXRecordDecl &RD); |
6855 | |
6856 | void ActOnFinishCXXMemberSpecification(Scope *S, SourceLocation RLoc, |
6857 | Decl *TagDecl, SourceLocation LBrac, |
6858 | SourceLocation RBrac, |
6859 | const ParsedAttributesView &AttrList); |
6860 | void ActOnFinishCXXMemberDecls(); |
6861 | void ActOnFinishCXXNonNestedClass(); |
6862 | |
6863 | void ActOnReenterCXXMethodParameter(Scope *S, ParmVarDecl *Param); |
6864 | unsigned ActOnReenterTemplateScope(Decl *Template, |
6865 | llvm::function_ref<Scope *()> EnterScope); |
6866 | void ActOnStartDelayedMemberDeclarations(Scope *S, Decl *Record); |
6867 | void ActOnStartDelayedCXXMethodDeclaration(Scope *S, Decl *Method); |
6868 | void ActOnDelayedCXXMethodParameter(Scope *S, Decl *Param); |
6869 | void ActOnFinishDelayedMemberDeclarations(Scope *S, Decl *Record); |
6870 | void ActOnFinishDelayedCXXMethodDeclaration(Scope *S, Decl *Method); |
6871 | void ActOnFinishDelayedMemberInitializers(Decl *Record); |
6872 | void MarkAsLateParsedTemplate(FunctionDecl *FD, Decl *FnD, |
6873 | CachedTokens &Toks); |
6874 | void UnmarkAsLateParsedTemplate(FunctionDecl *FD); |
6875 | bool IsInsideALocalClassWithinATemplateFunction(); |
6876 | |
6877 | Decl *ActOnStaticAssertDeclaration(SourceLocation StaticAssertLoc, |
6878 | Expr *AssertExpr, |
6879 | Expr *AssertMessageExpr, |
6880 | SourceLocation RParenLoc); |
6881 | Decl *BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc, |
6882 | Expr *AssertExpr, |
6883 | StringLiteral *AssertMessageExpr, |
6884 | SourceLocation RParenLoc, |
6885 | bool Failed); |
6886 | |
6887 | FriendDecl *CheckFriendTypeDecl(SourceLocation LocStart, |
6888 | SourceLocation FriendLoc, |
6889 | TypeSourceInfo *TSInfo); |
6890 | Decl *ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS, |
6891 | MultiTemplateParamsArg TemplateParams); |
6892 | NamedDecl *ActOnFriendFunctionDecl(Scope *S, Declarator &D, |
6893 | MultiTemplateParamsArg TemplateParams); |
6894 | |
6895 | QualType CheckConstructorDeclarator(Declarator &D, QualType R, |
6896 | StorageClass& SC); |
6897 | void CheckConstructor(CXXConstructorDecl *Constructor); |
6898 | QualType CheckDestructorDeclarator(Declarator &D, QualType R, |
6899 | StorageClass& SC); |
6900 | bool CheckDestructor(CXXDestructorDecl *Destructor); |
6901 | void CheckConversionDeclarator(Declarator &D, QualType &R, |
6902 | StorageClass& SC); |
6903 | Decl *ActOnConversionDeclarator(CXXConversionDecl *Conversion); |
6904 | void CheckDeductionGuideDeclarator(Declarator &D, QualType &R, |
6905 | StorageClass &SC); |
6906 | void CheckDeductionGuideTemplate(FunctionTemplateDecl *TD); |
6907 | |
6908 | void CheckExplicitlyDefaultedFunction(Scope *S, FunctionDecl *MD); |
6909 | |
6910 | bool CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD, |
6911 | CXXSpecialMember CSM); |
6912 | void CheckDelayedMemberExceptionSpecs(); |
6913 | |
6914 | bool CheckExplicitlyDefaultedComparison(Scope *S, FunctionDecl *MD, |
6915 | DefaultedComparisonKind DCK); |
6916 | void DeclareImplicitEqualityComparison(CXXRecordDecl *RD, |
6917 | FunctionDecl *Spaceship); |
6918 | void DefineDefaultedComparison(SourceLocation Loc, FunctionDecl *FD, |
6919 | DefaultedComparisonKind DCK); |
6920 | |
6921 | //===--------------------------------------------------------------------===// |
6922 | // C++ Derived Classes |
6923 | // |
6924 | |
6925 | /// ActOnBaseSpecifier - Parsed a base specifier |
6926 | CXXBaseSpecifier *CheckBaseSpecifier(CXXRecordDecl *Class, |
6927 | SourceRange SpecifierRange, |
6928 | bool Virtual, AccessSpecifier Access, |
6929 | TypeSourceInfo *TInfo, |
6930 | SourceLocation EllipsisLoc); |
6931 | |
6932 | BaseResult ActOnBaseSpecifier(Decl *classdecl, |
6933 | SourceRange SpecifierRange, |
6934 | ParsedAttributes &Attrs, |
6935 | bool Virtual, AccessSpecifier Access, |
6936 | ParsedType basetype, |
6937 | SourceLocation BaseLoc, |
6938 | SourceLocation EllipsisLoc); |
6939 | |
6940 | bool AttachBaseSpecifiers(CXXRecordDecl *Class, |
6941 | MutableArrayRef<CXXBaseSpecifier *> Bases); |
6942 | void ActOnBaseSpecifiers(Decl *ClassDecl, |
6943 | MutableArrayRef<CXXBaseSpecifier *> Bases); |
6944 | |
6945 | bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base); |
6946 | bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base, |
6947 | CXXBasePaths &Paths); |
6948 | |
6949 | // FIXME: I don't like this name. |
6950 | void BuildBasePathArray(const CXXBasePaths &Paths, CXXCastPath &BasePath); |
6951 | |
6952 | bool CheckDerivedToBaseConversion(QualType Derived, QualType Base, |
6953 | SourceLocation Loc, SourceRange Range, |
6954 | CXXCastPath *BasePath = nullptr, |
6955 | bool IgnoreAccess = false); |
6956 | bool CheckDerivedToBaseConversion(QualType Derived, QualType Base, |
6957 | unsigned InaccessibleBaseID, |
6958 | unsigned AmbiguousBaseConvID, |
6959 | SourceLocation Loc, SourceRange Range, |
6960 | DeclarationName Name, |
6961 | CXXCastPath *BasePath, |
6962 | bool IgnoreAccess = false); |
6963 | |
6964 | std::string getAmbiguousPathsDisplayString(CXXBasePaths &Paths); |
6965 | |
6966 | bool CheckOverridingFunctionAttributes(const CXXMethodDecl *New, |
6967 | const CXXMethodDecl *Old); |
6968 | |
6969 | /// CheckOverridingFunctionReturnType - Checks whether the return types are |
6970 | /// covariant, according to C++ [class.virtual]p5. |
6971 | bool CheckOverridingFunctionReturnType(const CXXMethodDecl *New, |
6972 | const CXXMethodDecl *Old); |
6973 | |
6974 | /// CheckOverridingFunctionExceptionSpec - Checks whether the exception |
6975 | /// spec is a subset of base spec. |
6976 | bool CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New, |
6977 | const CXXMethodDecl *Old); |
6978 | |
6979 | bool CheckPureMethod(CXXMethodDecl *Method, SourceRange InitRange); |
6980 | |
6981 | /// CheckOverrideControl - Check C++11 override control semantics. |
6982 | void CheckOverrideControl(NamedDecl *D); |
6983 | |
6984 | /// DiagnoseAbsenceOfOverrideControl - Diagnose if 'override' keyword was |
6985 | /// not used in the declaration of an overriding method. |
6986 | void DiagnoseAbsenceOfOverrideControl(NamedDecl *D, bool Inconsistent); |
6987 | |
6988 | /// CheckForFunctionMarkedFinal - Checks whether a virtual member function |
6989 | /// overrides a virtual member function marked 'final', according to |
6990 | /// C++11 [class.virtual]p4. |
6991 | bool CheckIfOverriddenFunctionIsMarkedFinal(const CXXMethodDecl *New, |
6992 | const CXXMethodDecl *Old); |
6993 | |
6994 | |
6995 | //===--------------------------------------------------------------------===// |
6996 | // C++ Access Control |
6997 | // |
6998 | |
6999 | enum AccessResult { |
7000 | AR_accessible, |
7001 | AR_inaccessible, |
7002 | AR_dependent, |
7003 | AR_delayed |
7004 | }; |
7005 | |
7006 | bool SetMemberAccessSpecifier(NamedDecl *MemberDecl, |
7007 | NamedDecl *PrevMemberDecl, |
7008 | AccessSpecifier LexicalAS); |
7009 | |
7010 | AccessResult CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E, |
7011 | DeclAccessPair FoundDecl); |
7012 | AccessResult CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E, |
7013 | DeclAccessPair FoundDecl); |
7014 | AccessResult CheckAllocationAccess(SourceLocation OperatorLoc, |
7015 | SourceRange PlacementRange, |
7016 | CXXRecordDecl *NamingClass, |
7017 | DeclAccessPair FoundDecl, |
7018 | bool Diagnose = true); |
7019 | AccessResult CheckConstructorAccess(SourceLocation Loc, |
7020 | CXXConstructorDecl *D, |
7021 | DeclAccessPair FoundDecl, |
7022 | const InitializedEntity &Entity, |
7023 | bool IsCopyBindingRefToTemp = false); |
7024 | AccessResult CheckConstructorAccess(SourceLocation Loc, |
7025 | CXXConstructorDecl *D, |
7026 | DeclAccessPair FoundDecl, |
7027 | const InitializedEntity &Entity, |
7028 | const PartialDiagnostic &PDiag); |
7029 | AccessResult CheckDestructorAccess(SourceLocation Loc, |
7030 | CXXDestructorDecl *Dtor, |
7031 | const PartialDiagnostic &PDiag, |
7032 | QualType objectType = QualType()); |
7033 | AccessResult CheckFriendAccess(NamedDecl *D); |
7034 | AccessResult CheckMemberAccess(SourceLocation UseLoc, |
7035 | CXXRecordDecl *NamingClass, |
7036 | DeclAccessPair Found); |
7037 | AccessResult |
7038 | CheckStructuredBindingMemberAccess(SourceLocation UseLoc, |
7039 | CXXRecordDecl *DecomposedClass, |
7040 | DeclAccessPair Field); |
7041 | AccessResult CheckMemberOperatorAccess(SourceLocation Loc, |
7042 | Expr *ObjectExpr, |
7043 | Expr *ArgExpr, |
7044 | DeclAccessPair FoundDecl); |
7045 | AccessResult CheckAddressOfMemberAccess(Expr *OvlExpr, |
7046 | DeclAccessPair FoundDecl); |
7047 | AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, |
7048 | QualType Base, QualType Derived, |
7049 | const CXXBasePath &Path, |
7050 | unsigned DiagID, |
7051 | bool ForceCheck = false, |
7052 | bool ForceUnprivileged = false); |
7053 | void CheckLookupAccess(const LookupResult &R); |
7054 | bool IsSimplyAccessible(NamedDecl *Decl, CXXRecordDecl *NamingClass, |
7055 | QualType BaseType); |
7056 | bool isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass, |
7057 | DeclAccessPair Found, QualType ObjectType, |
7058 | SourceLocation Loc, |
7059 | const PartialDiagnostic &Diag); |
7060 | bool isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass, |
7061 | DeclAccessPair Found, |
7062 | QualType ObjectType) { |
7063 | return isMemberAccessibleForDeletion(NamingClass, Found, ObjectType, |
7064 | SourceLocation(), PDiag()); |
7065 | } |
7066 | |
7067 | void HandleDependentAccessCheck(const DependentDiagnostic &DD, |
7068 | const MultiLevelTemplateArgumentList &TemplateArgs); |
7069 | void PerformDependentDiagnostics(const DeclContext *Pattern, |
7070 | const MultiLevelTemplateArgumentList &TemplateArgs); |
7071 | |
7072 | void HandleDelayedAccessCheck(sema::DelayedDiagnostic &DD, Decl *Ctx); |
7073 | |
7074 | /// When true, access checking violations are treated as SFINAE |
7075 | /// failures rather than hard errors. |
7076 | bool AccessCheckingSFINAE; |
7077 | |
7078 | enum AbstractDiagSelID { |
7079 | AbstractNone = -1, |
7080 | AbstractReturnType, |
7081 | AbstractParamType, |
7082 | AbstractVariableType, |
7083 | AbstractFieldType, |
7084 | AbstractIvarType, |
7085 | AbstractSynthesizedIvarType, |
7086 | AbstractArrayType |
7087 | }; |
7088 | |
7089 | bool isAbstractType(SourceLocation Loc, QualType T); |
7090 | bool RequireNonAbstractType(SourceLocation Loc, QualType T, |
7091 | TypeDiagnoser &Diagnoser); |
7092 | template <typename... Ts> |
7093 | bool RequireNonAbstractType(SourceLocation Loc, QualType T, unsigned DiagID, |
7094 | const Ts &...Args) { |
7095 | BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...); |
7096 | return RequireNonAbstractType(Loc, T, Diagnoser); |
7097 | } |
7098 | |
7099 | void DiagnoseAbstractType(const CXXRecordDecl *RD); |
7100 | |
7101 | //===--------------------------------------------------------------------===// |
7102 | // C++ Overloaded Operators [C++ 13.5] |
7103 | // |
7104 | |
7105 | bool CheckOverloadedOperatorDeclaration(FunctionDecl *FnDecl); |
7106 | |
7107 | bool CheckLiteralOperatorDeclaration(FunctionDecl *FnDecl); |
7108 | |
7109 | //===--------------------------------------------------------------------===// |
7110 | // C++ Templates [C++ 14] |
7111 | // |
7112 | void FilterAcceptableTemplateNames(LookupResult &R, |
7113 | bool AllowFunctionTemplates = true, |
7114 | bool AllowDependent = true); |
7115 | bool hasAnyAcceptableTemplateNames(LookupResult &R, |
7116 | bool AllowFunctionTemplates = true, |
7117 | bool AllowDependent = true, |
7118 | bool AllowNonTemplateFunctions = false); |
7119 | /// Try to interpret the lookup result D as a template-name. |
7120 | /// |
7121 | /// \param D A declaration found by name lookup. |
7122 | /// \param AllowFunctionTemplates Whether function templates should be |
7123 | /// considered valid results. |
7124 | /// \param AllowDependent Whether unresolved using declarations (that might |
7125 | /// name templates) should be considered valid results. |
7126 | NamedDecl *getAsTemplateNameDecl(NamedDecl *D, |
7127 | bool AllowFunctionTemplates = true, |
7128 | bool AllowDependent = true); |
7129 | |
7130 | enum TemplateNameIsRequiredTag { TemplateNameIsRequired }; |
7131 | /// Whether and why a template name is required in this lookup. |
7132 | class RequiredTemplateKind { |
7133 | public: |
7134 | /// Template name is required if TemplateKWLoc is valid. |
7135 | RequiredTemplateKind(SourceLocation TemplateKWLoc = SourceLocation()) |
7136 | : TemplateKW(TemplateKWLoc) {} |
7137 | /// Template name is unconditionally required. |
7138 | RequiredTemplateKind(TemplateNameIsRequiredTag) : TemplateKW() {} |
7139 | |
7140 | SourceLocation getTemplateKeywordLoc() const { |
7141 | return TemplateKW.getValueOr(SourceLocation()); |
7142 | } |
7143 | bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); } |
7144 | bool isRequired() const { return TemplateKW != SourceLocation(); } |
7145 | explicit operator bool() const { return isRequired(); } |
7146 | |
7147 | private: |
7148 | llvm::Optional<SourceLocation> TemplateKW; |
7149 | }; |
7150 | |
7151 | enum class AssumedTemplateKind { |
7152 | /// This is not assumed to be a template name. |
7153 | None, |
7154 | /// This is assumed to be a template name because lookup found nothing. |
7155 | FoundNothing, |
7156 | /// This is assumed to be a template name because lookup found one or more |
7157 | /// functions (but no function templates). |
7158 | FoundFunctions, |
7159 | }; |
7160 | bool LookupTemplateName( |
7161 | LookupResult &R, Scope *S, CXXScopeSpec &SS, QualType ObjectType, |
7162 | bool EnteringContext, bool &MemberOfUnknownSpecialization, |
7163 | RequiredTemplateKind RequiredTemplate = SourceLocation(), |
7164 | AssumedTemplateKind *ATK = nullptr, bool AllowTypoCorrection = true); |
7165 | |
7166 | TemplateNameKind isTemplateName(Scope *S, |
7167 | CXXScopeSpec &SS, |
7168 | bool hasTemplateKeyword, |
7169 | const UnqualifiedId &Name, |
7170 | ParsedType ObjectType, |
7171 | bool EnteringContext, |
7172 | TemplateTy &Template, |
7173 | bool &MemberOfUnknownSpecialization, |
7174 | bool Disambiguation = false); |
7175 | |
7176 | /// Try to resolve an undeclared template name as a type template. |
7177 | /// |
7178 | /// Sets II to the identifier corresponding to the template name, and updates |
7179 | /// Name to a corresponding (typo-corrected) type template name and TNK to |
7180 | /// the corresponding kind, if possible. |
7181 | void ActOnUndeclaredTypeTemplateName(Scope *S, TemplateTy &Name, |
7182 | TemplateNameKind &TNK, |
7183 | SourceLocation NameLoc, |
7184 | IdentifierInfo *&II); |
7185 | |
7186 | bool resolveAssumedTemplateNameAsType(Scope *S, TemplateName &Name, |
7187 | SourceLocation NameLoc, |
7188 | bool Diagnose = true); |
7189 | |
7190 | /// Determine whether a particular identifier might be the name in a C++1z |
7191 | /// deduction-guide declaration. |
7192 | bool isDeductionGuideName(Scope *S, const IdentifierInfo &Name, |
7193 | SourceLocation NameLoc, |
7194 | ParsedTemplateTy *Template = nullptr); |
7195 | |
7196 | bool DiagnoseUnknownTemplateName(const IdentifierInfo &II, |
7197 | SourceLocation IILoc, |
7198 | Scope *S, |
7199 | const CXXScopeSpec *SS, |
7200 | TemplateTy &SuggestedTemplate, |
7201 | TemplateNameKind &SuggestedKind); |
7202 | |
7203 | bool DiagnoseUninstantiableTemplate(SourceLocation PointOfInstantiation, |
7204 | NamedDecl *Instantiation, |
7205 | bool InstantiatedFromMember, |
7206 | const NamedDecl *Pattern, |
7207 | const NamedDecl *PatternDef, |
7208 | TemplateSpecializationKind TSK, |
7209 | bool Complain = true); |
7210 | |
7211 | void DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl); |
7212 | TemplateDecl *AdjustDeclIfTemplate(Decl *&Decl); |
7213 | |
7214 | NamedDecl *ActOnTypeParameter(Scope *S, bool Typename, |
7215 | SourceLocation EllipsisLoc, |
7216 | SourceLocation KeyLoc, |
7217 | IdentifierInfo *ParamName, |
7218 | SourceLocation ParamNameLoc, |
7219 | unsigned Depth, unsigned Position, |
7220 | SourceLocation EqualLoc, |
7221 | ParsedType DefaultArg, bool HasTypeConstraint); |
7222 | |
7223 | bool ActOnTypeConstraint(const CXXScopeSpec &SS, |
7224 | TemplateIdAnnotation *TypeConstraint, |
7225 | TemplateTypeParmDecl *ConstrainedParameter, |
7226 | SourceLocation EllipsisLoc); |
7227 | |
7228 | bool AttachTypeConstraint(NestedNameSpecifierLoc NS, |
7229 | DeclarationNameInfo NameInfo, |
7230 | ConceptDecl *NamedConcept, |
7231 | const TemplateArgumentListInfo *TemplateArgs, |
7232 | TemplateTypeParmDecl *ConstrainedParameter, |
7233 | SourceLocation EllipsisLoc); |
7234 | |
7235 | bool AttachTypeConstraint(AutoTypeLoc TL, |
7236 | NonTypeTemplateParmDecl *ConstrainedParameter, |
7237 | SourceLocation EllipsisLoc); |
7238 | |
7239 | QualType CheckNonTypeTemplateParameterType(TypeSourceInfo *&TSI, |
7240 | SourceLocation Loc); |
7241 | QualType CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc); |
7242 | |
7243 | NamedDecl *ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, |
7244 | unsigned Depth, |
7245 | unsigned Position, |
7246 | SourceLocation EqualLoc, |
7247 | Expr *DefaultArg); |
7248 | NamedDecl *ActOnTemplateTemplateParameter(Scope *S, |
7249 | SourceLocation TmpLoc, |
7250 | TemplateParameterList *Params, |
7251 | SourceLocation EllipsisLoc, |
7252 | IdentifierInfo *ParamName, |
7253 | SourceLocation ParamNameLoc, |
7254 | unsigned Depth, |
7255 | unsigned Position, |
7256 | SourceLocation EqualLoc, |
7257 | ParsedTemplateArgument DefaultArg); |
7258 | |
7259 | TemplateParameterList * |
7260 | ActOnTemplateParameterList(unsigned Depth, |
7261 | SourceLocation ExportLoc, |
7262 | SourceLocation TemplateLoc, |
7263 | SourceLocation LAngleLoc, |
7264 | ArrayRef<NamedDecl *> Params, |
7265 | SourceLocation RAngleLoc, |
7266 | Expr *RequiresClause); |
7267 | |
7268 | /// The context in which we are checking a template parameter list. |
7269 | enum TemplateParamListContext { |
7270 | TPC_ClassTemplate, |
7271 | TPC_VarTemplate, |
7272 | TPC_FunctionTemplate, |
7273 | TPC_ClassTemplateMember, |
7274 | TPC_FriendClassTemplate, |
7275 | TPC_FriendFunctionTemplate, |
7276 | TPC_FriendFunctionTemplateDefinition, |
7277 | TPC_TypeAliasTemplate |
7278 | }; |
7279 | |
7280 | bool CheckTemplateParameterList(TemplateParameterList *NewParams, |
7281 | TemplateParameterList *OldParams, |
7282 | TemplateParamListContext TPC, |
7283 | SkipBodyInfo *SkipBody = nullptr); |
7284 | TemplateParameterList *MatchTemplateParametersToScopeSpecifier( |
7285 | SourceLocation DeclStartLoc, SourceLocation DeclLoc, |
7286 | const CXXScopeSpec &SS, TemplateIdAnnotation *TemplateId, |
7287 | ArrayRef<TemplateParameterList *> ParamLists, |
7288 | bool IsFriend, bool &IsMemberSpecialization, bool &Invalid, |
7289 | bool SuppressDiagnostic = false); |
7290 | |
7291 | DeclResult CheckClassTemplate( |
7292 | Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, |
7293 | CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, |
7294 | const ParsedAttributesView &Attr, TemplateParameterList *TemplateParams, |
7295 | AccessSpecifier AS, SourceLocation ModulePrivateLoc, |
7296 | SourceLocation FriendLoc, unsigned NumOuterTemplateParamLists, |
7297 | TemplateParameterList **OuterTemplateParamLists, |
7298 | SkipBodyInfo *SkipBody = nullptr); |
7299 | |
7300 | TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, |
7301 | QualType NTTPType, |
7302 | SourceLocation Loc); |
7303 | |
7304 | /// Get a template argument mapping the given template parameter to itself, |
7305 | /// e.g. for X in \c template<int X>, this would return an expression template |
7306 | /// argument referencing X. |
7307 | TemplateArgumentLoc getIdentityTemplateArgumentLoc(NamedDecl *Param, |
7308 | SourceLocation Location); |
7309 | |
7310 | void translateTemplateArguments(const ASTTemplateArgsPtr &In, |
7311 | TemplateArgumentListInfo &Out); |
7312 | |
7313 | ParsedTemplateArgument ActOnTemplateTypeArgument(TypeResult ParsedType); |
7314 | |
7315 | void NoteAllFoundTemplates(TemplateName Name); |
7316 | |
7317 | QualType CheckTemplateIdType(TemplateName Template, |
7318 | SourceLocation TemplateLoc, |
7319 | TemplateArgumentListInfo &TemplateArgs); |
7320 | |
7321 | TypeResult |
7322 | ActOnTemplateIdType(Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, |
7323 | TemplateTy Template, IdentifierInfo *TemplateII, |
7324 | SourceLocation TemplateIILoc, SourceLocation LAngleLoc, |
7325 | ASTTemplateArgsPtr TemplateArgs, SourceLocation RAngleLoc, |
7326 | bool IsCtorOrDtorName = false, bool IsClassName = false); |
7327 | |
7328 | /// Parsed an elaborated-type-specifier that refers to a template-id, |
7329 | /// such as \c class T::template apply<U>. |
7330 | TypeResult ActOnTagTemplateIdType(TagUseKind TUK, |
7331 | TypeSpecifierType TagSpec, |
7332 | SourceLocation TagLoc, |
7333 | CXXScopeSpec &SS, |
7334 | SourceLocation TemplateKWLoc, |
7335 | TemplateTy TemplateD, |
7336 | SourceLocation TemplateLoc, |
7337 | SourceLocation LAngleLoc, |
7338 | ASTTemplateArgsPtr TemplateArgsIn, |
7339 | SourceLocation RAngleLoc); |
7340 | |
7341 | DeclResult ActOnVarTemplateSpecialization( |
7342 | Scope *S, Declarator &D, TypeSourceInfo *DI, |
7343 | SourceLocation TemplateKWLoc, TemplateParameterList *TemplateParams, |
7344 | StorageClass SC, bool IsPartialSpecialization); |
7345 | |
7346 | /// Get the specialization of the given variable template corresponding to |
7347 | /// the specified argument list, or a null-but-valid result if the arguments |
7348 | /// are dependent. |
7349 | DeclResult CheckVarTemplateId(VarTemplateDecl *Template, |
7350 | SourceLocation TemplateLoc, |
7351 | SourceLocation TemplateNameLoc, |
7352 | const TemplateArgumentListInfo &TemplateArgs); |
7353 | |
7354 | /// Form a reference to the specialization of the given variable template |
7355 | /// corresponding to the specified argument list, or a null-but-valid result |
7356 | /// if the arguments are dependent. |
7357 | ExprResult CheckVarTemplateId(const CXXScopeSpec &SS, |
7358 | const DeclarationNameInfo &NameInfo, |
7359 | VarTemplateDecl *Template, |
7360 | SourceLocation TemplateLoc, |
7361 | const TemplateArgumentListInfo *TemplateArgs); |
7362 | |
7363 | ExprResult |
7364 | CheckConceptTemplateId(const CXXScopeSpec &SS, |
7365 | SourceLocation TemplateKWLoc, |
7366 | const DeclarationNameInfo &ConceptNameInfo, |
7367 | NamedDecl *FoundDecl, ConceptDecl *NamedConcept, |
7368 | const TemplateArgumentListInfo *TemplateArgs); |
7369 | |
7370 | void diagnoseMissingTemplateArguments(TemplateName Name, SourceLocation Loc); |
7371 | |
7372 | ExprResult BuildTemplateIdExpr(const CXXScopeSpec &SS, |
7373 | SourceLocation TemplateKWLoc, |
7374 | LookupResult &R, |
7375 | bool RequiresADL, |
7376 | const TemplateArgumentListInfo *TemplateArgs); |
7377 | |
7378 | ExprResult BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS, |
7379 | SourceLocation TemplateKWLoc, |
7380 | const DeclarationNameInfo &NameInfo, |
7381 | const TemplateArgumentListInfo *TemplateArgs); |
7382 | |
7383 | TemplateNameKind ActOnTemplateName( |
7384 | Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, |
7385 | const UnqualifiedId &Name, ParsedType ObjectType, bool EnteringContext, |
7386 | TemplateTy &Template, bool AllowInjectedClassName = false); |
7387 | |
7388 | DeclResult ActOnClassTemplateSpecialization( |
7389 | Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, |
7390 | SourceLocation ModulePrivateLoc, CXXScopeSpec &SS, |
7391 | TemplateIdAnnotation &TemplateId, const ParsedAttributesView &Attr, |
7392 | MultiTemplateParamsArg TemplateParameterLists, |
7393 | SkipBodyInfo *SkipBody = nullptr); |
7394 | |
7395 | bool CheckTemplatePartialSpecializationArgs(SourceLocation Loc, |
7396 | TemplateDecl *PrimaryTemplate, |
7397 | unsigned NumExplicitArgs, |
7398 | ArrayRef<TemplateArgument> Args); |
7399 | void CheckTemplatePartialSpecialization( |
7400 | ClassTemplatePartialSpecializationDecl *Partial); |
7401 | void CheckTemplatePartialSpecialization( |
7402 | VarTemplatePartialSpecializationDecl *Partial); |
7403 | |
7404 | Decl *ActOnTemplateDeclarator(Scope *S, |
7405 | MultiTemplateParamsArg TemplateParameterLists, |
7406 | Declarator &D); |
7407 | |
7408 | bool |
7409 | CheckSpecializationInstantiationRedecl(SourceLocation NewLoc, |
7410 | TemplateSpecializationKind NewTSK, |
7411 | NamedDecl *PrevDecl, |
7412 | TemplateSpecializationKind PrevTSK, |
7413 | SourceLocation PrevPtOfInstantiation, |
7414 | bool &SuppressNew); |
7415 | |
7416 | bool CheckDependentFunctionTemplateSpecialization(FunctionDecl *FD, |
7417 | const TemplateArgumentListInfo &ExplicitTemplateArgs, |
7418 | LookupResult &Previous); |
7419 | |
7420 | bool CheckFunctionTemplateSpecialization( |
7421 | FunctionDecl *FD, TemplateArgumentListInfo *ExplicitTemplateArgs, |
7422 | LookupResult &Previous, bool QualifiedFriend = false); |
7423 | bool CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous); |
7424 | void CompleteMemberSpecialization(NamedDecl *Member, LookupResult &Previous); |
7425 | |
7426 | DeclResult ActOnExplicitInstantiation( |
7427 | Scope *S, SourceLocation ExternLoc, SourceLocation TemplateLoc, |
7428 | unsigned TagSpec, SourceLocation KWLoc, const CXXScopeSpec &SS, |
7429 | TemplateTy Template, SourceLocation TemplateNameLoc, |
7430 | SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs, |
7431 | SourceLocation RAngleLoc, const ParsedAttributesView &Attr); |
7432 | |
7433 | DeclResult ActOnExplicitInstantiation(Scope *S, SourceLocation ExternLoc, |
7434 | SourceLocation TemplateLoc, |
7435 | unsigned TagSpec, SourceLocation KWLoc, |
7436 | CXXScopeSpec &SS, IdentifierInfo *Name, |
7437 | SourceLocation NameLoc, |
7438 | const ParsedAttributesView &Attr); |
7439 | |
7440 | DeclResult ActOnExplicitInstantiation(Scope *S, |
7441 | SourceLocation ExternLoc, |
7442 | SourceLocation TemplateLoc, |
7443 | Declarator &D); |
7444 | |
7445 | TemplateArgumentLoc |
7446 | SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template, |
7447 | SourceLocation TemplateLoc, |
7448 | SourceLocation RAngleLoc, |
7449 | Decl *Param, |
7450 | SmallVectorImpl<TemplateArgument> |
7451 | &Converted, |
7452 | bool &HasDefaultArg); |
7453 | |
7454 | /// Specifies the context in which a particular template |
7455 | /// argument is being checked. |
7456 | enum CheckTemplateArgumentKind { |
7457 | /// The template argument was specified in the code or was |
7458 | /// instantiated with some deduced template arguments. |
7459 | CTAK_Specified, |
7460 | |
7461 | /// The template argument was deduced via template argument |
7462 | /// deduction. |
7463 | CTAK_Deduced, |
7464 | |
7465 | /// The template argument was deduced from an array bound |
7466 | /// via template argument deduction. |
7467 | CTAK_DeducedFromArrayBound |
7468 | }; |
7469 | |
7470 | bool CheckTemplateArgument(NamedDecl *Param, |
7471 | TemplateArgumentLoc &Arg, |
7472 | NamedDecl *Template, |
7473 | SourceLocation TemplateLoc, |
7474 | SourceLocation RAngleLoc, |
7475 | unsigned ArgumentPackIndex, |
7476 | SmallVectorImpl<TemplateArgument> &Converted, |
7477 | CheckTemplateArgumentKind CTAK = CTAK_Specified); |
7478 | |
7479 | /// Check that the given template arguments can be be provided to |
7480 | /// the given template, converting the arguments along the way. |
7481 | /// |
7482 | /// \param Template The template to which the template arguments are being |
7483 | /// provided. |
7484 | /// |
7485 | /// \param TemplateLoc The location of the template name in the source. |
7486 | /// |
7487 | /// \param TemplateArgs The list of template arguments. If the template is |
7488 | /// a template template parameter, this function may extend the set of |
7489 | /// template arguments to also include substituted, defaulted template |
7490 | /// arguments. |
7491 | /// |
7492 | /// \param PartialTemplateArgs True if the list of template arguments is |
7493 | /// intentionally partial, e.g., because we're checking just the initial |
7494 | /// set of template arguments. |
7495 | /// |
7496 | /// \param Converted Will receive the converted, canonicalized template |
7497 | /// arguments. |
7498 | /// |
7499 | /// \param UpdateArgsWithConversions If \c true, update \p TemplateArgs to |
7500 | /// contain the converted forms of the template arguments as written. |
7501 | /// Otherwise, \p TemplateArgs will not be modified. |
7502 | /// |
7503 | /// \param ConstraintsNotSatisfied If provided, and an error occured, will |
7504 | /// receive true if the cause for the error is the associated constraints of |
7505 | /// the template not being satisfied by the template arguments. |
7506 | /// |
7507 | /// \returns true if an error occurred, false otherwise. |
7508 | bool CheckTemplateArgumentList(TemplateDecl *Template, |
7509 | SourceLocation TemplateLoc, |
7510 | TemplateArgumentListInfo &TemplateArgs, |
7511 | bool PartialTemplateArgs, |
7512 | SmallVectorImpl<TemplateArgument> &Converted, |
7513 | bool UpdateArgsWithConversions = true, |
7514 | bool *ConstraintsNotSatisfied = nullptr); |
7515 | |
7516 | bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param, |
7517 | TemplateArgumentLoc &Arg, |
7518 | SmallVectorImpl<TemplateArgument> &Converted); |
7519 | |
7520 | bool CheckTemplateArgument(TemplateTypeParmDecl *Param, |
7521 | TypeSourceInfo *Arg); |
7522 | ExprResult CheckTemplateArgument(NonTypeTemplateParmDecl *Param, |
7523 | QualType InstantiatedParamType, Expr *Arg, |
7524 | TemplateArgument &Converted, |
7525 | CheckTemplateArgumentKind CTAK = CTAK_Specified); |
7526 | bool CheckTemplateTemplateArgument(TemplateTemplateParmDecl *Param, |
7527 | TemplateParameterList *Params, |
7528 | TemplateArgumentLoc &Arg); |
7529 | |
7530 | ExprResult |
7531 | BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, |
7532 | QualType ParamType, |
7533 | SourceLocation Loc); |
7534 | ExprResult |
7535 | BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg, |
7536 | SourceLocation Loc); |
7537 | |
7538 | /// Enumeration describing how template parameter lists are compared |
7539 | /// for equality. |
7540 | enum TemplateParameterListEqualKind { |
7541 | /// We are matching the template parameter lists of two templates |
7542 | /// that might be redeclarations. |
7543 | /// |
7544 | /// \code |
7545 | /// template<typename T> struct X; |
7546 | /// template<typename T> struct X; |
7547 | /// \endcode |
7548 | TPL_TemplateMatch, |
7549 | |
7550 | /// We are matching the template parameter lists of two template |
7551 | /// template parameters as part of matching the template parameter lists |
7552 | /// of two templates that might be redeclarations. |
7553 | /// |
7554 | /// \code |
7555 | /// template<template<int I> class TT> struct X; |
7556 | /// template<template<int Value> class Other> struct X; |
7557 | /// \endcode |
7558 | TPL_TemplateTemplateParmMatch, |
7559 | |
7560 | /// We are matching the template parameter lists of a template |
7561 | /// template argument against the template parameter lists of a template |
7562 | /// template parameter. |
7563 | /// |
7564 | /// \code |
7565 | /// template<template<int Value> class Metafun> struct X; |
7566 | /// template<int Value> struct integer_c; |
7567 | /// X<integer_c> xic; |
7568 | /// \endcode |
7569 | TPL_TemplateTemplateArgumentMatch |
7570 | }; |
7571 | |
7572 | bool TemplateParameterListsAreEqual(TemplateParameterList *New, |
7573 | TemplateParameterList *Old, |
7574 | bool Complain, |
7575 | TemplateParameterListEqualKind Kind, |
7576 | SourceLocation TemplateArgLoc |
7577 | = SourceLocation()); |
7578 | |
7579 | bool CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams); |
7580 | |
7581 | /// Called when the parser has parsed a C++ typename |
7582 | /// specifier, e.g., "typename T::type". |
7583 | /// |
7584 | /// \param S The scope in which this typename type occurs. |
7585 | /// \param TypenameLoc the location of the 'typename' keyword |
7586 | /// \param SS the nested-name-specifier following the typename (e.g., 'T::'). |
7587 | /// \param II the identifier we're retrieving (e.g., 'type' in the example). |
7588 | /// \param IdLoc the location of the identifier. |
7589 | TypeResult |
7590 | ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, |
7591 | const CXXScopeSpec &SS, const IdentifierInfo &II, |
7592 | SourceLocation IdLoc); |
7593 | |
7594 | /// Called when the parser has parsed a C++ typename |
7595 | /// specifier that ends in a template-id, e.g., |
7596 | /// "typename MetaFun::template apply<T1, T2>". |
7597 | /// |
7598 | /// \param S The scope in which this typename type occurs. |
7599 | /// \param TypenameLoc the location of the 'typename' keyword |
7600 | /// \param SS the nested-name-specifier following the typename (e.g., 'T::'). |
7601 | /// \param TemplateLoc the location of the 'template' keyword, if any. |
7602 | /// \param TemplateName The template name. |
7603 | /// \param TemplateII The identifier used to name the template. |
7604 | /// \param TemplateIILoc The location of the template name. |
7605 | /// \param LAngleLoc The location of the opening angle bracket ('<'). |
7606 | /// \param TemplateArgs The template arguments. |
7607 | /// \param RAngleLoc The location of the closing angle bracket ('>'). |
7608 | TypeResult |
7609 | ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, |
7610 | const CXXScopeSpec &SS, |
7611 | SourceLocation TemplateLoc, |
7612 | TemplateTy TemplateName, |
7613 | IdentifierInfo *TemplateII, |
7614 | SourceLocation TemplateIILoc, |
7615 | SourceLocation LAngleLoc, |
7616 | ASTTemplateArgsPtr TemplateArgs, |
7617 | SourceLocation RAngleLoc); |
7618 | |
7619 | QualType CheckTypenameType(ElaboratedTypeKeyword Keyword, |
7620 | SourceLocation KeywordLoc, |
7621 | NestedNameSpecifierLoc QualifierLoc, |
7622 | const IdentifierInfo &II, |
7623 | SourceLocation IILoc, |
7624 | TypeSourceInfo **TSI, |
7625 | bool DeducedTSTContext); |
7626 | |
7627 | QualType CheckTypenameType(ElaboratedTypeKeyword Keyword, |
7628 | SourceLocation KeywordLoc, |
7629 | NestedNameSpecifierLoc QualifierLoc, |
7630 | const IdentifierInfo &II, |
7631 | SourceLocation IILoc, |
7632 | bool DeducedTSTContext = true); |
7633 | |
7634 | |
7635 | TypeSourceInfo *RebuildTypeInCurrentInstantiation(TypeSourceInfo *T, |
7636 | SourceLocation Loc, |
7637 | DeclarationName Name); |
7638 | bool RebuildNestedNameSpecifierInCurrentInstantiation(CXXScopeSpec &SS); |
7639 | |
7640 | ExprResult RebuildExprInCurrentInstantiation(Expr *E); |
7641 | bool RebuildTemplateParamsInCurrentInstantiation( |
7642 | TemplateParameterList *Params); |
7643 | |
7644 | std::string |
7645 | getTemplateArgumentBindingsText(const TemplateParameterList *Params, |
7646 | const TemplateArgumentList &Args); |
7647 | |
7648 | std::string |
7649 | getTemplateArgumentBindingsText(const TemplateParameterList *Params, |
7650 | const TemplateArgument *Args, |
7651 | unsigned NumArgs); |
7652 | |
7653 | //===--------------------------------------------------------------------===// |
7654 | // C++ Concepts |
7655 | //===--------------------------------------------------------------------===// |
7656 | Decl *ActOnConceptDefinition( |
7657 | Scope *S, MultiTemplateParamsArg TemplateParameterLists, |
7658 | IdentifierInfo *Name, SourceLocation NameLoc, Expr *ConstraintExpr); |
7659 | |
7660 | RequiresExprBodyDecl * |
7661 | ActOnStartRequiresExpr(SourceLocation RequiresKWLoc, |
7662 | ArrayRef<ParmVarDecl *> LocalParameters, |
7663 | Scope *BodyScope); |
7664 | void ActOnFinishRequiresExpr(); |
7665 | concepts::Requirement *ActOnSimpleRequirement(Expr *E); |
7666 | concepts::Requirement *ActOnTypeRequirement( |
7667 | SourceLocation TypenameKWLoc, CXXScopeSpec &SS, SourceLocation NameLoc, |
7668 | IdentifierInfo *TypeName, TemplateIdAnnotation *TemplateId); |
7669 | concepts::Requirement *ActOnCompoundRequirement(Expr *E, |
7670 | SourceLocation NoexceptLoc); |
7671 | concepts::Requirement * |
7672 | ActOnCompoundRequirement( |
7673 | Expr *E, SourceLocation NoexceptLoc, CXXScopeSpec &SS, |
7674 | TemplateIdAnnotation *TypeConstraint, unsigned Depth); |
7675 | concepts::Requirement *ActOnNestedRequirement(Expr *Constraint); |
7676 | concepts::ExprRequirement * |
7677 | BuildExprRequirement( |
7678 | Expr *E, bool IsSatisfied, SourceLocation NoexceptLoc, |
7679 | concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement); |
7680 | concepts::ExprRequirement * |
7681 | BuildExprRequirement( |
7682 | concepts::Requirement::SubstitutionDiagnostic *ExprSubstDiag, |
7683 | bool IsSatisfied, SourceLocation NoexceptLoc, |
7684 | concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement); |
7685 | concepts::TypeRequirement *BuildTypeRequirement(TypeSourceInfo *Type); |
7686 | concepts::TypeRequirement * |
7687 | BuildTypeRequirement( |
7688 | concepts::Requirement::SubstitutionDiagnostic *SubstDiag); |
7689 | concepts::NestedRequirement *BuildNestedRequirement(Expr *E); |
7690 | concepts::NestedRequirement * |
7691 | BuildNestedRequirement( |
7692 | concepts::Requirement::SubstitutionDiagnostic *SubstDiag); |
7693 | ExprResult ActOnRequiresExpr(SourceLocation RequiresKWLoc, |
7694 | RequiresExprBodyDecl *Body, |
7695 | ArrayRef<ParmVarDecl *> LocalParameters, |
7696 | ArrayRef<concepts::Requirement *> Requirements, |
7697 | SourceLocation ClosingBraceLoc); |
7698 | |
7699 | //===--------------------------------------------------------------------===// |
7700 | // C++ Variadic Templates (C++0x [temp.variadic]) |
7701 | //===--------------------------------------------------------------------===// |
7702 | |
7703 | /// Determine whether an unexpanded parameter pack might be permitted in this |
7704 | /// location. Useful for error recovery. |
7705 | bool isUnexpandedParameterPackPermitted(); |
7706 | |
7707 | /// The context in which an unexpanded parameter pack is |
7708 | /// being diagnosed. |
7709 | /// |
7710 | /// Note that the values of this enumeration line up with the first |
7711 | /// argument to the \c err_unexpanded_parameter_pack diagnostic. |
7712 | enum UnexpandedParameterPackContext { |
7713 | /// An arbitrary expression. |
7714 | UPPC_Expression = 0, |
7715 | |
7716 | /// The base type of a class type. |
7717 | UPPC_BaseType, |
7718 | |
7719 | /// The type of an arbitrary declaration. |
7720 | UPPC_DeclarationType, |
7721 | |
7722 | /// The type of a data member. |
7723 | UPPC_DataMemberType, |
7724 | |
7725 | /// The size of a bit-field. |
7726 | UPPC_BitFieldWidth, |
7727 | |
7728 | /// The expression in a static assertion. |
7729 | UPPC_StaticAssertExpression, |
7730 | |
7731 | /// The fixed underlying type of an enumeration. |
7732 | UPPC_FixedUnderlyingType, |
7733 | |
7734 | /// The enumerator value. |
7735 | UPPC_EnumeratorValue, |
7736 | |
7737 | /// A using declaration. |
7738 | UPPC_UsingDeclaration, |
7739 | |
7740 | /// A friend declaration. |
7741 | UPPC_FriendDeclaration, |
7742 | |
7743 | /// A declaration qualifier. |
7744 | UPPC_DeclarationQualifier, |
7745 | |
7746 | /// An initializer. |
7747 | UPPC_Initializer, |
7748 | |
7749 | /// A default argument. |
7750 | UPPC_DefaultArgument, |
7751 | |
7752 | /// The type of a non-type template parameter. |
7753 | UPPC_NonTypeTemplateParameterType, |
7754 | |
7755 | /// The type of an exception. |
7756 | UPPC_ExceptionType, |
7757 | |
7758 | /// Partial specialization. |
7759 | UPPC_PartialSpecialization, |
7760 | |
7761 | /// Microsoft __if_exists. |
7762 | UPPC_IfExists, |
7763 | |
7764 | /// Microsoft __if_not_exists. |
7765 | UPPC_IfNotExists, |
7766 | |
7767 | /// Lambda expression. |
7768 | UPPC_Lambda, |
7769 | |
7770 | /// Block expression. |
7771 | UPPC_Block, |
7772 | |
7773 | /// A type constraint. |
7774 | UPPC_TypeConstraint, |
7775 | |
7776 | // A requirement in a requires-expression. |
7777 | UPPC_Requirement, |
7778 | }; |
7779 | |
7780 | /// Diagnose unexpanded parameter packs. |
7781 | /// |
7782 | /// \param Loc The location at which we should emit the diagnostic. |
7783 | /// |
7784 | /// \param UPPC The context in which we are diagnosing unexpanded |
7785 | /// parameter packs. |
7786 | /// |
7787 | /// \param Unexpanded the set of unexpanded parameter packs. |
7788 | /// |
7789 | /// \returns true if an error occurred, false otherwise. |
7790 | bool DiagnoseUnexpandedParameterPacks(SourceLocation Loc, |
7791 | UnexpandedParameterPackContext UPPC, |
7792 | ArrayRef<UnexpandedParameterPack> Unexpanded); |
7793 | |
7794 | /// If the given type contains an unexpanded parameter pack, |
7795 | /// diagnose the error. |
7796 | /// |
7797 | /// \param Loc The source location where a diagnostc should be emitted. |
7798 | /// |
7799 | /// \param T The type that is being checked for unexpanded parameter |
7800 | /// packs. |
7801 | /// |
7802 | /// \returns true if an error occurred, false otherwise. |
7803 | bool DiagnoseUnexpandedParameterPack(SourceLocation Loc, TypeSourceInfo *T, |
7804 | UnexpandedParameterPackContext UPPC); |
7805 | |
7806 | /// If the given expression contains an unexpanded parameter |
7807 | /// pack, diagnose the error. |
7808 | /// |
7809 | /// \param E The expression that is being checked for unexpanded |
7810 | /// parameter packs. |
7811 | /// |
7812 | /// \returns true if an error occurred, false otherwise. |
7813 | bool DiagnoseUnexpandedParameterPack(Expr *E, |
7814 | UnexpandedParameterPackContext UPPC = UPPC_Expression); |
7815 | |
7816 | /// If the given requirees-expression contains an unexpanded reference to one |
7817 | /// of its own parameter packs, diagnose the error. |
7818 | /// |
7819 | /// \param RE The requiress-expression that is being checked for unexpanded |
7820 | /// parameter packs. |
7821 | /// |
7822 | /// \returns true if an error occurred, false otherwise. |
7823 | bool DiagnoseUnexpandedParameterPackInRequiresExpr(RequiresExpr *RE); |
7824 | |
7825 | /// If the given nested-name-specifier contains an unexpanded |
7826 | /// parameter pack, diagnose the error. |
7827 | /// |
7828 | /// \param SS The nested-name-specifier that is being checked for |
7829 | /// unexpanded parameter packs. |
7830 | /// |
7831 | /// \returns true if an error occurred, false otherwise. |
7832 | bool DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS, |
7833 | UnexpandedParameterPackContext UPPC); |
7834 | |
7835 | /// If the given name contains an unexpanded parameter pack, |
7836 | /// diagnose the error. |
7837 | /// |
7838 | /// \param NameInfo The name (with source location information) that |
7839 | /// is being checked for unexpanded parameter packs. |
7840 | /// |
7841 | /// \returns true if an error occurred, false otherwise. |
7842 | bool DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo, |
7843 | UnexpandedParameterPackContext UPPC); |
7844 | |
7845 | /// If the given template name contains an unexpanded parameter pack, |
7846 | /// diagnose the error. |
7847 | /// |
7848 | /// \param Loc The location of the template name. |
7849 | /// |
7850 | /// \param Template The template name that is being checked for unexpanded |
7851 | /// parameter packs. |
7852 | /// |
7853 | /// \returns true if an error occurred, false otherwise. |
7854 | bool DiagnoseUnexpandedParameterPack(SourceLocation Loc, |
7855 | TemplateName Template, |
7856 | UnexpandedParameterPackContext UPPC); |
7857 | |
7858 | /// If the given template argument contains an unexpanded parameter |
7859 | /// pack, diagnose the error. |
7860 | /// |
7861 | /// \param Arg The template argument that is being checked for unexpanded |
7862 | /// parameter packs. |
7863 | /// |
7864 | /// \returns true if an error occurred, false otherwise. |
7865 | bool DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg, |
7866 | UnexpandedParameterPackContext UPPC); |
7867 | |
7868 | /// Collect the set of unexpanded parameter packs within the given |
7869 | /// template argument. |
7870 | /// |
7871 | /// \param Arg The template argument that will be traversed to find |
7872 | /// unexpanded parameter packs. |
7873 | void collectUnexpandedParameterPacks(TemplateArgument Arg, |
7874 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); |
7875 | |
7876 | /// Collect the set of unexpanded parameter packs within the given |
7877 | /// template argument. |
7878 | /// |
7879 | /// \param Arg The template argument that will be traversed to find |
7880 | /// unexpanded parameter packs. |
7881 | void collectUnexpandedParameterPacks(TemplateArgumentLoc Arg, |
7882 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); |
7883 | |
7884 | /// Collect the set of unexpanded parameter packs within the given |
7885 | /// type. |
7886 | /// |
7887 | /// \param T The type that will be traversed to find |
7888 | /// unexpanded parameter packs. |
7889 | void collectUnexpandedParameterPacks(QualType T, |
7890 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); |
7891 | |
7892 | /// Collect the set of unexpanded parameter packs within the given |
7893 | /// type. |
7894 | /// |
7895 | /// \param TL The type that will be traversed to find |
7896 | /// unexpanded parameter packs. |
7897 | void collectUnexpandedParameterPacks(TypeLoc TL, |
7898 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); |
7899 | |
7900 | /// Collect the set of unexpanded parameter packs within the given |
7901 | /// nested-name-specifier. |
7902 | /// |
7903 | /// \param NNS The nested-name-specifier that will be traversed to find |
7904 | /// unexpanded parameter packs. |
7905 | void collectUnexpandedParameterPacks(NestedNameSpecifierLoc NNS, |
7906 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); |
7907 | |
7908 | /// Collect the set of unexpanded parameter packs within the given |
7909 | /// name. |
7910 | /// |
7911 | /// \param NameInfo The name that will be traversed to find |
7912 | /// unexpanded parameter packs. |
7913 | void collectUnexpandedParameterPacks(const DeclarationNameInfo &NameInfo, |
7914 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); |
7915 | |
7916 | /// Invoked when parsing a template argument followed by an |
7917 | /// ellipsis, which creates a pack expansion. |
7918 | /// |
7919 | /// \param Arg The template argument preceding the ellipsis, which |
7920 | /// may already be invalid. |
7921 | /// |
7922 | /// \param EllipsisLoc The location of the ellipsis. |
7923 | ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg, |
7924 | SourceLocation EllipsisLoc); |
7925 | |
7926 | /// Invoked when parsing a type followed by an ellipsis, which |
7927 | /// creates a pack expansion. |
7928 | /// |
7929 | /// \param Type The type preceding the ellipsis, which will become |
7930 | /// the pattern of the pack expansion. |
7931 | /// |
7932 | /// \param EllipsisLoc The location of the ellipsis. |
7933 | TypeResult ActOnPackExpansion(ParsedType Type, SourceLocation EllipsisLoc); |
7934 | |
7935 | /// Construct a pack expansion type from the pattern of the pack |
7936 | /// expansion. |
7937 | TypeSourceInfo *CheckPackExpansion(TypeSourceInfo *Pattern, |
7938 | SourceLocation EllipsisLoc, |
7939 | Optional<unsigned> NumExpansions); |
7940 | |
7941 | /// Construct a pack expansion type from the pattern of the pack |
7942 | /// expansion. |
7943 | QualType CheckPackExpansion(QualType Pattern, |
7944 | SourceRange PatternRange, |
7945 | SourceLocation EllipsisLoc, |
7946 | Optional<unsigned> NumExpansions); |
7947 | |
7948 | /// Invoked when parsing an expression followed by an ellipsis, which |
7949 | /// creates a pack expansion. |
7950 | /// |
7951 | /// \param Pattern The expression preceding the ellipsis, which will become |
7952 | /// the pattern of the pack expansion. |
7953 | /// |
7954 | /// \param EllipsisLoc The location of the ellipsis. |
7955 | ExprResult ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc); |
7956 | |
7957 | /// Invoked when parsing an expression followed by an ellipsis, which |
7958 | /// creates a pack expansion. |
7959 | /// |
7960 | /// \param Pattern The expression preceding the ellipsis, which will become |
7961 | /// the pattern of the pack expansion. |
7962 | /// |
7963 | /// \param EllipsisLoc The location of the ellipsis. |
7964 | ExprResult CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc, |
7965 | Optional<unsigned> NumExpansions); |
7966 | |
7967 | /// Determine whether we could expand a pack expansion with the |
7968 | /// given set of parameter packs into separate arguments by repeatedly |
7969 | /// transforming the pattern. |
7970 | /// |
7971 | /// \param EllipsisLoc The location of the ellipsis that identifies the |
7972 | /// pack expansion. |
7973 | /// |
7974 | /// \param PatternRange The source range that covers the entire pattern of |
7975 | /// the pack expansion. |
7976 | /// |
7977 | /// \param Unexpanded The set of unexpanded parameter packs within the |
7978 | /// pattern. |
7979 | /// |
7980 | /// \param ShouldExpand Will be set to \c true if the transformer should |
7981 | /// expand the corresponding pack expansions into separate arguments. When |
7982 | /// set, \c NumExpansions must also be set. |
7983 | /// |
7984 | /// \param RetainExpansion Whether the caller should add an unexpanded |
7985 | /// pack expansion after all of the expanded arguments. This is used |
7986 | /// when extending explicitly-specified template argument packs per |
7987 | /// C++0x [temp.arg.explicit]p9. |
7988 | /// |
7989 | /// \param NumExpansions The number of separate arguments that will be in |
7990 | /// the expanded form of the corresponding pack expansion. This is both an |
7991 | /// input and an output parameter, which can be set by the caller if the |
7992 | /// number of expansions is known a priori (e.g., due to a prior substitution) |
7993 | /// and will be set by the callee when the number of expansions is known. |
7994 | /// The callee must set this value when \c ShouldExpand is \c true; it may |
7995 | /// set this value in other cases. |
7996 | /// |
7997 | /// \returns true if an error occurred (e.g., because the parameter packs |
7998 | /// are to be instantiated with arguments of different lengths), false |
7999 | /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions) |
8000 | /// must be set. |
8001 | bool CheckParameterPacksForExpansion(SourceLocation EllipsisLoc, |
8002 | SourceRange PatternRange, |
8003 | ArrayRef<UnexpandedParameterPack> Unexpanded, |
8004 | const MultiLevelTemplateArgumentList &TemplateArgs, |
8005 | bool &ShouldExpand, |
8006 | bool &RetainExpansion, |
8007 | Optional<unsigned> &NumExpansions); |
8008 | |
8009 | /// Determine the number of arguments in the given pack expansion |
8010 | /// type. |
8011 | /// |
8012 | /// This routine assumes that the number of arguments in the expansion is |
8013 | /// consistent across all of the unexpanded parameter packs in its pattern. |
8014 | /// |
8015 | /// Returns an empty Optional if the type can't be expanded. |
8016 | Optional<unsigned> getNumArgumentsInExpansion(QualType T, |
8017 | const MultiLevelTemplateArgumentList &TemplateArgs); |
8018 | |
8019 | /// Determine whether the given declarator contains any unexpanded |
8020 | /// parameter packs. |
8021 | /// |
8022 | /// This routine is used by the parser to disambiguate function declarators |
8023 | /// with an ellipsis prior to the ')', e.g., |
8024 | /// |
8025 | /// \code |
8026 | /// void f(T...); |
8027 | /// \endcode |
8028 | /// |
8029 | /// To determine whether we have an (unnamed) function parameter pack or |
8030 | /// a variadic function. |
8031 | /// |
8032 | /// \returns true if the declarator contains any unexpanded parameter packs, |
8033 | /// false otherwise. |
8034 | bool containsUnexpandedParameterPacks(Declarator &D); |
8035 | |
8036 | /// Returns the pattern of the pack expansion for a template argument. |
8037 | /// |
8038 | /// \param OrigLoc The template argument to expand. |
8039 | /// |
8040 | /// \param Ellipsis Will be set to the location of the ellipsis. |
8041 | /// |
8042 | /// \param NumExpansions Will be set to the number of expansions that will |
8043 | /// be generated from this pack expansion, if known a priori. |
8044 | TemplateArgumentLoc getTemplateArgumentPackExpansionPattern( |
8045 | TemplateArgumentLoc OrigLoc, |
8046 | SourceLocation &Ellipsis, |
8047 | Optional<unsigned> &NumExpansions) const; |
8048 | |
8049 | /// Given a template argument that contains an unexpanded parameter pack, but |
8050 | /// which has already been substituted, attempt to determine the number of |
8051 | /// elements that will be produced once this argument is fully-expanded. |
8052 | /// |
8053 | /// This is intended for use when transforming 'sizeof...(Arg)' in order to |
8054 | /// avoid actually expanding the pack where possible. |
8055 | Optional<unsigned> getFullyPackExpandedSize(TemplateArgument Arg); |
8056 | |
8057 | //===--------------------------------------------------------------------===// |
8058 | // C++ Template Argument Deduction (C++ [temp.deduct]) |
8059 | //===--------------------------------------------------------------------===// |
8060 | |
8061 | /// Adjust the type \p ArgFunctionType to match the calling convention, |
8062 | /// noreturn, and optionally the exception specification of \p FunctionType. |
8063 | /// Deduction often wants to ignore these properties when matching function |
8064 | /// types. |
8065 | QualType adjustCCAndNoReturn(QualType ArgFunctionType, QualType FunctionType, |
8066 | bool AdjustExceptionSpec = false); |
8067 | |
8068 | /// Describes the result of template argument deduction. |
8069 | /// |
8070 | /// The TemplateDeductionResult enumeration describes the result of |
8071 | /// template argument deduction, as returned from |
8072 | /// DeduceTemplateArguments(). The separate TemplateDeductionInfo |
8073 | /// structure provides additional information about the results of |
8074 | /// template argument deduction, e.g., the deduced template argument |
8075 | /// list (if successful) or the specific template parameters or |
8076 | /// deduced arguments that were involved in the failure. |
8077 | enum TemplateDeductionResult { |
8078 | /// Template argument deduction was successful. |
8079 | TDK_Success = 0, |
8080 | /// The declaration was invalid; do nothing. |
8081 | TDK_Invalid, |
8082 | /// Template argument deduction exceeded the maximum template |
8083 | /// instantiation depth (which has already been diagnosed). |
8084 | TDK_InstantiationDepth, |
8085 | /// Template argument deduction did not deduce a value |
8086 | /// for every template parameter. |
8087 | TDK_Incomplete, |
8088 | /// Template argument deduction did not deduce a value for every |
8089 | /// expansion of an expanded template parameter pack. |
8090 | TDK_IncompletePack, |
8091 | /// Template argument deduction produced inconsistent |
8092 | /// deduced values for the given template parameter. |
8093 | TDK_Inconsistent, |
8094 | /// Template argument deduction failed due to inconsistent |
8095 | /// cv-qualifiers on a template parameter type that would |
8096 | /// otherwise be deduced, e.g., we tried to deduce T in "const T" |
8097 | /// but were given a non-const "X". |
8098 | TDK_Underqualified, |
8099 | /// Substitution of the deduced template argument values |
8100 | /// resulted in an error. |
8101 | TDK_SubstitutionFailure, |
8102 | /// After substituting deduced template arguments, a dependent |
8103 | /// parameter type did not match the corresponding argument. |
8104 | TDK_DeducedMismatch, |
8105 | /// After substituting deduced template arguments, an element of |
8106 | /// a dependent parameter type did not match the corresponding element |
8107 | /// of the corresponding argument (when deducing from an initializer list). |
8108 | TDK_DeducedMismatchNested, |
8109 | /// A non-depnedent component of the parameter did not match the |
8110 | /// corresponding component of the argument. |
8111 | TDK_NonDeducedMismatch, |
8112 | /// When performing template argument deduction for a function |
8113 | /// template, there were too many call arguments. |
8114 | TDK_TooManyArguments, |
8115 | /// When performing template argument deduction for a function |
8116 | /// template, there were too few call arguments. |
8117 | TDK_TooFewArguments, |
8118 | /// The explicitly-specified template arguments were not valid |
8119 | /// template arguments for the given template. |
8120 | TDK_InvalidExplicitArguments, |
8121 | /// Checking non-dependent argument conversions failed. |
8122 | TDK_NonDependentConversionFailure, |
8123 | /// The deduced arguments did not satisfy the constraints associated |
8124 | /// with the template. |
8125 | TDK_ConstraintsNotSatisfied, |
8126 | /// Deduction failed; that's all we know. |
8127 | TDK_MiscellaneousDeductionFailure, |
8128 | /// CUDA Target attributes do not match. |
8129 | TDK_CUDATargetMismatch |
8130 | }; |
8131 | |
8132 | TemplateDeductionResult |
8133 | DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, |
8134 | const TemplateArgumentList &TemplateArgs, |
8135 | sema::TemplateDeductionInfo &Info); |
8136 | |
8137 | TemplateDeductionResult |
8138 | DeduceTemplateArguments(VarTemplatePartialSpecializationDecl *Partial, |
8139 | const TemplateArgumentList &TemplateArgs, |
8140 | sema::TemplateDeductionInfo &Info); |
8141 | |
8142 | TemplateDeductionResult SubstituteExplicitTemplateArguments( |
8143 | FunctionTemplateDecl *FunctionTemplate, |
8144 | TemplateArgumentListInfo &ExplicitTemplateArgs, |
8145 | SmallVectorImpl<DeducedTemplateArgument> &Deduced, |
8146 | SmallVectorImpl<QualType> &ParamTypes, QualType *FunctionType, |
8147 | sema::TemplateDeductionInfo &Info); |
8148 | |
8149 | /// brief A function argument from which we performed template argument |
8150 | // deduction for a call. |
8151 | struct OriginalCallArg { |
8152 | OriginalCallArg(QualType OriginalParamType, bool DecomposedParam, |
8153 | unsigned ArgIdx, QualType OriginalArgType) |
8154 | : OriginalParamType(OriginalParamType), |
8155 | DecomposedParam(DecomposedParam), ArgIdx(ArgIdx), |
8156 | OriginalArgType(OriginalArgType) {} |
8157 | |
8158 | QualType OriginalParamType; |
8159 | bool DecomposedParam; |
8160 | unsigned ArgIdx; |
8161 | QualType OriginalArgType; |
8162 | }; |
8163 | |
8164 | TemplateDeductionResult FinishTemplateArgumentDeduction( |
8165 | FunctionTemplateDecl *FunctionTemplate, |
8166 | SmallVectorImpl<DeducedTemplateArgument> &Deduced, |
8167 | unsigned NumExplicitlySpecified, FunctionDecl *&Specialization, |
8168 | sema::TemplateDeductionInfo &Info, |
8169 | SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs = nullptr, |
8170 | bool PartialOverloading = false, |
8171 | llvm::function_ref<bool()> CheckNonDependent = []{ return false; }); |
8172 | |
8173 | TemplateDeductionResult DeduceTemplateArguments( |
8174 | FunctionTemplateDecl *FunctionTemplate, |
8175 | TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args, |
8176 | FunctionDecl *&Specialization, sema::TemplateDeductionInfo &Info, |
8177 | bool PartialOverloading, |
8178 | llvm::function_ref<bool(ArrayRef<QualType>)> CheckNonDependent); |
8179 | |
8180 | TemplateDeductionResult |
8181 | DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, |
8182 | TemplateArgumentListInfo *ExplicitTemplateArgs, |
8183 | QualType ArgFunctionType, |
8184 | FunctionDecl *&Specialization, |
8185 | sema::TemplateDeductionInfo &Info, |
8186 | bool IsAddressOfFunction = false); |
8187 | |
8188 | TemplateDeductionResult |
8189 | DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, |
8190 | QualType ToType, |
8191 | CXXConversionDecl *&Specialization, |
8192 | sema::TemplateDeductionInfo &Info); |
8193 | |
8194 | TemplateDeductionResult |
8195 | DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, |
8196 | TemplateArgumentListInfo *ExplicitTemplateArgs, |
8197 | FunctionDecl *&Specialization, |
8198 | sema::TemplateDeductionInfo &Info, |
8199 | bool IsAddressOfFunction = false); |
8200 | |
8201 | /// Substitute Replacement for \p auto in \p TypeWithAuto |
8202 | QualType SubstAutoType(QualType TypeWithAuto, QualType Replacement); |
8203 | /// Substitute Replacement for auto in TypeWithAuto |
8204 | TypeSourceInfo* SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto, |
8205 | QualType Replacement); |
8206 | /// Completely replace the \c auto in \p TypeWithAuto by |
8207 | /// \p Replacement. This does not retain any \c auto type sugar. |
8208 | QualType ReplaceAutoType(QualType TypeWithAuto, QualType Replacement); |
8209 | TypeSourceInfo *ReplaceAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto, |
8210 | QualType Replacement); |
8211 | |
8212 | /// Result type of DeduceAutoType. |
8213 | enum DeduceAutoResult { |
8214 | DAR_Succeeded, |
8215 | DAR_Failed, |
8216 | DAR_FailedAlreadyDiagnosed |
8217 | }; |
8218 | |
8219 | DeduceAutoResult |
8220 | DeduceAutoType(TypeSourceInfo *AutoType, Expr *&Initializer, QualType &Result, |
8221 | Optional<unsigned> DependentDeductionDepth = None, |
8222 | bool IgnoreConstraints = false); |
8223 | DeduceAutoResult |
8224 | DeduceAutoType(TypeLoc AutoTypeLoc, Expr *&Initializer, QualType &Result, |
8225 | Optional<unsigned> DependentDeductionDepth = None, |
8226 | bool IgnoreConstraints = false); |
8227 | void DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init); |
8228 | bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc, |
8229 | bool Diagnose = true); |
8230 | |
8231 | /// Declare implicit deduction guides for a class template if we've |
8232 | /// not already done so. |
8233 | void DeclareImplicitDeductionGuides(TemplateDecl *Template, |
8234 | SourceLocation Loc); |
8235 | |
8236 | QualType DeduceTemplateSpecializationFromInitializer( |
8237 | TypeSourceInfo *TInfo, const InitializedEntity &Entity, |
8238 | const InitializationKind &Kind, MultiExprArg Init); |
8239 | |
8240 | QualType deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name, |
8241 | QualType Type, TypeSourceInfo *TSI, |
8242 | SourceRange Range, bool DirectInit, |
8243 | Expr *Init); |
8244 | |
8245 | TypeLoc getReturnTypeLoc(FunctionDecl *FD) const; |
8246 | |
8247 | bool DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD, |
8248 | SourceLocation ReturnLoc, |
8249 | Expr *&RetExpr, AutoType *AT); |
8250 | |
8251 | FunctionTemplateDecl *getMoreSpecializedTemplate( |
8252 | FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc, |
8253 | TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1, |
8254 | unsigned NumCallArguments2, bool Reversed = false); |
8255 | UnresolvedSetIterator |
8256 | getMostSpecialized(UnresolvedSetIterator SBegin, UnresolvedSetIterator SEnd, |
8257 | TemplateSpecCandidateSet &FailedCandidates, |
8258 | SourceLocation Loc, |
8259 | const PartialDiagnostic &NoneDiag, |
8260 | const PartialDiagnostic &AmbigDiag, |
8261 | const PartialDiagnostic &CandidateDiag, |
8262 | bool Complain = true, QualType TargetType = QualType()); |
8263 | |
8264 | ClassTemplatePartialSpecializationDecl * |
8265 | getMoreSpecializedPartialSpecialization( |
8266 | ClassTemplatePartialSpecializationDecl *PS1, |
8267 | ClassTemplatePartialSpecializationDecl *PS2, |
8268 | SourceLocation Loc); |
8269 | |
8270 | bool isMoreSpecializedThanPrimary(ClassTemplatePartialSpecializationDecl *T, |
8271 | sema::TemplateDeductionInfo &Info); |
8272 | |
8273 | VarTemplatePartialSpecializationDecl *getMoreSpecializedPartialSpecialization( |
8274 | VarTemplatePartialSpecializationDecl *PS1, |
8275 | VarTemplatePartialSpecializationDecl *PS2, SourceLocation Loc); |
8276 | |
8277 | bool isMoreSpecializedThanPrimary(VarTemplatePartialSpecializationDecl *T, |
8278 | sema::TemplateDeductionInfo &Info); |
8279 | |
8280 | bool isTemplateTemplateParameterAtLeastAsSpecializedAs( |
8281 | TemplateParameterList *PParam, TemplateDecl *AArg, SourceLocation Loc); |
8282 | |
8283 | void MarkUsedTemplateParameters(const Expr *E, bool OnlyDeduced, |
8284 | unsigned Depth, llvm::SmallBitVector &Used); |
8285 | |
8286 | void MarkUsedTemplateParameters(const TemplateArgumentList &TemplateArgs, |
8287 | bool OnlyDeduced, |
8288 | unsigned Depth, |
8289 | llvm::SmallBitVector &Used); |
8290 | void MarkDeducedTemplateParameters( |
8291 | const FunctionTemplateDecl *FunctionTemplate, |
8292 | llvm::SmallBitVector &Deduced) { |
8293 | return MarkDeducedTemplateParameters(Context, FunctionTemplate, Deduced); |
8294 | } |
8295 | static void MarkDeducedTemplateParameters(ASTContext &Ctx, |
8296 | const FunctionTemplateDecl *FunctionTemplate, |
8297 | llvm::SmallBitVector &Deduced); |
8298 | |
8299 | //===--------------------------------------------------------------------===// |
8300 | // C++ Template Instantiation |
8301 | // |
8302 | |
8303 | MultiLevelTemplateArgumentList |
8304 | getTemplateInstantiationArgs(NamedDecl *D, |
8305 | const TemplateArgumentList *Innermost = nullptr, |
8306 | bool RelativeToPrimary = false, |
8307 | const FunctionDecl *Pattern = nullptr); |
8308 | |
8309 | /// A context in which code is being synthesized (where a source location |
8310 | /// alone is not sufficient to identify the context). This covers template |
8311 | /// instantiation and various forms of implicitly-generated functions. |
8312 | struct CodeSynthesisContext { |
8313 | /// The kind of template instantiation we are performing |
8314 | enum SynthesisKind { |
8315 | /// We are instantiating a template declaration. The entity is |
8316 | /// the declaration we're instantiating (e.g., a CXXRecordDecl). |
8317 | TemplateInstantiation, |
8318 | |
8319 | /// We are instantiating a default argument for a template |
8320 | /// parameter. The Entity is the template parameter whose argument is |
8321 | /// being instantiated, the Template is the template, and the |
8322 | /// TemplateArgs/NumTemplateArguments provide the template arguments as |
8323 | /// specified. |
8324 | DefaultTemplateArgumentInstantiation, |
8325 | |
8326 | /// We are instantiating a default argument for a function. |
8327 | /// The Entity is the ParmVarDecl, and TemplateArgs/NumTemplateArgs |
8328 | /// provides the template arguments as specified. |
8329 | DefaultFunctionArgumentInstantiation, |
8330 | |
8331 | /// We are substituting explicit template arguments provided for |
8332 | /// a function template. The entity is a FunctionTemplateDecl. |
8333 | ExplicitTemplateArgumentSubstitution, |
8334 | |
8335 | /// We are substituting template argument determined as part of |
8336 | /// template argument deduction for either a class template |
8337 | /// partial specialization or a function template. The |
8338 | /// Entity is either a {Class|Var}TemplatePartialSpecializationDecl or |
8339 | /// a TemplateDecl. |
8340 | DeducedTemplateArgumentSubstitution, |
8341 | |
8342 | /// We are substituting prior template arguments into a new |
8343 | /// template parameter. The template parameter itself is either a |
8344 | /// NonTypeTemplateParmDecl or a TemplateTemplateParmDecl. |
8345 | PriorTemplateArgumentSubstitution, |
8346 | |
8347 | /// We are checking the validity of a default template argument that |
8348 | /// has been used when naming a template-id. |
8349 | DefaultTemplateArgumentChecking, |
8350 | |
8351 | /// We are computing the exception specification for a defaulted special |
8352 | /// member function. |
8353 | ExceptionSpecEvaluation, |
8354 | |
8355 | /// We are instantiating the exception specification for a function |
8356 | /// template which was deferred until it was needed. |
8357 | ExceptionSpecInstantiation, |
8358 | |
8359 | /// We are instantiating a requirement of a requires expression. |
8360 | RequirementInstantiation, |
8361 | |
8362 | /// We are checking the satisfaction of a nested requirement of a requires |
8363 | /// expression. |
8364 | NestedRequirementConstraintsCheck, |
8365 | |
8366 | /// We are declaring an implicit special member function. |
8367 | DeclaringSpecialMember, |
8368 | |
8369 | /// We are declaring an implicit 'operator==' for a defaulted |
8370 | /// 'operator<=>'. |
8371 | DeclaringImplicitEqualityComparison, |
8372 | |
8373 | /// We are defining a synthesized function (such as a defaulted special |
8374 | /// member). |
8375 | DefiningSynthesizedFunction, |
8376 | |
8377 | // We are checking the constraints associated with a constrained entity or |
8378 | // the constraint expression of a concept. This includes the checks that |
8379 | // atomic constraints have the type 'bool' and that they can be constant |
8380 | // evaluated. |
8381 | ConstraintsCheck, |
8382 | |
8383 | // We are substituting template arguments into a constraint expression. |
8384 | ConstraintSubstitution, |
8385 | |
8386 | // We are normalizing a constraint expression. |
8387 | ConstraintNormalization, |
8388 | |
8389 | // We are substituting into the parameter mapping of an atomic constraint |
8390 | // during normalization. |
8391 | ParameterMappingSubstitution, |
8392 | |
8393 | /// We are rewriting a comparison operator in terms of an operator<=>. |
8394 | RewritingOperatorAsSpaceship, |
8395 | |
8396 | /// We are initializing a structured binding. |
8397 | InitializingStructuredBinding, |
8398 | |
8399 | /// We are marking a class as __dllexport. |
8400 | MarkingClassDllexported, |
8401 | |
8402 | /// Added for Template instantiation observation. |
8403 | /// Memoization means we are _not_ instantiating a template because |
8404 | /// it is already instantiated (but we entered a context where we |
8405 | /// would have had to if it was not already instantiated). |
8406 | Memoization |
8407 | } Kind; |
8408 | |
8409 | /// Was the enclosing context a non-instantiation SFINAE context? |
8410 | bool SavedInNonInstantiationSFINAEContext; |
8411 | |
8412 | /// The point of instantiation or synthesis within the source code. |
8413 | SourceLocation PointOfInstantiation; |
8414 | |
8415 | /// The entity that is being synthesized. |
8416 | Decl *Entity; |
8417 | |
8418 | /// The template (or partial specialization) in which we are |
8419 | /// performing the instantiation, for substitutions of prior template |
8420 | /// arguments. |
8421 | NamedDecl *Template; |
8422 | |
8423 | /// The list of template arguments we are substituting, if they |
8424 | /// are not part of the entity. |
8425 | const TemplateArgument *TemplateArgs; |
8426 | |
8427 | // FIXME: Wrap this union around more members, or perhaps store the |
8428 | // kind-specific members in the RAII object owning the context. |
8429 | union { |
8430 | /// The number of template arguments in TemplateArgs. |
8431 | unsigned NumTemplateArgs; |
8432 | |
8433 | /// The special member being declared or defined. |
8434 | CXXSpecialMember SpecialMember; |
8435 | }; |
8436 | |
8437 | ArrayRef<TemplateArgument> template_arguments() const { |
8438 | assert(Kind != DeclaringSpecialMember)((Kind != DeclaringSpecialMember) ? static_cast<void> ( 0) : __assert_fail ("Kind != DeclaringSpecialMember", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 8438, __PRETTY_FUNCTION__)); |
8439 | return {TemplateArgs, NumTemplateArgs}; |
8440 | } |
8441 | |
8442 | /// The template deduction info object associated with the |
8443 | /// substitution or checking of explicit or deduced template arguments. |
8444 | sema::TemplateDeductionInfo *DeductionInfo; |
8445 | |
8446 | /// The source range that covers the construct that cause |
8447 | /// the instantiation, e.g., the template-id that causes a class |
8448 | /// template instantiation. |
8449 | SourceRange InstantiationRange; |
8450 | |
8451 | CodeSynthesisContext() |
8452 | : Kind(TemplateInstantiation), |
8453 | SavedInNonInstantiationSFINAEContext(false), Entity(nullptr), |
8454 | Template(nullptr), TemplateArgs(nullptr), NumTemplateArgs(0), |
8455 | DeductionInfo(nullptr) {} |
8456 | |
8457 | /// Determines whether this template is an actual instantiation |
8458 | /// that should be counted toward the maximum instantiation depth. |
8459 | bool isInstantiationRecord() const; |
8460 | }; |
8461 | |
8462 | /// List of active code synthesis contexts. |
8463 | /// |
8464 | /// This vector is treated as a stack. As synthesis of one entity requires |
8465 | /// synthesis of another, additional contexts are pushed onto the stack. |
8466 | SmallVector<CodeSynthesisContext, 16> CodeSynthesisContexts; |
8467 | |
8468 | /// Specializations whose definitions are currently being instantiated. |
8469 | llvm::DenseSet<std::pair<Decl *, unsigned>> InstantiatingSpecializations; |
8470 | |
8471 | /// Non-dependent types used in templates that have already been instantiated |
8472 | /// by some template instantiation. |
8473 | llvm::DenseSet<QualType> InstantiatedNonDependentTypes; |
8474 | |
8475 | /// Extra modules inspected when performing a lookup during a template |
8476 | /// instantiation. Computed lazily. |
8477 | SmallVector<Module*, 16> CodeSynthesisContextLookupModules; |
8478 | |
8479 | /// Cache of additional modules that should be used for name lookup |
8480 | /// within the current template instantiation. Computed lazily; use |
8481 | /// getLookupModules() to get a complete set. |
8482 | llvm::DenseSet<Module*> LookupModulesCache; |
8483 | |
8484 | /// Get the set of additional modules that should be checked during |
8485 | /// name lookup. A module and its imports become visible when instanting a |
8486 | /// template defined within it. |
8487 | llvm::DenseSet<Module*> &getLookupModules(); |
8488 | |
8489 | /// Map from the most recent declaration of a namespace to the most |
8490 | /// recent visible declaration of that namespace. |
8491 | llvm::DenseMap<NamedDecl*, NamedDecl*> VisibleNamespaceCache; |
8492 | |
8493 | /// Whether we are in a SFINAE context that is not associated with |
8494 | /// template instantiation. |
8495 | /// |
8496 | /// This is used when setting up a SFINAE trap (\c see SFINAETrap) outside |
8497 | /// of a template instantiation or template argument deduction. |
8498 | bool InNonInstantiationSFINAEContext; |
8499 | |
8500 | /// The number of \p CodeSynthesisContexts that are not template |
8501 | /// instantiations and, therefore, should not be counted as part of the |
8502 | /// instantiation depth. |
8503 | /// |
8504 | /// When the instantiation depth reaches the user-configurable limit |
8505 | /// \p LangOptions::InstantiationDepth we will abort instantiation. |
8506 | // FIXME: Should we have a similar limit for other forms of synthesis? |
8507 | unsigned NonInstantiationEntries; |
8508 | |
8509 | /// The depth of the context stack at the point when the most recent |
8510 | /// error or warning was produced. |
8511 | /// |
8512 | /// This value is used to suppress printing of redundant context stacks |
8513 | /// when there are multiple errors or warnings in the same instantiation. |
8514 | // FIXME: Does this belong in Sema? It's tough to implement it anywhere else. |
8515 | unsigned LastEmittedCodeSynthesisContextDepth = 0; |
8516 | |
8517 | /// The template instantiation callbacks to trace or track |
8518 | /// instantiations (objects can be chained). |
8519 | /// |
8520 | /// This callbacks is used to print, trace or track template |
8521 | /// instantiations as they are being constructed. |
8522 | std::vector<std::unique_ptr<TemplateInstantiationCallback>> |
8523 | TemplateInstCallbacks; |
8524 | |
8525 | /// The current index into pack expansion arguments that will be |
8526 | /// used for substitution of parameter packs. |
8527 | /// |
8528 | /// The pack expansion index will be -1 to indicate that parameter packs |
8529 | /// should be instantiated as themselves. Otherwise, the index specifies |
8530 | /// which argument within the parameter pack will be used for substitution. |
8531 | int ArgumentPackSubstitutionIndex; |
8532 | |
8533 | /// RAII object used to change the argument pack substitution index |
8534 | /// within a \c Sema object. |
8535 | /// |
8536 | /// See \c ArgumentPackSubstitutionIndex for more information. |
8537 | class ArgumentPackSubstitutionIndexRAII { |
8538 | Sema &Self; |
8539 | int OldSubstitutionIndex; |
8540 | |
8541 | public: |
8542 | ArgumentPackSubstitutionIndexRAII(Sema &Self, int NewSubstitutionIndex) |
8543 | : Self(Self), OldSubstitutionIndex(Self.ArgumentPackSubstitutionIndex) { |
8544 | Self.ArgumentPackSubstitutionIndex = NewSubstitutionIndex; |
8545 | } |
8546 | |
8547 | ~ArgumentPackSubstitutionIndexRAII() { |
8548 | Self.ArgumentPackSubstitutionIndex = OldSubstitutionIndex; |
8549 | } |
8550 | }; |
8551 | |
8552 | friend class ArgumentPackSubstitutionRAII; |
8553 | |
8554 | /// For each declaration that involved template argument deduction, the |
8555 | /// set of diagnostics that were suppressed during that template argument |
8556 | /// deduction. |
8557 | /// |
8558 | /// FIXME: Serialize this structure to the AST file. |
8559 | typedef llvm::DenseMap<Decl *, SmallVector<PartialDiagnosticAt, 1> > |
8560 | SuppressedDiagnosticsMap; |
8561 | SuppressedDiagnosticsMap SuppressedDiagnostics; |
8562 | |
8563 | /// A stack object to be created when performing template |
8564 | /// instantiation. |
8565 | /// |
8566 | /// Construction of an object of type \c InstantiatingTemplate |
8567 | /// pushes the current instantiation onto the stack of active |
8568 | /// instantiations. If the size of this stack exceeds the maximum |
8569 | /// number of recursive template instantiations, construction |
8570 | /// produces an error and evaluates true. |
8571 | /// |
8572 | /// Destruction of this object will pop the named instantiation off |
8573 | /// the stack. |
8574 | struct InstantiatingTemplate { |
8575 | /// Note that we are instantiating a class template, |
8576 | /// function template, variable template, alias template, |
8577 | /// or a member thereof. |
8578 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8579 | Decl *Entity, |
8580 | SourceRange InstantiationRange = SourceRange()); |
8581 | |
8582 | struct ExceptionSpecification {}; |
8583 | /// Note that we are instantiating an exception specification |
8584 | /// of a function template. |
8585 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8586 | FunctionDecl *Entity, ExceptionSpecification, |
8587 | SourceRange InstantiationRange = SourceRange()); |
8588 | |
8589 | /// Note that we are instantiating a default argument in a |
8590 | /// template-id. |
8591 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8592 | TemplateParameter Param, TemplateDecl *Template, |
8593 | ArrayRef<TemplateArgument> TemplateArgs, |
8594 | SourceRange InstantiationRange = SourceRange()); |
8595 | |
8596 | /// Note that we are substituting either explicitly-specified or |
8597 | /// deduced template arguments during function template argument deduction. |
8598 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8599 | FunctionTemplateDecl *FunctionTemplate, |
8600 | ArrayRef<TemplateArgument> TemplateArgs, |
8601 | CodeSynthesisContext::SynthesisKind Kind, |
8602 | sema::TemplateDeductionInfo &DeductionInfo, |
8603 | SourceRange InstantiationRange = SourceRange()); |
8604 | |
8605 | /// Note that we are instantiating as part of template |
8606 | /// argument deduction for a class template declaration. |
8607 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8608 | TemplateDecl *Template, |
8609 | ArrayRef<TemplateArgument> TemplateArgs, |
8610 | sema::TemplateDeductionInfo &DeductionInfo, |
8611 | SourceRange InstantiationRange = SourceRange()); |
8612 | |
8613 | /// Note that we are instantiating as part of template |
8614 | /// argument deduction for a class template partial |
8615 | /// specialization. |
8616 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8617 | ClassTemplatePartialSpecializationDecl *PartialSpec, |
8618 | ArrayRef<TemplateArgument> TemplateArgs, |
8619 | sema::TemplateDeductionInfo &DeductionInfo, |
8620 | SourceRange InstantiationRange = SourceRange()); |
8621 | |
8622 | /// Note that we are instantiating as part of template |
8623 | /// argument deduction for a variable template partial |
8624 | /// specialization. |
8625 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8626 | VarTemplatePartialSpecializationDecl *PartialSpec, |
8627 | ArrayRef<TemplateArgument> TemplateArgs, |
8628 | sema::TemplateDeductionInfo &DeductionInfo, |
8629 | SourceRange InstantiationRange = SourceRange()); |
8630 | |
8631 | /// Note that we are instantiating a default argument for a function |
8632 | /// parameter. |
8633 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8634 | ParmVarDecl *Param, |
8635 | ArrayRef<TemplateArgument> TemplateArgs, |
8636 | SourceRange InstantiationRange = SourceRange()); |
8637 | |
8638 | /// Note that we are substituting prior template arguments into a |
8639 | /// non-type parameter. |
8640 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8641 | NamedDecl *Template, |
8642 | NonTypeTemplateParmDecl *Param, |
8643 | ArrayRef<TemplateArgument> TemplateArgs, |
8644 | SourceRange InstantiationRange); |
8645 | |
8646 | /// Note that we are substituting prior template arguments into a |
8647 | /// template template parameter. |
8648 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8649 | NamedDecl *Template, |
8650 | TemplateTemplateParmDecl *Param, |
8651 | ArrayRef<TemplateArgument> TemplateArgs, |
8652 | SourceRange InstantiationRange); |
8653 | |
8654 | /// Note that we are checking the default template argument |
8655 | /// against the template parameter for a given template-id. |
8656 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8657 | TemplateDecl *Template, |
8658 | NamedDecl *Param, |
8659 | ArrayRef<TemplateArgument> TemplateArgs, |
8660 | SourceRange InstantiationRange); |
8661 | |
8662 | struct ConstraintsCheck {}; |
8663 | /// \brief Note that we are checking the constraints associated with some |
8664 | /// constrained entity (a concept declaration or a template with associated |
8665 | /// constraints). |
8666 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8667 | ConstraintsCheck, NamedDecl *Template, |
8668 | ArrayRef<TemplateArgument> TemplateArgs, |
8669 | SourceRange InstantiationRange); |
8670 | |
8671 | struct ConstraintSubstitution {}; |
8672 | /// \brief Note that we are checking a constraint expression associated |
8673 | /// with a template declaration or as part of the satisfaction check of a |
8674 | /// concept. |
8675 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8676 | ConstraintSubstitution, NamedDecl *Template, |
8677 | sema::TemplateDeductionInfo &DeductionInfo, |
8678 | SourceRange InstantiationRange); |
8679 | |
8680 | struct ConstraintNormalization {}; |
8681 | /// \brief Note that we are normalizing a constraint expression. |
8682 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8683 | ConstraintNormalization, NamedDecl *Template, |
8684 | SourceRange InstantiationRange); |
8685 | |
8686 | struct ParameterMappingSubstitution {}; |
8687 | /// \brief Note that we are subtituting into the parameter mapping of an |
8688 | /// atomic constraint during constraint normalization. |
8689 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8690 | ParameterMappingSubstitution, NamedDecl *Template, |
8691 | SourceRange InstantiationRange); |
8692 | |
8693 | /// \brief Note that we are substituting template arguments into a part of |
8694 | /// a requirement of a requires expression. |
8695 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8696 | concepts::Requirement *Req, |
8697 | sema::TemplateDeductionInfo &DeductionInfo, |
8698 | SourceRange InstantiationRange = SourceRange()); |
8699 | |
8700 | /// \brief Note that we are checking the satisfaction of the constraint |
8701 | /// expression inside of a nested requirement. |
8702 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8703 | concepts::NestedRequirement *Req, ConstraintsCheck, |
8704 | SourceRange InstantiationRange = SourceRange()); |
8705 | |
8706 | /// Note that we have finished instantiating this template. |
8707 | void Clear(); |
8708 | |
8709 | ~InstantiatingTemplate() { Clear(); } |
8710 | |
8711 | /// Determines whether we have exceeded the maximum |
8712 | /// recursive template instantiations. |
8713 | bool isInvalid() const { return Invalid; } |
8714 | |
8715 | /// Determine whether we are already instantiating this |
8716 | /// specialization in some surrounding active instantiation. |
8717 | bool isAlreadyInstantiating() const { return AlreadyInstantiating; } |
8718 | |
8719 | private: |
8720 | Sema &SemaRef; |
8721 | bool Invalid; |
8722 | bool AlreadyInstantiating; |
8723 | bool CheckInstantiationDepth(SourceLocation PointOfInstantiation, |
8724 | SourceRange InstantiationRange); |
8725 | |
8726 | InstantiatingTemplate( |
8727 | Sema &SemaRef, CodeSynthesisContext::SynthesisKind Kind, |
8728 | SourceLocation PointOfInstantiation, SourceRange InstantiationRange, |
8729 | Decl *Entity, NamedDecl *Template = nullptr, |
8730 | ArrayRef<TemplateArgument> TemplateArgs = None, |
8731 | sema::TemplateDeductionInfo *DeductionInfo = nullptr); |
8732 | |
8733 | InstantiatingTemplate(const InstantiatingTemplate&) = delete; |
8734 | |
8735 | InstantiatingTemplate& |
8736 | operator=(const InstantiatingTemplate&) = delete; |
8737 | }; |
8738 | |
8739 | void pushCodeSynthesisContext(CodeSynthesisContext Ctx); |
8740 | void popCodeSynthesisContext(); |
8741 | |
8742 | /// Determine whether we are currently performing template instantiation. |
8743 | bool inTemplateInstantiation() const { |
8744 | return CodeSynthesisContexts.size() > NonInstantiationEntries; |
8745 | } |
8746 | |
8747 | void PrintContextStack() { |
8748 | if (!CodeSynthesisContexts.empty() && |
8749 | CodeSynthesisContexts.size() != LastEmittedCodeSynthesisContextDepth) { |
8750 | PrintInstantiationStack(); |
8751 | LastEmittedCodeSynthesisContextDepth = CodeSynthesisContexts.size(); |
8752 | } |
8753 | if (PragmaAttributeCurrentTargetDecl) |
8754 | PrintPragmaAttributeInstantiationPoint(); |
8755 | } |
8756 | void PrintInstantiationStack(); |
8757 | |
8758 | void PrintPragmaAttributeInstantiationPoint(); |
8759 | |
8760 | /// Determines whether we are currently in a context where |
8761 | /// template argument substitution failures are not considered |
8762 | /// errors. |
8763 | /// |
8764 | /// \returns An empty \c Optional if we're not in a SFINAE context. |
8765 | /// Otherwise, contains a pointer that, if non-NULL, contains the nearest |
8766 | /// template-deduction context object, which can be used to capture |
8767 | /// diagnostics that will be suppressed. |
8768 | Optional<sema::TemplateDeductionInfo *> isSFINAEContext() const; |
8769 | |
8770 | /// Determines whether we are currently in a context that |
8771 | /// is not evaluated as per C++ [expr] p5. |
8772 | bool isUnevaluatedContext() const { |
8773 | assert(!ExprEvalContexts.empty() &&((!ExprEvalContexts.empty() && "Must be in an expression evaluation context" ) ? static_cast<void> (0) : __assert_fail ("!ExprEvalContexts.empty() && \"Must be in an expression evaluation context\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 8774, __PRETTY_FUNCTION__)) |
8774 | "Must be in an expression evaluation context")((!ExprEvalContexts.empty() && "Must be in an expression evaluation context" ) ? static_cast<void> (0) : __assert_fail ("!ExprEvalContexts.empty() && \"Must be in an expression evaluation context\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 8774, __PRETTY_FUNCTION__)); |
8775 | return ExprEvalContexts.back().isUnevaluated(); |
8776 | } |
8777 | |
8778 | /// RAII class used to determine whether SFINAE has |
8779 | /// trapped any errors that occur during template argument |
8780 | /// deduction. |
8781 | class SFINAETrap { |
8782 | Sema &SemaRef; |
8783 | unsigned PrevSFINAEErrors; |
8784 | bool PrevInNonInstantiationSFINAEContext; |
8785 | bool PrevAccessCheckingSFINAE; |
8786 | bool PrevLastDiagnosticIgnored; |
8787 | |
8788 | public: |
8789 | explicit SFINAETrap(Sema &SemaRef, bool AccessCheckingSFINAE = false) |
8790 | : SemaRef(SemaRef), PrevSFINAEErrors(SemaRef.NumSFINAEErrors), |
8791 | PrevInNonInstantiationSFINAEContext( |
8792 | SemaRef.InNonInstantiationSFINAEContext), |
8793 | PrevAccessCheckingSFINAE(SemaRef.AccessCheckingSFINAE), |
8794 | PrevLastDiagnosticIgnored( |
8795 | SemaRef.getDiagnostics().isLastDiagnosticIgnored()) |
8796 | { |
8797 | if (!SemaRef.isSFINAEContext()) |
8798 | SemaRef.InNonInstantiationSFINAEContext = true; |
8799 | SemaRef.AccessCheckingSFINAE = AccessCheckingSFINAE; |
8800 | } |
8801 | |
8802 | ~SFINAETrap() { |
8803 | SemaRef.NumSFINAEErrors = PrevSFINAEErrors; |
8804 | SemaRef.InNonInstantiationSFINAEContext |
8805 | = PrevInNonInstantiationSFINAEContext; |
8806 | SemaRef.AccessCheckingSFINAE = PrevAccessCheckingSFINAE; |
8807 | SemaRef.getDiagnostics().setLastDiagnosticIgnored( |
8808 | PrevLastDiagnosticIgnored); |
8809 | } |
8810 | |
8811 | /// Determine whether any SFINAE errors have been trapped. |
8812 | bool hasErrorOccurred() const { |
8813 | return SemaRef.NumSFINAEErrors > PrevSFINAEErrors; |
8814 | } |
8815 | }; |
8816 | |
8817 | /// RAII class used to indicate that we are performing provisional |
8818 | /// semantic analysis to determine the validity of a construct, so |
8819 | /// typo-correction and diagnostics in the immediate context (not within |
8820 | /// implicitly-instantiated templates) should be suppressed. |
8821 | class TentativeAnalysisScope { |
8822 | Sema &SemaRef; |
8823 | // FIXME: Using a SFINAETrap for this is a hack. |
8824 | SFINAETrap Trap; |
8825 | bool PrevDisableTypoCorrection; |
8826 | public: |
8827 | explicit TentativeAnalysisScope(Sema &SemaRef) |
8828 | : SemaRef(SemaRef), Trap(SemaRef, true), |
8829 | PrevDisableTypoCorrection(SemaRef.DisableTypoCorrection) { |
8830 | SemaRef.DisableTypoCorrection = true; |
8831 | } |
8832 | ~TentativeAnalysisScope() { |
8833 | SemaRef.DisableTypoCorrection = PrevDisableTypoCorrection; |
8834 | } |
8835 | }; |
8836 | |
8837 | /// The current instantiation scope used to store local |
8838 | /// variables. |
8839 | LocalInstantiationScope *CurrentInstantiationScope; |
8840 | |
8841 | /// Tracks whether we are in a context where typo correction is |
8842 | /// disabled. |
8843 | bool DisableTypoCorrection; |
8844 | |
8845 | /// The number of typos corrected by CorrectTypo. |
8846 | unsigned TyposCorrected; |
8847 | |
8848 | typedef llvm::SmallSet<SourceLocation, 2> SrcLocSet; |
8849 | typedef llvm::DenseMap<IdentifierInfo *, SrcLocSet> IdentifierSourceLocations; |
8850 | |
8851 | /// A cache containing identifiers for which typo correction failed and |
8852 | /// their locations, so that repeated attempts to correct an identifier in a |
8853 | /// given location are ignored if typo correction already failed for it. |
8854 | IdentifierSourceLocations TypoCorrectionFailures; |
8855 | |
8856 | /// Worker object for performing CFG-based warnings. |
8857 | sema::AnalysisBasedWarnings AnalysisWarnings; |
8858 | threadSafety::BeforeSet *ThreadSafetyDeclCache; |
8859 | |
8860 | /// An entity for which implicit template instantiation is required. |
8861 | /// |
8862 | /// The source location associated with the declaration is the first place in |
8863 | /// the source code where the declaration was "used". It is not necessarily |
8864 | /// the point of instantiation (which will be either before or after the |
8865 | /// namespace-scope declaration that triggered this implicit instantiation), |
8866 | /// However, it is the location that diagnostics should generally refer to, |
8867 | /// because users will need to know what code triggered the instantiation. |
8868 | typedef std::pair<ValueDecl *, SourceLocation> PendingImplicitInstantiation; |
8869 | |
8870 | /// The queue of implicit template instantiations that are required |
8871 | /// but have not yet been performed. |
8872 | std::deque<PendingImplicitInstantiation> PendingInstantiations; |
8873 | |
8874 | /// Queue of implicit template instantiations that cannot be performed |
8875 | /// eagerly. |
8876 | SmallVector<PendingImplicitInstantiation, 1> LateParsedInstantiations; |
8877 | |
8878 | class GlobalEagerInstantiationScope { |
8879 | public: |
8880 | GlobalEagerInstantiationScope(Sema &S, bool Enabled) |
8881 | : S(S), Enabled(Enabled) { |
8882 | if (!Enabled) return; |
8883 | |
8884 | SavedPendingInstantiations.swap(S.PendingInstantiations); |
8885 | SavedVTableUses.swap(S.VTableUses); |
8886 | } |
8887 | |
8888 | void perform() { |
8889 | if (Enabled) { |
8890 | S.DefineUsedVTables(); |
8891 | S.PerformPendingInstantiations(); |
8892 | } |
8893 | } |
8894 | |
8895 | ~GlobalEagerInstantiationScope() { |
8896 | if (!Enabled) return; |
8897 | |
8898 | // Restore the set of pending vtables. |
8899 | assert(S.VTableUses.empty() &&((S.VTableUses.empty() && "VTableUses should be empty before it is discarded." ) ? static_cast<void> (0) : __assert_fail ("S.VTableUses.empty() && \"VTableUses should be empty before it is discarded.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 8900, __PRETTY_FUNCTION__)) |
8900 | "VTableUses should be empty before it is discarded.")((S.VTableUses.empty() && "VTableUses should be empty before it is discarded." ) ? static_cast<void> (0) : __assert_fail ("S.VTableUses.empty() && \"VTableUses should be empty before it is discarded.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 8900, __PRETTY_FUNCTION__)); |
8901 | S.VTableUses.swap(SavedVTableUses); |
8902 | |
8903 | // Restore the set of pending implicit instantiations. |
8904 | if (S.TUKind != TU_Prefix || !S.LangOpts.PCHInstantiateTemplates) { |
8905 | assert(S.PendingInstantiations.empty() &&((S.PendingInstantiations.empty() && "PendingInstantiations should be empty before it is discarded." ) ? static_cast<void> (0) : __assert_fail ("S.PendingInstantiations.empty() && \"PendingInstantiations should be empty before it is discarded.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 8906, __PRETTY_FUNCTION__)) |
8906 | "PendingInstantiations should be empty before it is discarded.")((S.PendingInstantiations.empty() && "PendingInstantiations should be empty before it is discarded." ) ? static_cast<void> (0) : __assert_fail ("S.PendingInstantiations.empty() && \"PendingInstantiations should be empty before it is discarded.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 8906, __PRETTY_FUNCTION__)); |
8907 | S.PendingInstantiations.swap(SavedPendingInstantiations); |
8908 | } else { |
8909 | // Template instantiations in the PCH may be delayed until the TU. |
8910 | S.PendingInstantiations.swap(SavedPendingInstantiations); |
8911 | S.PendingInstantiations.insert(S.PendingInstantiations.end(), |
8912 | SavedPendingInstantiations.begin(), |
8913 | SavedPendingInstantiations.end()); |
8914 | } |
8915 | } |
8916 | |
8917 | private: |
8918 | Sema &S; |
8919 | SmallVector<VTableUse, 16> SavedVTableUses; |
8920 | std::deque<PendingImplicitInstantiation> SavedPendingInstantiations; |
8921 | bool Enabled; |
8922 | }; |
8923 | |
8924 | /// The queue of implicit template instantiations that are required |
8925 | /// and must be performed within the current local scope. |
8926 | /// |
8927 | /// This queue is only used for member functions of local classes in |
8928 | /// templates, which must be instantiated in the same scope as their |
8929 | /// enclosing function, so that they can reference function-local |
8930 | /// types, static variables, enumerators, etc. |
8931 | std::deque<PendingImplicitInstantiation> PendingLocalImplicitInstantiations; |
8932 | |
8933 | class LocalEagerInstantiationScope { |
8934 | public: |
8935 | LocalEagerInstantiationScope(Sema &S) : S(S) { |
8936 | SavedPendingLocalImplicitInstantiations.swap( |
8937 | S.PendingLocalImplicitInstantiations); |
8938 | } |
8939 | |
8940 | void perform() { S.PerformPendingInstantiations(/*LocalOnly=*/true); } |
8941 | |
8942 | ~LocalEagerInstantiationScope() { |
8943 | assert(S.PendingLocalImplicitInstantiations.empty() &&((S.PendingLocalImplicitInstantiations.empty() && "there shouldn't be any pending local implicit instantiations" ) ? static_cast<void> (0) : __assert_fail ("S.PendingLocalImplicitInstantiations.empty() && \"there shouldn't be any pending local implicit instantiations\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 8944, __PRETTY_FUNCTION__)) |
8944 | "there shouldn't be any pending local implicit instantiations")((S.PendingLocalImplicitInstantiations.empty() && "there shouldn't be any pending local implicit instantiations" ) ? static_cast<void> (0) : __assert_fail ("S.PendingLocalImplicitInstantiations.empty() && \"there shouldn't be any pending local implicit instantiations\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 8944, __PRETTY_FUNCTION__)); |
8945 | SavedPendingLocalImplicitInstantiations.swap( |
8946 | S.PendingLocalImplicitInstantiations); |
8947 | } |
8948 | |
8949 | private: |
8950 | Sema &S; |
8951 | std::deque<PendingImplicitInstantiation> |
8952 | SavedPendingLocalImplicitInstantiations; |
8953 | }; |
8954 | |
8955 | /// A helper class for building up ExtParameterInfos. |
8956 | class ExtParameterInfoBuilder { |
8957 | SmallVector<FunctionProtoType::ExtParameterInfo, 16> Infos; |
8958 | bool HasInteresting = false; |
8959 | |
8960 | public: |
8961 | /// Set the ExtParameterInfo for the parameter at the given index, |
8962 | /// |
8963 | void set(unsigned index, FunctionProtoType::ExtParameterInfo info) { |
8964 | assert(Infos.size() <= index)((Infos.size() <= index) ? static_cast<void> (0) : __assert_fail ("Infos.size() <= index", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 8964, __PRETTY_FUNCTION__)); |
8965 | Infos.resize(index); |
8966 | Infos.push_back(info); |
8967 | |
8968 | if (!HasInteresting) |
8969 | HasInteresting = (info != FunctionProtoType::ExtParameterInfo()); |
8970 | } |
8971 | |
8972 | /// Return a pointer (suitable for setting in an ExtProtoInfo) to the |
8973 | /// ExtParameterInfo array we've built up. |
8974 | const FunctionProtoType::ExtParameterInfo * |
8975 | getPointerOrNull(unsigned numParams) { |
8976 | if (!HasInteresting) return nullptr; |
8977 | Infos.resize(numParams); |
8978 | return Infos.data(); |
8979 | } |
8980 | }; |
8981 | |
8982 | void PerformPendingInstantiations(bool LocalOnly = false); |
8983 | |
8984 | TypeSourceInfo *SubstType(TypeSourceInfo *T, |
8985 | const MultiLevelTemplateArgumentList &TemplateArgs, |
8986 | SourceLocation Loc, DeclarationName Entity, |
8987 | bool AllowDeducedTST = false); |
8988 | |
8989 | QualType SubstType(QualType T, |
8990 | const MultiLevelTemplateArgumentList &TemplateArgs, |
8991 | SourceLocation Loc, DeclarationName Entity); |
8992 | |
8993 | TypeSourceInfo *SubstType(TypeLoc TL, |
8994 | const MultiLevelTemplateArgumentList &TemplateArgs, |
8995 | SourceLocation Loc, DeclarationName Entity); |
8996 | |
8997 | TypeSourceInfo *SubstFunctionDeclType(TypeSourceInfo *T, |
8998 | const MultiLevelTemplateArgumentList &TemplateArgs, |
8999 | SourceLocation Loc, |
9000 | DeclarationName Entity, |
9001 | CXXRecordDecl *ThisContext, |
9002 | Qualifiers ThisTypeQuals); |
9003 | void SubstExceptionSpec(FunctionDecl *New, const FunctionProtoType *Proto, |
9004 | const MultiLevelTemplateArgumentList &Args); |
9005 | bool SubstExceptionSpec(SourceLocation Loc, |
9006 | FunctionProtoType::ExceptionSpecInfo &ESI, |
9007 | SmallVectorImpl<QualType> &ExceptionStorage, |
9008 | const MultiLevelTemplateArgumentList &Args); |
9009 | ParmVarDecl *SubstParmVarDecl(ParmVarDecl *D, |
9010 | const MultiLevelTemplateArgumentList &TemplateArgs, |
9011 | int indexAdjustment, |
9012 | Optional<unsigned> NumExpansions, |
9013 | bool ExpectParameterPack); |
9014 | bool SubstParmTypes(SourceLocation Loc, ArrayRef<ParmVarDecl *> Params, |
9015 | const FunctionProtoType::ExtParameterInfo *ExtParamInfos, |
9016 | const MultiLevelTemplateArgumentList &TemplateArgs, |
9017 | SmallVectorImpl<QualType> &ParamTypes, |
9018 | SmallVectorImpl<ParmVarDecl *> *OutParams, |
9019 | ExtParameterInfoBuilder &ParamInfos); |
9020 | ExprResult SubstExpr(Expr *E, |
9021 | const MultiLevelTemplateArgumentList &TemplateArgs); |
9022 | |
9023 | /// Substitute the given template arguments into a list of |
9024 | /// expressions, expanding pack expansions if required. |
9025 | /// |
9026 | /// \param Exprs The list of expressions to substitute into. |
9027 | /// |
9028 | /// \param IsCall Whether this is some form of call, in which case |
9029 | /// default arguments will be dropped. |
9030 | /// |
9031 | /// \param TemplateArgs The set of template arguments to substitute. |
9032 | /// |
9033 | /// \param Outputs Will receive all of the substituted arguments. |
9034 | /// |
9035 | /// \returns true if an error occurred, false otherwise. |
9036 | bool SubstExprs(ArrayRef<Expr *> Exprs, bool IsCall, |
9037 | const MultiLevelTemplateArgumentList &TemplateArgs, |
9038 | SmallVectorImpl<Expr *> &Outputs); |
9039 | |
9040 | StmtResult SubstStmt(Stmt *S, |
9041 | const MultiLevelTemplateArgumentList &TemplateArgs); |
9042 | |
9043 | TemplateParameterList * |
9044 | SubstTemplateParams(TemplateParameterList *Params, DeclContext *Owner, |
9045 | const MultiLevelTemplateArgumentList &TemplateArgs); |
9046 | |
9047 | bool |
9048 | SubstTemplateArguments(ArrayRef<TemplateArgumentLoc> Args, |
9049 | const MultiLevelTemplateArgumentList &TemplateArgs, |
9050 | TemplateArgumentListInfo &Outputs); |
9051 | |
9052 | |
9053 | Decl *SubstDecl(Decl *D, DeclContext *Owner, |
9054 | const MultiLevelTemplateArgumentList &TemplateArgs); |
9055 | |
9056 | /// Substitute the name and return type of a defaulted 'operator<=>' to form |
9057 | /// an implicit 'operator=='. |
9058 | FunctionDecl *SubstSpaceshipAsEqualEqual(CXXRecordDecl *RD, |
9059 | FunctionDecl *Spaceship); |
9060 | |
9061 | ExprResult SubstInitializer(Expr *E, |
9062 | const MultiLevelTemplateArgumentList &TemplateArgs, |
9063 | bool CXXDirectInit); |
9064 | |
9065 | bool |
9066 | SubstBaseSpecifiers(CXXRecordDecl *Instantiation, |
9067 | CXXRecordDecl *Pattern, |
9068 | const MultiLevelTemplateArgumentList &TemplateArgs); |
9069 | |
9070 | bool |
9071 | InstantiateClass(SourceLocation PointOfInstantiation, |
9072 | CXXRecordDecl *Instantiation, CXXRecordDecl *Pattern, |
9073 | const MultiLevelTemplateArgumentList &TemplateArgs, |
9074 | TemplateSpecializationKind TSK, |
9075 | bool Complain = true); |
9076 | |
9077 | bool InstantiateEnum(SourceLocation PointOfInstantiation, |
9078 | EnumDecl *Instantiation, EnumDecl *Pattern, |
9079 | const MultiLevelTemplateArgumentList &TemplateArgs, |
9080 | TemplateSpecializationKind TSK); |
9081 | |
9082 | bool InstantiateInClassInitializer( |
9083 | SourceLocation PointOfInstantiation, FieldDecl *Instantiation, |
9084 | FieldDecl *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs); |
9085 | |
9086 | struct LateInstantiatedAttribute { |
9087 | const Attr *TmplAttr; |
9088 | LocalInstantiationScope *Scope; |
9089 | Decl *NewDecl; |
9090 | |
9091 | LateInstantiatedAttribute(const Attr *A, LocalInstantiationScope *S, |
9092 | Decl *D) |
9093 | : TmplAttr(A), Scope(S), NewDecl(D) |
9094 | { } |
9095 | }; |
9096 | typedef SmallVector<LateInstantiatedAttribute, 16> LateInstantiatedAttrVec; |
9097 | |
9098 | void InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, |
9099 | const Decl *Pattern, Decl *Inst, |
9100 | LateInstantiatedAttrVec *LateAttrs = nullptr, |
9101 | LocalInstantiationScope *OuterMostScope = nullptr); |
9102 | |
9103 | void |
9104 | InstantiateAttrsForDecl(const MultiLevelTemplateArgumentList &TemplateArgs, |
9105 | const Decl *Pattern, Decl *Inst, |
9106 | LateInstantiatedAttrVec *LateAttrs = nullptr, |
9107 | LocalInstantiationScope *OuterMostScope = nullptr); |
9108 | |
9109 | bool usesPartialOrExplicitSpecialization( |
9110 | SourceLocation Loc, ClassTemplateSpecializationDecl *ClassTemplateSpec); |
9111 | |
9112 | bool |
9113 | InstantiateClassTemplateSpecialization(SourceLocation PointOfInstantiation, |
9114 | ClassTemplateSpecializationDecl *ClassTemplateSpec, |
9115 | TemplateSpecializationKind TSK, |
9116 | bool Complain = true); |
9117 | |
9118 | void InstantiateClassMembers(SourceLocation PointOfInstantiation, |
9119 | CXXRecordDecl *Instantiation, |
9120 | const MultiLevelTemplateArgumentList &TemplateArgs, |
9121 | TemplateSpecializationKind TSK); |
9122 | |
9123 | void InstantiateClassTemplateSpecializationMembers( |
9124 | SourceLocation PointOfInstantiation, |
9125 | ClassTemplateSpecializationDecl *ClassTemplateSpec, |
9126 | TemplateSpecializationKind TSK); |
9127 | |
9128 | NestedNameSpecifierLoc |
9129 | SubstNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, |
9130 | const MultiLevelTemplateArgumentList &TemplateArgs); |
9131 | |
9132 | DeclarationNameInfo |
9133 | SubstDeclarationNameInfo(const DeclarationNameInfo &NameInfo, |
9134 | const MultiLevelTemplateArgumentList &TemplateArgs); |
9135 | TemplateName |
9136 | SubstTemplateName(NestedNameSpecifierLoc QualifierLoc, TemplateName Name, |
9137 | SourceLocation Loc, |
9138 | const MultiLevelTemplateArgumentList &TemplateArgs); |
9139 | bool Subst(const TemplateArgumentLoc *Args, unsigned NumArgs, |
9140 | TemplateArgumentListInfo &Result, |
9141 | const MultiLevelTemplateArgumentList &TemplateArgs); |
9142 | |
9143 | bool InstantiateDefaultArgument(SourceLocation CallLoc, FunctionDecl *FD, |
9144 | ParmVarDecl *Param); |
9145 | void InstantiateExceptionSpec(SourceLocation PointOfInstantiation, |
9146 | FunctionDecl *Function); |
9147 | bool CheckInstantiatedFunctionTemplateConstraints( |
9148 | SourceLocation PointOfInstantiation, FunctionDecl *Decl, |
9149 | ArrayRef<TemplateArgument> TemplateArgs, |
9150 | ConstraintSatisfaction &Satisfaction); |
9151 | FunctionDecl *InstantiateFunctionDeclaration(FunctionTemplateDecl *FTD, |
9152 | const TemplateArgumentList *Args, |
9153 | SourceLocation Loc); |
9154 | void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, |
9155 | FunctionDecl *Function, |
9156 | bool Recursive = false, |
9157 | bool DefinitionRequired = false, |
9158 | bool AtEndOfTU = false); |
9159 | VarTemplateSpecializationDecl *BuildVarTemplateInstantiation( |
9160 | VarTemplateDecl *VarTemplate, VarDecl *FromVar, |
9161 | const TemplateArgumentList &TemplateArgList, |
9162 | const TemplateArgumentListInfo &TemplateArgsInfo, |
9163 | SmallVectorImpl<TemplateArgument> &Converted, |
9164 | SourceLocation PointOfInstantiation, void *InsertPos, |
9165 | LateInstantiatedAttrVec *LateAttrs = nullptr, |
9166 | LocalInstantiationScope *StartingScope = nullptr); |
9167 | VarTemplateSpecializationDecl *CompleteVarTemplateSpecializationDecl( |
9168 | VarTemplateSpecializationDecl *VarSpec, VarDecl *PatternDecl, |
9169 | const MultiLevelTemplateArgumentList &TemplateArgs); |
9170 | void |
9171 | BuildVariableInstantiation(VarDecl *NewVar, VarDecl *OldVar, |
9172 | const MultiLevelTemplateArgumentList &TemplateArgs, |
9173 | LateInstantiatedAttrVec *LateAttrs, |
9174 | DeclContext *Owner, |
9175 | LocalInstantiationScope *StartingScope, |
9176 | bool InstantiatingVarTemplate = false, |
9177 | VarTemplateSpecializationDecl *PrevVTSD = nullptr); |
9178 | |
9179 | void InstantiateVariableInitializer( |
9180 | VarDecl *Var, VarDecl *OldVar, |
9181 | const MultiLevelTemplateArgumentList &TemplateArgs); |
9182 | void InstantiateVariableDefinition(SourceLocation PointOfInstantiation, |
9183 | VarDecl *Var, bool Recursive = false, |
9184 | bool DefinitionRequired = false, |
9185 | bool AtEndOfTU = false); |
9186 | |
9187 | void InstantiateMemInitializers(CXXConstructorDecl *New, |
9188 | const CXXConstructorDecl *Tmpl, |
9189 | const MultiLevelTemplateArgumentList &TemplateArgs); |
9190 | |
9191 | NamedDecl *FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, |
9192 | const MultiLevelTemplateArgumentList &TemplateArgs, |
9193 | bool FindingInstantiatedContext = false); |
9194 | DeclContext *FindInstantiatedContext(SourceLocation Loc, DeclContext *DC, |
9195 | const MultiLevelTemplateArgumentList &TemplateArgs); |
9196 | |
9197 | // Objective-C declarations. |
9198 | enum ObjCContainerKind { |
9199 | OCK_None = -1, |
9200 | OCK_Interface = 0, |
9201 | OCK_Protocol, |
9202 | OCK_Category, |
9203 | OCK_ClassExtension, |
9204 | OCK_Implementation, |
9205 | OCK_CategoryImplementation |
9206 | }; |
9207 | ObjCContainerKind getObjCContainerKind() const; |
9208 | |
9209 | DeclResult actOnObjCTypeParam(Scope *S, |
9210 | ObjCTypeParamVariance variance, |
9211 | SourceLocation varianceLoc, |
9212 | unsigned index, |
9213 | IdentifierInfo *paramName, |
9214 | SourceLocation paramLoc, |
9215 | SourceLocation colonLoc, |
9216 | ParsedType typeBound); |
9217 | |
9218 | ObjCTypeParamList *actOnObjCTypeParamList(Scope *S, SourceLocation lAngleLoc, |
9219 | ArrayRef<Decl *> typeParams, |
9220 | SourceLocation rAngleLoc); |
9221 | void popObjCTypeParamList(Scope *S, ObjCTypeParamList *typeParamList); |
9222 | |
9223 | Decl *ActOnStartClassInterface( |
9224 | Scope *S, SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName, |
9225 | SourceLocation ClassLoc, ObjCTypeParamList *typeParamList, |
9226 | IdentifierInfo *SuperName, SourceLocation SuperLoc, |
9227 | ArrayRef<ParsedType> SuperTypeArgs, SourceRange SuperTypeArgsRange, |
9228 | Decl *const *ProtoRefs, unsigned NumProtoRefs, |
9229 | const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, |
9230 | const ParsedAttributesView &AttrList); |
9231 | |
9232 | void ActOnSuperClassOfClassInterface(Scope *S, |
9233 | SourceLocation AtInterfaceLoc, |
9234 | ObjCInterfaceDecl *IDecl, |
9235 | IdentifierInfo *ClassName, |
9236 | SourceLocation ClassLoc, |
9237 | IdentifierInfo *SuperName, |
9238 | SourceLocation SuperLoc, |
9239 | ArrayRef<ParsedType> SuperTypeArgs, |
9240 | SourceRange SuperTypeArgsRange); |
9241 | |
9242 | void ActOnTypedefedProtocols(SmallVectorImpl<Decl *> &ProtocolRefs, |
9243 | SmallVectorImpl<SourceLocation> &ProtocolLocs, |
9244 | IdentifierInfo *SuperName, |
9245 | SourceLocation SuperLoc); |
9246 | |
9247 | Decl *ActOnCompatibilityAlias( |
9248 | SourceLocation AtCompatibilityAliasLoc, |
9249 | IdentifierInfo *AliasName, SourceLocation AliasLocation, |
9250 | IdentifierInfo *ClassName, SourceLocation ClassLocation); |
9251 | |
9252 | bool CheckForwardProtocolDeclarationForCircularDependency( |
9253 | IdentifierInfo *PName, |
9254 | SourceLocation &PLoc, SourceLocation PrevLoc, |
9255 | const ObjCList<ObjCProtocolDecl> &PList); |
9256 | |
9257 | Decl *ActOnStartProtocolInterface( |
9258 | SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName, |
9259 | SourceLocation ProtocolLoc, Decl *const *ProtoRefNames, |
9260 | unsigned NumProtoRefs, const SourceLocation *ProtoLocs, |
9261 | SourceLocation EndProtoLoc, const ParsedAttributesView &AttrList); |
9262 | |
9263 | Decl *ActOnStartCategoryInterface( |
9264 | SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName, |
9265 | SourceLocation ClassLoc, ObjCTypeParamList *typeParamList, |
9266 | IdentifierInfo *CategoryName, SourceLocation CategoryLoc, |
9267 | Decl *const *ProtoRefs, unsigned NumProtoRefs, |
9268 | const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, |
9269 | const ParsedAttributesView &AttrList); |
9270 | |
9271 | Decl *ActOnStartClassImplementation(SourceLocation AtClassImplLoc, |
9272 | IdentifierInfo *ClassName, |
9273 | SourceLocation ClassLoc, |
9274 | IdentifierInfo *SuperClassname, |
9275 | SourceLocation SuperClassLoc, |
9276 | const ParsedAttributesView &AttrList); |
9277 | |
9278 | Decl *ActOnStartCategoryImplementation(SourceLocation AtCatImplLoc, |
9279 | IdentifierInfo *ClassName, |
9280 | SourceLocation ClassLoc, |
9281 | IdentifierInfo *CatName, |
9282 | SourceLocation CatLoc, |
9283 | const ParsedAttributesView &AttrList); |
9284 | |
9285 | DeclGroupPtrTy ActOnFinishObjCImplementation(Decl *ObjCImpDecl, |
9286 | ArrayRef<Decl *> Decls); |
9287 | |
9288 | DeclGroupPtrTy ActOnForwardClassDeclaration(SourceLocation Loc, |
9289 | IdentifierInfo **IdentList, |
9290 | SourceLocation *IdentLocs, |
9291 | ArrayRef<ObjCTypeParamList *> TypeParamLists, |
9292 | unsigned NumElts); |
9293 | |
9294 | DeclGroupPtrTy |
9295 | ActOnForwardProtocolDeclaration(SourceLocation AtProtoclLoc, |
9296 | ArrayRef<IdentifierLocPair> IdentList, |
9297 | const ParsedAttributesView &attrList); |
9298 | |
9299 | void FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer, |
9300 | ArrayRef<IdentifierLocPair> ProtocolId, |
9301 | SmallVectorImpl<Decl *> &Protocols); |
9302 | |
9303 | void DiagnoseTypeArgsAndProtocols(IdentifierInfo *ProtocolId, |
9304 | SourceLocation ProtocolLoc, |
9305 | IdentifierInfo *TypeArgId, |
9306 | SourceLocation TypeArgLoc, |
9307 | bool SelectProtocolFirst = false); |
9308 | |
9309 | /// Given a list of identifiers (and their locations), resolve the |
9310 | /// names to either Objective-C protocol qualifiers or type |
9311 | /// arguments, as appropriate. |
9312 | void actOnObjCTypeArgsOrProtocolQualifiers( |
9313 | Scope *S, |
9314 | ParsedType baseType, |
9315 | SourceLocation lAngleLoc, |
9316 | ArrayRef<IdentifierInfo *> identifiers, |
9317 | ArrayRef<SourceLocation> identifierLocs, |
9318 | SourceLocation rAngleLoc, |
9319 | SourceLocation &typeArgsLAngleLoc, |
9320 | SmallVectorImpl<ParsedType> &typeArgs, |
9321 | SourceLocation &typeArgsRAngleLoc, |
9322 | SourceLocation &protocolLAngleLoc, |
9323 | SmallVectorImpl<Decl *> &protocols, |
9324 | SourceLocation &protocolRAngleLoc, |
9325 | bool warnOnIncompleteProtocols); |
9326 | |
9327 | /// Build a an Objective-C protocol-qualified 'id' type where no |
9328 | /// base type was specified. |
9329 | TypeResult actOnObjCProtocolQualifierType( |
9330 | SourceLocation lAngleLoc, |
9331 | ArrayRef<Decl *> protocols, |
9332 | ArrayRef<SourceLocation> protocolLocs, |
9333 | SourceLocation rAngleLoc); |
9334 | |
9335 | /// Build a specialized and/or protocol-qualified Objective-C type. |
9336 | TypeResult actOnObjCTypeArgsAndProtocolQualifiers( |
9337 | Scope *S, |
9338 | SourceLocation Loc, |
9339 | ParsedType BaseType, |
9340 | SourceLocation TypeArgsLAngleLoc, |
9341 | ArrayRef<ParsedType> TypeArgs, |
9342 | SourceLocation TypeArgsRAngleLoc, |
9343 | SourceLocation ProtocolLAngleLoc, |
9344 | ArrayRef<Decl *> Protocols, |
9345 | ArrayRef<SourceLocation> ProtocolLocs, |
9346 | SourceLocation ProtocolRAngleLoc); |
9347 | |
9348 | /// Build an Objective-C type parameter type. |
9349 | QualType BuildObjCTypeParamType(const ObjCTypeParamDecl *Decl, |
9350 | SourceLocation ProtocolLAngleLoc, |
9351 | ArrayRef<ObjCProtocolDecl *> Protocols, |
9352 | ArrayRef<SourceLocation> ProtocolLocs, |
9353 | SourceLocation ProtocolRAngleLoc, |
9354 | bool FailOnError = false); |
9355 | |
9356 | /// Build an Objective-C object pointer type. |
9357 | QualType BuildObjCObjectType(QualType BaseType, |
9358 | SourceLocation Loc, |
9359 | SourceLocation TypeArgsLAngleLoc, |
9360 | ArrayRef<TypeSourceInfo *> TypeArgs, |
9361 | SourceLocation TypeArgsRAngleLoc, |
9362 | SourceLocation ProtocolLAngleLoc, |
9363 | ArrayRef<ObjCProtocolDecl *> Protocols, |
9364 | ArrayRef<SourceLocation> ProtocolLocs, |
9365 | SourceLocation ProtocolRAngleLoc, |
9366 | bool FailOnError = false); |
9367 | |
9368 | /// Ensure attributes are consistent with type. |
9369 | /// \param [in, out] Attributes The attributes to check; they will |
9370 | /// be modified to be consistent with \p PropertyTy. |
9371 | void CheckObjCPropertyAttributes(Decl *PropertyPtrTy, |
9372 | SourceLocation Loc, |
9373 | unsigned &Attributes, |
9374 | bool propertyInPrimaryClass); |
9375 | |
9376 | /// Process the specified property declaration and create decls for the |
9377 | /// setters and getters as needed. |
9378 | /// \param property The property declaration being processed |
9379 | void ProcessPropertyDecl(ObjCPropertyDecl *property); |
9380 | |
9381 | |
9382 | void DiagnosePropertyMismatch(ObjCPropertyDecl *Property, |
9383 | ObjCPropertyDecl *SuperProperty, |
9384 | const IdentifierInfo *Name, |
9385 | bool OverridingProtocolProperty); |
9386 | |
9387 | void DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT, |
9388 | ObjCInterfaceDecl *ID); |
9389 | |
9390 | Decl *ActOnAtEnd(Scope *S, SourceRange AtEnd, |
9391 | ArrayRef<Decl *> allMethods = None, |
9392 | ArrayRef<DeclGroupPtrTy> allTUVars = None); |
9393 | |
9394 | Decl *ActOnProperty(Scope *S, SourceLocation AtLoc, |
9395 | SourceLocation LParenLoc, |
9396 | FieldDeclarator &FD, ObjCDeclSpec &ODS, |
9397 | Selector GetterSel, Selector SetterSel, |
9398 | tok::ObjCKeywordKind MethodImplKind, |
9399 | DeclContext *lexicalDC = nullptr); |
9400 | |
9401 | Decl *ActOnPropertyImplDecl(Scope *S, |
9402 | SourceLocation AtLoc, |
9403 | SourceLocation PropertyLoc, |
9404 | bool ImplKind, |
9405 | IdentifierInfo *PropertyId, |
9406 | IdentifierInfo *PropertyIvar, |
9407 | SourceLocation PropertyIvarLoc, |
9408 | ObjCPropertyQueryKind QueryKind); |
9409 | |
9410 | enum ObjCSpecialMethodKind { |
9411 | OSMK_None, |
9412 | OSMK_Alloc, |
9413 | OSMK_New, |
9414 | OSMK_Copy, |
9415 | OSMK_RetainingInit, |
9416 | OSMK_NonRetainingInit |
9417 | }; |
9418 | |
9419 | struct ObjCArgInfo { |
9420 | IdentifierInfo *Name; |
9421 | SourceLocation NameLoc; |
9422 | // The Type is null if no type was specified, and the DeclSpec is invalid |
9423 | // in this case. |
9424 | ParsedType Type; |
9425 | ObjCDeclSpec DeclSpec; |
9426 | |
9427 | /// ArgAttrs - Attribute list for this argument. |
9428 | ParsedAttributesView ArgAttrs; |
9429 | }; |
9430 | |
9431 | Decl *ActOnMethodDeclaration( |
9432 | Scope *S, |
9433 | SourceLocation BeginLoc, // location of the + or -. |
9434 | SourceLocation EndLoc, // location of the ; or {. |
9435 | tok::TokenKind MethodType, ObjCDeclSpec &ReturnQT, ParsedType ReturnType, |
9436 | ArrayRef<SourceLocation> SelectorLocs, Selector Sel, |
9437 | // optional arguments. The number of types/arguments is obtained |
9438 | // from the Sel.getNumArgs(). |
9439 | ObjCArgInfo *ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo, |
9440 | unsigned CNumArgs, // c-style args |
9441 | const ParsedAttributesView &AttrList, tok::ObjCKeywordKind MethodImplKind, |
9442 | bool isVariadic, bool MethodDefinition); |
9443 | |
9444 | ObjCMethodDecl *LookupMethodInQualifiedType(Selector Sel, |
9445 | const ObjCObjectPointerType *OPT, |
9446 | bool IsInstance); |
9447 | ObjCMethodDecl *LookupMethodInObjectType(Selector Sel, QualType Ty, |
9448 | bool IsInstance); |
9449 | |
9450 | bool CheckARCMethodDecl(ObjCMethodDecl *method); |
9451 | bool inferObjCARCLifetime(ValueDecl *decl); |
9452 | |
9453 | void deduceOpenCLAddressSpace(ValueDecl *decl); |
9454 | |
9455 | ExprResult |
9456 | HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, |
9457 | Expr *BaseExpr, |
9458 | SourceLocation OpLoc, |
9459 | DeclarationName MemberName, |
9460 | SourceLocation MemberLoc, |
9461 | SourceLocation SuperLoc, QualType SuperType, |
9462 | bool Super); |
9463 | |
9464 | ExprResult |
9465 | ActOnClassPropertyRefExpr(IdentifierInfo &receiverName, |
9466 | IdentifierInfo &propertyName, |
9467 | SourceLocation receiverNameLoc, |
9468 | SourceLocation propertyNameLoc); |
9469 | |
9470 | ObjCMethodDecl *tryCaptureObjCSelf(SourceLocation Loc); |
9471 | |
9472 | /// Describes the kind of message expression indicated by a message |
9473 | /// send that starts with an identifier. |
9474 | enum ObjCMessageKind { |
9475 | /// The message is sent to 'super'. |
9476 | ObjCSuperMessage, |
9477 | /// The message is an instance message. |
9478 | ObjCInstanceMessage, |
9479 | /// The message is a class message, and the identifier is a type |
9480 | /// name. |
9481 | ObjCClassMessage |
9482 | }; |
9483 | |
9484 | ObjCMessageKind getObjCMessageKind(Scope *S, |
9485 | IdentifierInfo *Name, |
9486 | SourceLocation NameLoc, |
9487 | bool IsSuper, |
9488 | bool HasTrailingDot, |
9489 | ParsedType &ReceiverType); |
9490 | |
9491 | ExprResult ActOnSuperMessage(Scope *S, SourceLocation SuperLoc, |
9492 | Selector Sel, |
9493 | SourceLocation LBracLoc, |
9494 | ArrayRef<SourceLocation> SelectorLocs, |
9495 | SourceLocation RBracLoc, |
9496 | MultiExprArg Args); |
9497 | |
9498 | ExprResult BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, |
9499 | QualType ReceiverType, |
9500 | SourceLocation SuperLoc, |
9501 | Selector Sel, |
9502 | ObjCMethodDecl *Method, |
9503 | SourceLocation LBracLoc, |
9504 | ArrayRef<SourceLocation> SelectorLocs, |
9505 | SourceLocation RBracLoc, |
9506 | MultiExprArg Args, |
9507 | bool isImplicit = false); |
9508 | |
9509 | ExprResult BuildClassMessageImplicit(QualType ReceiverType, |
9510 | bool isSuperReceiver, |
9511 | SourceLocation Loc, |
9512 | Selector Sel, |
9513 | ObjCMethodDecl *Method, |
9514 | MultiExprArg Args); |
9515 | |
9516 | ExprResult ActOnClassMessage(Scope *S, |
9517 | ParsedType Receiver, |
9518 | Selector Sel, |
9519 | SourceLocation LBracLoc, |
9520 | ArrayRef<SourceLocation> SelectorLocs, |
9521 | SourceLocation RBracLoc, |
9522 | MultiExprArg Args); |
9523 | |
9524 | ExprResult BuildInstanceMessage(Expr *Receiver, |
9525 | QualType ReceiverType, |
9526 | SourceLocation SuperLoc, |
9527 | Selector Sel, |
9528 | ObjCMethodDecl *Method, |
9529 | SourceLocation LBracLoc, |
9530 | ArrayRef<SourceLocation> SelectorLocs, |
9531 | SourceLocation RBracLoc, |
9532 | MultiExprArg Args, |
9533 | bool isImplicit = false); |
9534 | |
9535 | ExprResult BuildInstanceMessageImplicit(Expr *Receiver, |
9536 | QualType ReceiverType, |
9537 | SourceLocation Loc, |
9538 | Selector Sel, |
9539 | ObjCMethodDecl *Method, |
9540 | MultiExprArg Args); |
9541 | |
9542 | ExprResult ActOnInstanceMessage(Scope *S, |
9543 | Expr *Receiver, |
9544 | Selector Sel, |
9545 | SourceLocation LBracLoc, |
9546 | ArrayRef<SourceLocation> SelectorLocs, |
9547 | SourceLocation RBracLoc, |
9548 | MultiExprArg Args); |
9549 | |
9550 | ExprResult BuildObjCBridgedCast(SourceLocation LParenLoc, |
9551 | ObjCBridgeCastKind Kind, |
9552 | SourceLocation BridgeKeywordLoc, |
9553 | TypeSourceInfo *TSInfo, |
9554 | Expr *SubExpr); |
9555 | |
9556 | ExprResult ActOnObjCBridgedCast(Scope *S, |
9557 | SourceLocation LParenLoc, |
9558 | ObjCBridgeCastKind Kind, |
9559 | SourceLocation BridgeKeywordLoc, |
9560 | ParsedType Type, |
9561 | SourceLocation RParenLoc, |
9562 | Expr *SubExpr); |
9563 | |
9564 | void CheckTollFreeBridgeCast(QualType castType, Expr *castExpr); |
9565 | |
9566 | void CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr); |
9567 | |
9568 | bool CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr, |
9569 | CastKind &Kind); |
9570 | |
9571 | bool checkObjCBridgeRelatedComponents(SourceLocation Loc, |
9572 | QualType DestType, QualType SrcType, |
9573 | ObjCInterfaceDecl *&RelatedClass, |
9574 | ObjCMethodDecl *&ClassMethod, |
9575 | ObjCMethodDecl *&InstanceMethod, |
9576 | TypedefNameDecl *&TDNDecl, |
9577 | bool CfToNs, bool Diagnose = true); |
9578 | |
9579 | bool CheckObjCBridgeRelatedConversions(SourceLocation Loc, |
9580 | QualType DestType, QualType SrcType, |
9581 | Expr *&SrcExpr, bool Diagnose = true); |
9582 | |
9583 | bool CheckConversionToObjCLiteral(QualType DstType, Expr *&SrcExpr, |
9584 | bool Diagnose = true); |
9585 | |
9586 | bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall); |
9587 | |
9588 | /// Check whether the given new method is a valid override of the |
9589 | /// given overridden method, and set any properties that should be inherited. |
9590 | void CheckObjCMethodOverride(ObjCMethodDecl *NewMethod, |
9591 | const ObjCMethodDecl *Overridden); |
9592 | |
9593 | /// Describes the compatibility of a result type with its method. |
9594 | enum ResultTypeCompatibilityKind { |
9595 | RTC_Compatible, |
9596 | RTC_Incompatible, |
9597 | RTC_Unknown |
9598 | }; |
9599 | |
9600 | void CheckObjCMethodDirectOverrides(ObjCMethodDecl *method, |
9601 | ObjCMethodDecl *overridden); |
9602 | |
9603 | void CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod, |
9604 | ObjCInterfaceDecl *CurrentClass, |
9605 | ResultTypeCompatibilityKind RTC); |
9606 | |
9607 | enum PragmaOptionsAlignKind { |
9608 | POAK_Native, // #pragma options align=native |
9609 | POAK_Natural, // #pragma options align=natural |
9610 | POAK_Packed, // #pragma options align=packed |
9611 | POAK_Power, // #pragma options align=power |
9612 | POAK_Mac68k, // #pragma options align=mac68k |
9613 | POAK_Reset // #pragma options align=reset |
9614 | }; |
9615 | |
9616 | /// ActOnPragmaClangSection - Called on well formed \#pragma clang section |
9617 | void ActOnPragmaClangSection(SourceLocation PragmaLoc, |
9618 | PragmaClangSectionAction Action, |
9619 | PragmaClangSectionKind SecKind, StringRef SecName); |
9620 | |
9621 | /// ActOnPragmaOptionsAlign - Called on well formed \#pragma options align. |
9622 | void ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind, |
9623 | SourceLocation PragmaLoc); |
9624 | |
9625 | /// ActOnPragmaPack - Called on well formed \#pragma pack(...). |
9626 | void ActOnPragmaPack(SourceLocation PragmaLoc, PragmaMsStackAction Action, |
9627 | StringRef SlotLabel, Expr *Alignment); |
9628 | |
9629 | enum class PragmaPackDiagnoseKind { |
9630 | NonDefaultStateAtInclude, |
9631 | ChangedStateAtExit |
9632 | }; |
9633 | |
9634 | void DiagnoseNonDefaultPragmaPack(PragmaPackDiagnoseKind Kind, |
9635 | SourceLocation IncludeLoc); |
9636 | void DiagnoseUnterminatedPragmaPack(); |
9637 | |
9638 | /// ActOnPragmaMSStruct - Called on well formed \#pragma ms_struct [on|off]. |
9639 | void ActOnPragmaMSStruct(PragmaMSStructKind Kind); |
9640 | |
9641 | /// ActOnPragmaMSComment - Called on well formed |
9642 | /// \#pragma comment(kind, "arg"). |
9643 | void ActOnPragmaMSComment(SourceLocation CommentLoc, PragmaMSCommentKind Kind, |
9644 | StringRef Arg); |
9645 | |
9646 | /// ActOnPragmaMSPointersToMembers - called on well formed \#pragma |
9647 | /// pointers_to_members(representation method[, general purpose |
9648 | /// representation]). |
9649 | void ActOnPragmaMSPointersToMembers( |
9650 | LangOptions::PragmaMSPointersToMembersKind Kind, |
9651 | SourceLocation PragmaLoc); |
9652 | |
9653 | /// Called on well formed \#pragma vtordisp(). |
9654 | void ActOnPragmaMSVtorDisp(PragmaMsStackAction Action, |
9655 | SourceLocation PragmaLoc, |
9656 | MSVtorDispMode Value); |
9657 | |
9658 | enum PragmaSectionKind { |
9659 | PSK_DataSeg, |
9660 | PSK_BSSSeg, |
9661 | PSK_ConstSeg, |
9662 | PSK_CodeSeg, |
9663 | }; |
9664 | |
9665 | bool UnifySection(StringRef SectionName, |
9666 | int SectionFlags, |
9667 | DeclaratorDecl *TheDecl); |
9668 | bool UnifySection(StringRef SectionName, |
9669 | int SectionFlags, |
9670 | SourceLocation PragmaSectionLocation); |
9671 | |
9672 | /// Called on well formed \#pragma bss_seg/data_seg/const_seg/code_seg. |
9673 | void ActOnPragmaMSSeg(SourceLocation PragmaLocation, |
9674 | PragmaMsStackAction Action, |
9675 | llvm::StringRef StackSlotLabel, |
9676 | StringLiteral *SegmentName, |
9677 | llvm::StringRef PragmaName); |
9678 | |
9679 | /// Called on well formed \#pragma section(). |
9680 | void ActOnPragmaMSSection(SourceLocation PragmaLocation, |
9681 | int SectionFlags, StringLiteral *SegmentName); |
9682 | |
9683 | /// Called on well-formed \#pragma init_seg(). |
9684 | void ActOnPragmaMSInitSeg(SourceLocation PragmaLocation, |
9685 | StringLiteral *SegmentName); |
9686 | |
9687 | /// Called on #pragma clang __debug dump II |
9688 | void ActOnPragmaDump(Scope *S, SourceLocation Loc, IdentifierInfo *II); |
9689 | |
9690 | /// ActOnPragmaDetectMismatch - Call on well-formed \#pragma detect_mismatch |
9691 | void ActOnPragmaDetectMismatch(SourceLocation Loc, StringRef Name, |
9692 | StringRef Value); |
9693 | |
9694 | /// Are precise floating point semantics currently enabled? |
9695 | bool isPreciseFPEnabled() { |
9696 | return !CurFPFeatures.getAllowFPReassociate() && |
9697 | !CurFPFeatures.getNoSignedZero() && |
9698 | !CurFPFeatures.getAllowReciprocal() && |
9699 | !CurFPFeatures.getAllowApproxFunc(); |
9700 | } |
9701 | |
9702 | /// ActOnPragmaFloatControl - Call on well-formed \#pragma float_control |
9703 | void ActOnPragmaFloatControl(SourceLocation Loc, PragmaMsStackAction Action, |
9704 | PragmaFloatControlKind Value); |
9705 | |
9706 | /// ActOnPragmaUnused - Called on well-formed '\#pragma unused'. |
9707 | void ActOnPragmaUnused(const Token &Identifier, |
9708 | Scope *curScope, |
9709 | SourceLocation PragmaLoc); |
9710 | |
9711 | /// ActOnPragmaVisibility - Called on well formed \#pragma GCC visibility... . |
9712 | void ActOnPragmaVisibility(const IdentifierInfo* VisType, |
9713 | SourceLocation PragmaLoc); |
9714 | |
9715 | NamedDecl *DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II, |
9716 | SourceLocation Loc); |
9717 | void DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W); |
9718 | |
9719 | /// ActOnPragmaWeakID - Called on well formed \#pragma weak ident. |
9720 | void ActOnPragmaWeakID(IdentifierInfo* WeakName, |
9721 | SourceLocation PragmaLoc, |
9722 | SourceLocation WeakNameLoc); |
9723 | |
9724 | /// ActOnPragmaRedefineExtname - Called on well formed |
9725 | /// \#pragma redefine_extname oldname newname. |
9726 | void ActOnPragmaRedefineExtname(IdentifierInfo* WeakName, |
9727 | IdentifierInfo* AliasName, |
9728 | SourceLocation PragmaLoc, |
9729 | SourceLocation WeakNameLoc, |
9730 | SourceLocation AliasNameLoc); |
9731 | |
9732 | /// ActOnPragmaWeakAlias - Called on well formed \#pragma weak ident = ident. |
9733 | void ActOnPragmaWeakAlias(IdentifierInfo* WeakName, |
9734 | IdentifierInfo* AliasName, |
9735 | SourceLocation PragmaLoc, |
9736 | SourceLocation WeakNameLoc, |
9737 | SourceLocation AliasNameLoc); |
9738 | |
9739 | /// ActOnPragmaFPContract - Called on well formed |
9740 | /// \#pragma {STDC,OPENCL} FP_CONTRACT and |
9741 | /// \#pragma clang fp contract |
9742 | void ActOnPragmaFPContract(SourceLocation Loc, LangOptions::FPModeKind FPC); |
9743 | |
9744 | /// Called on well formed |
9745 | /// \#pragma clang fp reassociate |
9746 | void ActOnPragmaFPReassociate(SourceLocation Loc, bool IsEnabled); |
9747 | |
9748 | /// ActOnPragmaFenvAccess - Called on well formed |
9749 | /// \#pragma STDC FENV_ACCESS |
9750 | void ActOnPragmaFEnvAccess(SourceLocation Loc, bool IsEnabled); |
9751 | |
9752 | /// Called to set constant rounding mode for floating point operations. |
9753 | void setRoundingMode(SourceLocation Loc, llvm::RoundingMode); |
9754 | |
9755 | /// Called to set exception behavior for floating point operations. |
9756 | void setExceptionMode(SourceLocation Loc, LangOptions::FPExceptionModeKind); |
9757 | |
9758 | /// AddAlignmentAttributesForRecord - Adds any needed alignment attributes to |
9759 | /// a the record decl, to handle '\#pragma pack' and '\#pragma options align'. |
9760 | void AddAlignmentAttributesForRecord(RecordDecl *RD); |
9761 | |
9762 | /// AddMsStructLayoutForRecord - Adds ms_struct layout attribute to record. |
9763 | void AddMsStructLayoutForRecord(RecordDecl *RD); |
9764 | |
9765 | /// FreePackedContext - Deallocate and null out PackContext. |
9766 | void FreePackedContext(); |
9767 | |
9768 | /// PushNamespaceVisibilityAttr - Note that we've entered a |
9769 | /// namespace with a visibility attribute. |
9770 | void PushNamespaceVisibilityAttr(const VisibilityAttr *Attr, |
9771 | SourceLocation Loc); |
9772 | |
9773 | /// AddPushedVisibilityAttribute - If '\#pragma GCC visibility' was used, |
9774 | /// add an appropriate visibility attribute. |
9775 | void AddPushedVisibilityAttribute(Decl *RD); |
9776 | |
9777 | /// PopPragmaVisibility - Pop the top element of the visibility stack; used |
9778 | /// for '\#pragma GCC visibility' and visibility attributes on namespaces. |
9779 | void PopPragmaVisibility(bool IsNamespaceEnd, SourceLocation EndLoc); |
9780 | |
9781 | /// FreeVisContext - Deallocate and null out VisContext. |
9782 | void FreeVisContext(); |
9783 | |
9784 | /// AddCFAuditedAttribute - Check whether we're currently within |
9785 | /// '\#pragma clang arc_cf_code_audited' and, if so, consider adding |
9786 | /// the appropriate attribute. |
9787 | void AddCFAuditedAttribute(Decl *D); |
9788 | |
9789 | void ActOnPragmaAttributeAttribute(ParsedAttr &Attribute, |
9790 | SourceLocation PragmaLoc, |
9791 | attr::ParsedSubjectMatchRuleSet Rules); |
9792 | void ActOnPragmaAttributeEmptyPush(SourceLocation PragmaLoc, |
9793 | const IdentifierInfo *Namespace); |
9794 | |
9795 | /// Called on well-formed '\#pragma clang attribute pop'. |
9796 | void ActOnPragmaAttributePop(SourceLocation PragmaLoc, |
9797 | const IdentifierInfo *Namespace); |
9798 | |
9799 | /// Adds the attributes that have been specified using the |
9800 | /// '\#pragma clang attribute push' directives to the given declaration. |
9801 | void AddPragmaAttributes(Scope *S, Decl *D); |
9802 | |
9803 | void DiagnoseUnterminatedPragmaAttribute(); |
9804 | |
9805 | /// Called on well formed \#pragma clang optimize. |
9806 | void ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc); |
9807 | |
9808 | /// Get the location for the currently active "\#pragma clang optimize |
9809 | /// off". If this location is invalid, then the state of the pragma is "on". |
9810 | SourceLocation getOptimizeOffPragmaLocation() const { |
9811 | return OptimizeOffPragmaLocation; |
9812 | } |
9813 | |
9814 | /// Only called on function definitions; if there is a pragma in scope |
9815 | /// with the effect of a range-based optnone, consider marking the function |
9816 | /// with attribute optnone. |
9817 | void AddRangeBasedOptnone(FunctionDecl *FD); |
9818 | |
9819 | /// Adds the 'optnone' attribute to the function declaration if there |
9820 | /// are no conflicts; Loc represents the location causing the 'optnone' |
9821 | /// attribute to be added (usually because of a pragma). |
9822 | void AddOptnoneAttributeIfNoConflicts(FunctionDecl *FD, SourceLocation Loc); |
9823 | |
9824 | /// AddAlignedAttr - Adds an aligned attribute to a particular declaration. |
9825 | void AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E, |
9826 | bool IsPackExpansion); |
9827 | void AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, TypeSourceInfo *T, |
9828 | bool IsPackExpansion); |
9829 | |
9830 | /// AddAssumeAlignedAttr - Adds an assume_aligned attribute to a particular |
9831 | /// declaration. |
9832 | void AddAssumeAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E, |
9833 | Expr *OE); |
9834 | |
9835 | /// AddAllocAlignAttr - Adds an alloc_align attribute to a particular |
9836 | /// declaration. |
9837 | void AddAllocAlignAttr(Decl *D, const AttributeCommonInfo &CI, |
9838 | Expr *ParamExpr); |
9839 | |
9840 | /// AddAlignValueAttr - Adds an align_value attribute to a particular |
9841 | /// declaration. |
9842 | void AddAlignValueAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E); |
9843 | |
9844 | /// AddLaunchBoundsAttr - Adds a launch_bounds attribute to a particular |
9845 | /// declaration. |
9846 | void AddLaunchBoundsAttr(Decl *D, const AttributeCommonInfo &CI, |
9847 | Expr *MaxThreads, Expr *MinBlocks); |
9848 | |
9849 | /// AddModeAttr - Adds a mode attribute to a particular declaration. |
9850 | void AddModeAttr(Decl *D, const AttributeCommonInfo &CI, IdentifierInfo *Name, |
9851 | bool InInstantiation = false); |
9852 | |
9853 | void AddParameterABIAttr(Decl *D, const AttributeCommonInfo &CI, |
9854 | ParameterABI ABI); |
9855 | |
9856 | enum class RetainOwnershipKind {NS, CF, OS}; |
9857 | void AddXConsumedAttr(Decl *D, const AttributeCommonInfo &CI, |
9858 | RetainOwnershipKind K, bool IsTemplateInstantiation); |
9859 | |
9860 | /// addAMDGPUFlatWorkGroupSizeAttr - Adds an amdgpu_flat_work_group_size |
9861 | /// attribute to a particular declaration. |
9862 | void addAMDGPUFlatWorkGroupSizeAttr(Decl *D, const AttributeCommonInfo &CI, |
9863 | Expr *Min, Expr *Max); |
9864 | |
9865 | /// addAMDGPUWavePersEUAttr - Adds an amdgpu_waves_per_eu attribute to a |
9866 | /// particular declaration. |
9867 | void addAMDGPUWavesPerEUAttr(Decl *D, const AttributeCommonInfo &CI, |
9868 | Expr *Min, Expr *Max); |
9869 | |
9870 | bool checkNSReturnsRetainedReturnType(SourceLocation loc, QualType type); |
9871 | |
9872 | //===--------------------------------------------------------------------===// |
9873 | // C++ Coroutines TS |
9874 | // |
9875 | bool ActOnCoroutineBodyStart(Scope *S, SourceLocation KwLoc, |
9876 | StringRef Keyword); |
9877 | ExprResult ActOnCoawaitExpr(Scope *S, SourceLocation KwLoc, Expr *E); |
9878 | ExprResult ActOnCoyieldExpr(Scope *S, SourceLocation KwLoc, Expr *E); |
9879 | StmtResult ActOnCoreturnStmt(Scope *S, SourceLocation KwLoc, Expr *E); |
9880 | |
9881 | ExprResult BuildResolvedCoawaitExpr(SourceLocation KwLoc, Expr *E, |
9882 | bool IsImplicit = false); |
9883 | ExprResult BuildUnresolvedCoawaitExpr(SourceLocation KwLoc, Expr *E, |
9884 | UnresolvedLookupExpr* Lookup); |
9885 | ExprResult BuildCoyieldExpr(SourceLocation KwLoc, Expr *E); |
9886 | StmtResult BuildCoreturnStmt(SourceLocation KwLoc, Expr *E, |
9887 | bool IsImplicit = false); |
9888 | StmtResult BuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs); |
9889 | bool buildCoroutineParameterMoves(SourceLocation Loc); |
9890 | VarDecl *buildCoroutinePromise(SourceLocation Loc); |
9891 | void CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body); |
9892 | ClassTemplateDecl *lookupCoroutineTraits(SourceLocation KwLoc, |
9893 | SourceLocation FuncLoc); |
9894 | /// Check that the expression co_await promise.final_suspend() shall not be |
9895 | /// potentially-throwing. |
9896 | bool checkFinalSuspendNoThrow(const Stmt *FinalSuspend); |
9897 | |
9898 | //===--------------------------------------------------------------------===// |
9899 | // OpenCL extensions. |
9900 | // |
9901 | private: |
9902 | std::string CurrOpenCLExtension; |
9903 | /// Extensions required by an OpenCL type. |
9904 | llvm::DenseMap<const Type*, std::set<std::string>> OpenCLTypeExtMap; |
9905 | /// Extensions required by an OpenCL declaration. |
9906 | llvm::DenseMap<const Decl*, std::set<std::string>> OpenCLDeclExtMap; |
9907 | public: |
9908 | llvm::StringRef getCurrentOpenCLExtension() const { |
9909 | return CurrOpenCLExtension; |
9910 | } |
9911 | |
9912 | /// Check if a function declaration \p FD associates with any |
9913 | /// extensions present in OpenCLDeclExtMap and if so return the |
9914 | /// extension(s) name(s). |
9915 | std::string getOpenCLExtensionsFromDeclExtMap(FunctionDecl *FD); |
9916 | |
9917 | /// Check if a function type \p FT associates with any |
9918 | /// extensions present in OpenCLTypeExtMap and if so return the |
9919 | /// extension(s) name(s). |
9920 | std::string getOpenCLExtensionsFromTypeExtMap(FunctionType *FT); |
9921 | |
9922 | /// Find an extension in an appropriate extension map and return its name |
9923 | template<typename T, typename MapT> |
9924 | std::string getOpenCLExtensionsFromExtMap(T* FT, MapT &Map); |
9925 | |
9926 | void setCurrentOpenCLExtension(llvm::StringRef Ext) { |
9927 | CurrOpenCLExtension = std::string(Ext); |
9928 | } |
9929 | |
9930 | /// Set OpenCL extensions for a type which can only be used when these |
9931 | /// OpenCL extensions are enabled. If \p Exts is empty, do nothing. |
9932 | /// \param Exts A space separated list of OpenCL extensions. |
9933 | void setOpenCLExtensionForType(QualType T, llvm::StringRef Exts); |
9934 | |
9935 | /// Set OpenCL extensions for a declaration which can only be |
9936 | /// used when these OpenCL extensions are enabled. If \p Exts is empty, do |
9937 | /// nothing. |
9938 | /// \param Exts A space separated list of OpenCL extensions. |
9939 | void setOpenCLExtensionForDecl(Decl *FD, llvm::StringRef Exts); |
9940 | |
9941 | /// Set current OpenCL extensions for a type which can only be used |
9942 | /// when these OpenCL extensions are enabled. If current OpenCL extension is |
9943 | /// empty, do nothing. |
9944 | void setCurrentOpenCLExtensionForType(QualType T); |
9945 | |
9946 | /// Set current OpenCL extensions for a declaration which |
9947 | /// can only be used when these OpenCL extensions are enabled. If current |
9948 | /// OpenCL extension is empty, do nothing. |
9949 | void setCurrentOpenCLExtensionForDecl(Decl *FD); |
9950 | |
9951 | bool isOpenCLDisabledDecl(Decl *FD); |
9952 | |
9953 | /// Check if type \p T corresponding to declaration specifier \p DS |
9954 | /// is disabled due to required OpenCL extensions being disabled. If so, |
9955 | /// emit diagnostics. |
9956 | /// \return true if type is disabled. |
9957 | bool checkOpenCLDisabledTypeDeclSpec(const DeclSpec &DS, QualType T); |
9958 | |
9959 | /// Check if declaration \p D used by expression \p E |
9960 | /// is disabled due to required OpenCL extensions being disabled. If so, |
9961 | /// emit diagnostics. |
9962 | /// \return true if type is disabled. |
9963 | bool checkOpenCLDisabledDecl(const NamedDecl &D, const Expr &E); |
9964 | |
9965 | //===--------------------------------------------------------------------===// |
9966 | // OpenMP directives and clauses. |
9967 | // |
9968 | private: |
9969 | void *VarDataSharingAttributesStack; |
9970 | /// Number of nested '#pragma omp declare target' directives. |
9971 | SmallVector<SourceLocation, 4> DeclareTargetNesting; |
9972 | /// Initialization of data-sharing attributes stack. |
9973 | void InitDataSharingAttributesStack(); |
9974 | void DestroyDataSharingAttributesStack(); |
9975 | ExprResult |
9976 | VerifyPositiveIntegerConstantInClause(Expr *Op, OpenMPClauseKind CKind, |
9977 | bool StrictlyPositive = true); |
9978 | /// Returns OpenMP nesting level for current directive. |
9979 | unsigned getOpenMPNestingLevel() const; |
9980 | |
9981 | /// Adjusts the function scopes index for the target-based regions. |
9982 | void adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, |
9983 | unsigned Level) const; |
9984 | |
9985 | /// Returns the number of scopes associated with the construct on the given |
9986 | /// OpenMP level. |
9987 | int getNumberOfConstructScopes(unsigned Level) const; |
9988 | |
9989 | /// Push new OpenMP function region for non-capturing function. |
9990 | void pushOpenMPFunctionRegion(); |
9991 | |
9992 | /// Pop OpenMP function region for non-capturing function. |
9993 | void popOpenMPFunctionRegion(const sema::FunctionScopeInfo *OldFSI); |
9994 | |
9995 | /// Checks if a type or a declaration is disabled due to the owning extension |
9996 | /// being disabled, and emits diagnostic messages if it is disabled. |
9997 | /// \param D type or declaration to be checked. |
9998 | /// \param DiagLoc source location for the diagnostic message. |
9999 | /// \param DiagInfo information to be emitted for the diagnostic message. |
10000 | /// \param SrcRange source range of the declaration. |
10001 | /// \param Map maps type or declaration to the extensions. |
10002 | /// \param Selector selects diagnostic message: 0 for type and 1 for |
10003 | /// declaration. |
10004 | /// \return true if the type or declaration is disabled. |
10005 | template <typename T, typename DiagLocT, typename DiagInfoT, typename MapT> |
10006 | bool checkOpenCLDisabledTypeOrDecl(T D, DiagLocT DiagLoc, DiagInfoT DiagInfo, |
10007 | MapT &Map, unsigned Selector = 0, |
10008 | SourceRange SrcRange = SourceRange()); |
10009 | |
10010 | /// Helper to keep information about the current `omp begin/end declare |
10011 | /// variant` nesting. |
10012 | struct OMPDeclareVariantScope { |
10013 | /// The associated OpenMP context selector. |
10014 | OMPTraitInfo *TI; |
10015 | |
10016 | /// The associated OpenMP context selector mangling. |
10017 | std::string NameSuffix; |
10018 | |
10019 | OMPDeclareVariantScope(OMPTraitInfo &TI); |
10020 | }; |
10021 | |
10022 | /// The current `omp begin/end declare variant` scopes. |
10023 | SmallVector<OMPDeclareVariantScope, 4> OMPDeclareVariantScopes; |
10024 | |
10025 | /// The declarator \p D defines a function in the scope \p S which is nested |
10026 | /// in an `omp begin/end declare variant` scope. In this method we create a |
10027 | /// declaration for \p D and rename \p D according to the OpenMP context |
10028 | /// selector of the surrounding scope. |
10029 | FunctionDecl * |
10030 | ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S, |
10031 | Declarator &D); |
10032 | |
10033 | /// Register \p FD as specialization of \p BaseFD in the current `omp |
10034 | /// begin/end declare variant` scope. |
10035 | void ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( |
10036 | FunctionDecl *FD, FunctionDecl *BaseFD); |
10037 | |
10038 | public: |
10039 | |
10040 | /// Can we exit a scope at the moment. |
10041 | bool isInOpenMPDeclareVariantScope() { |
10042 | return !OMPDeclareVariantScopes.empty(); |
10043 | } |
10044 | |
10045 | /// Given the potential call expression \p Call, determine if there is a |
10046 | /// specialization via the OpenMP declare variant mechanism available. If |
10047 | /// there is, return the specialized call expression, otherwise return the |
10048 | /// original \p Call. |
10049 | ExprResult ActOnOpenMPCall(ExprResult Call, Scope *Scope, |
10050 | SourceLocation LParenLoc, MultiExprArg ArgExprs, |
10051 | SourceLocation RParenLoc, Expr *ExecConfig); |
10052 | |
10053 | /// Handle a `omp begin declare variant`. |
10054 | void ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, OMPTraitInfo &TI); |
10055 | |
10056 | /// Handle a `omp end declare variant`. |
10057 | void ActOnOpenMPEndDeclareVariant(); |
10058 | |
10059 | /// Checks if the variant/multiversion functions are compatible. |
10060 | bool areMultiversionVariantFunctionsCompatible( |
10061 | const FunctionDecl *OldFD, const FunctionDecl *NewFD, |
10062 | const PartialDiagnostic &NoProtoDiagID, |
10063 | const PartialDiagnosticAt &NoteCausedDiagIDAt, |
10064 | const PartialDiagnosticAt &NoSupportDiagIDAt, |
10065 | const PartialDiagnosticAt &DiffDiagIDAt, bool TemplatesSupported, |
10066 | bool ConstexprSupported, bool CLinkageMayDiffer); |
10067 | |
10068 | /// Function tries to capture lambda's captured variables in the OpenMP region |
10069 | /// before the original lambda is captured. |
10070 | void tryCaptureOpenMPLambdas(ValueDecl *V); |
10071 | |
10072 | /// Return true if the provided declaration \a VD should be captured by |
10073 | /// reference. |
10074 | /// \param Level Relative level of nested OpenMP construct for that the check |
10075 | /// is performed. |
10076 | /// \param OpenMPCaptureLevel Capture level within an OpenMP construct. |
10077 | bool isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, |
10078 | unsigned OpenMPCaptureLevel) const; |
10079 | |
10080 | /// Check if the specified variable is used in one of the private |
10081 | /// clauses (private, firstprivate, lastprivate, reduction etc.) in OpenMP |
10082 | /// constructs. |
10083 | VarDecl *isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo = false, |
10084 | unsigned StopAt = 0); |
10085 | ExprResult getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, |
10086 | ExprObjectKind OK, SourceLocation Loc); |
10087 | |
10088 | /// If the current region is a loop-based region, mark the start of the loop |
10089 | /// construct. |
10090 | void startOpenMPLoop(); |
10091 | |
10092 | /// If the current region is a range loop-based region, mark the start of the |
10093 | /// loop construct. |
10094 | void startOpenMPCXXRangeFor(); |
10095 | |
10096 | /// Check if the specified variable is used in 'private' clause. |
10097 | /// \param Level Relative level of nested OpenMP construct for that the check |
10098 | /// is performed. |
10099 | OpenMPClauseKind isOpenMPPrivateDecl(ValueDecl *D, unsigned Level, |
10100 | unsigned CapLevel) const; |
10101 | |
10102 | /// Sets OpenMP capture kind (OMPC_private, OMPC_firstprivate, OMPC_map etc.) |
10103 | /// for \p FD based on DSA for the provided corresponding captured declaration |
10104 | /// \p D. |
10105 | void setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, unsigned Level); |
10106 | |
10107 | /// Check if the specified variable is captured by 'target' directive. |
10108 | /// \param Level Relative level of nested OpenMP construct for that the check |
10109 | /// is performed. |
10110 | bool isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, |
10111 | unsigned CaptureLevel) const; |
10112 | |
10113 | /// Check if the specified global variable must be captured by outer capture |
10114 | /// regions. |
10115 | /// \param Level Relative level of nested OpenMP construct for that |
10116 | /// the check is performed. |
10117 | bool isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, |
10118 | unsigned CaptureLevel) const; |
10119 | |
10120 | ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc, |
10121 | Expr *Op); |
10122 | /// Called on start of new data sharing attribute block. |
10123 | void StartOpenMPDSABlock(OpenMPDirectiveKind K, |
10124 | const DeclarationNameInfo &DirName, Scope *CurScope, |
10125 | SourceLocation Loc); |
10126 | /// Start analysis of clauses. |
10127 | void StartOpenMPClause(OpenMPClauseKind K); |
10128 | /// End analysis of clauses. |
10129 | void EndOpenMPClause(); |
10130 | /// Called on end of data sharing attribute block. |
10131 | void EndOpenMPDSABlock(Stmt *CurDirective); |
10132 | |
10133 | /// Check if the current region is an OpenMP loop region and if it is, |
10134 | /// mark loop control variable, used in \p Init for loop initialization, as |
10135 | /// private by default. |
10136 | /// \param Init First part of the for loop. |
10137 | void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init); |
10138 | |
10139 | // OpenMP directives and clauses. |
10140 | /// Called on correct id-expression from the '#pragma omp |
10141 | /// threadprivate'. |
10142 | ExprResult ActOnOpenMPIdExpression(Scope *CurScope, CXXScopeSpec &ScopeSpec, |
10143 | const DeclarationNameInfo &Id, |
10144 | OpenMPDirectiveKind Kind); |
10145 | /// Called on well-formed '#pragma omp threadprivate'. |
10146 | DeclGroupPtrTy ActOnOpenMPThreadprivateDirective( |
10147 | SourceLocation Loc, |
10148 | ArrayRef<Expr *> VarList); |
10149 | /// Builds a new OpenMPThreadPrivateDecl and checks its correctness. |
10150 | OMPThreadPrivateDecl *CheckOMPThreadPrivateDecl(SourceLocation Loc, |
10151 | ArrayRef<Expr *> VarList); |
10152 | /// Called on well-formed '#pragma omp allocate'. |
10153 | DeclGroupPtrTy ActOnOpenMPAllocateDirective(SourceLocation Loc, |
10154 | ArrayRef<Expr *> VarList, |
10155 | ArrayRef<OMPClause *> Clauses, |
10156 | DeclContext *Owner = nullptr); |
10157 | /// Called on well-formed '#pragma omp requires'. |
10158 | DeclGroupPtrTy ActOnOpenMPRequiresDirective(SourceLocation Loc, |
10159 | ArrayRef<OMPClause *> ClauseList); |
10160 | /// Check restrictions on Requires directive |
10161 | OMPRequiresDecl *CheckOMPRequiresDecl(SourceLocation Loc, |
10162 | ArrayRef<OMPClause *> Clauses); |
10163 | /// Check if the specified type is allowed to be used in 'omp declare |
10164 | /// reduction' construct. |
10165 | QualType ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, |
10166 | TypeResult ParsedType); |
10167 | /// Called on start of '#pragma omp declare reduction'. |
10168 | DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveStart( |
10169 | Scope *S, DeclContext *DC, DeclarationName Name, |
10170 | ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, |
10171 | AccessSpecifier AS, Decl *PrevDeclInScope = nullptr); |
10172 | /// Initialize declare reduction construct initializer. |
10173 | void ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D); |
10174 | /// Finish current declare reduction construct initializer. |
10175 | void ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner); |
10176 | /// Initialize declare reduction construct initializer. |
10177 | /// \return omp_priv variable. |
10178 | VarDecl *ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D); |
10179 | /// Finish current declare reduction construct initializer. |
10180 | void ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, |
10181 | VarDecl *OmpPrivParm); |
10182 | /// Called at the end of '#pragma omp declare reduction'. |
10183 | DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd( |
10184 | Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid); |
10185 | |
10186 | /// Check variable declaration in 'omp declare mapper' construct. |
10187 | TypeResult ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D); |
10188 | /// Check if the specified type is allowed to be used in 'omp declare |
10189 | /// mapper' construct. |
10190 | QualType ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, |
10191 | TypeResult ParsedType); |
10192 | /// Called on start of '#pragma omp declare mapper'. |
10193 | DeclGroupPtrTy ActOnOpenMPDeclareMapperDirective( |
10194 | Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, |
10195 | SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, |
10196 | Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, |
10197 | Decl *PrevDeclInScope = nullptr); |
10198 | /// Build the mapper variable of '#pragma omp declare mapper'. |
10199 | ExprResult ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, |
10200 | QualType MapperType, |
10201 | SourceLocation StartLoc, |
10202 | DeclarationName VN); |
10203 | bool isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const; |
10204 | const ValueDecl *getOpenMPDeclareMapperVarName() const; |
10205 | |
10206 | /// Called on the start of target region i.e. '#pragma omp declare target'. |
10207 | bool ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc); |
10208 | /// Called at the end of target region i.e. '#pragme omp end declare target'. |
10209 | void ActOnFinishOpenMPDeclareTargetDirective(); |
10210 | /// Searches for the provided declaration name for OpenMP declare target |
10211 | /// directive. |
10212 | NamedDecl * |
10213 | lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, |
10214 | const DeclarationNameInfo &Id, |
10215 | NamedDeclSetType &SameDirectiveDecls); |
10216 | /// Called on correct id-expression from the '#pragma omp declare target'. |
10217 | void ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc, |
10218 | OMPDeclareTargetDeclAttr::MapTypeTy MT, |
10219 | OMPDeclareTargetDeclAttr::DevTypeTy DT); |
10220 | /// Check declaration inside target region. |
10221 | void |
10222 | checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, |
10223 | SourceLocation IdLoc = SourceLocation()); |
10224 | /// Finishes analysis of the deferred functions calls that may be declared as |
10225 | /// host/nohost during device/host compilation. |
10226 | void finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, |
10227 | const FunctionDecl *Callee, |
10228 | SourceLocation Loc); |
10229 | /// Return true inside OpenMP declare target region. |
10230 | bool isInOpenMPDeclareTargetContext() const { |
10231 | return !DeclareTargetNesting.empty(); |
10232 | } |
10233 | /// Return true inside OpenMP target region. |
10234 | bool isInOpenMPTargetExecutionDirective() const; |
10235 | |
10236 | /// Return the number of captured regions created for an OpenMP directive. |
10237 | static int getOpenMPCaptureLevels(OpenMPDirectiveKind Kind); |
10238 | |
10239 | /// Initialization of captured region for OpenMP region. |
10240 | void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope); |
10241 | /// End of OpenMP region. |
10242 | /// |
10243 | /// \param S Statement associated with the current OpenMP region. |
10244 | /// \param Clauses List of clauses for the current OpenMP region. |
10245 | /// |
10246 | /// \returns Statement for finished OpenMP region. |
10247 | StmtResult ActOnOpenMPRegionEnd(StmtResult S, ArrayRef<OMPClause *> Clauses); |
10248 | StmtResult ActOnOpenMPExecutableDirective( |
10249 | OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, |
10250 | OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, |
10251 | Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc); |
10252 | /// Called on well-formed '\#pragma omp parallel' after parsing |
10253 | /// of the associated statement. |
10254 | StmtResult ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, |
10255 | Stmt *AStmt, |
10256 | SourceLocation StartLoc, |
10257 | SourceLocation EndLoc); |
10258 | using VarsWithInheritedDSAType = |
10259 | llvm::SmallDenseMap<const ValueDecl *, const Expr *, 4>; |
10260 | /// Called on well-formed '\#pragma omp simd' after parsing |
10261 | /// of the associated statement. |
10262 | StmtResult |
10263 | ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, |
10264 | SourceLocation StartLoc, SourceLocation EndLoc, |
10265 | VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10266 | /// Called on well-formed '\#pragma omp for' after parsing |
10267 | /// of the associated statement. |
10268 | StmtResult |
10269 | ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, |
10270 | SourceLocation StartLoc, SourceLocation EndLoc, |
10271 | VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10272 | /// Called on well-formed '\#pragma omp for simd' after parsing |
10273 | /// of the associated statement. |
10274 | StmtResult |
10275 | ActOnOpenMPForSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, |
10276 | SourceLocation StartLoc, SourceLocation EndLoc, |
10277 | VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10278 | /// Called on well-formed '\#pragma omp sections' after parsing |
10279 | /// of the associated statement. |
10280 | StmtResult ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, |
10281 | Stmt *AStmt, SourceLocation StartLoc, |
10282 | SourceLocation EndLoc); |
10283 | /// Called on well-formed '\#pragma omp section' after parsing of the |
10284 | /// associated statement. |
10285 | StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc, |
10286 | SourceLocation EndLoc); |
10287 | /// Called on well-formed '\#pragma omp single' after parsing of the |
10288 | /// associated statement. |
10289 | StmtResult ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, |
10290 | Stmt *AStmt, SourceLocation StartLoc, |
10291 | SourceLocation EndLoc); |
10292 | /// Called on well-formed '\#pragma omp master' after parsing of the |
10293 | /// associated statement. |
10294 | StmtResult ActOnOpenMPMasterDirective(Stmt *AStmt, SourceLocation StartLoc, |
10295 | SourceLocation EndLoc); |
10296 | /// Called on well-formed '\#pragma omp critical' after parsing of the |
10297 | /// associated statement. |
10298 | StmtResult ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName, |
10299 | ArrayRef<OMPClause *> Clauses, |
10300 | Stmt *AStmt, SourceLocation StartLoc, |
10301 | SourceLocation EndLoc); |
10302 | /// Called on well-formed '\#pragma omp parallel for' after parsing |
10303 | /// of the associated statement. |
10304 | StmtResult ActOnOpenMPParallelForDirective( |
10305 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10306 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10307 | /// Called on well-formed '\#pragma omp parallel for simd' after |
10308 | /// parsing of the associated statement. |
10309 | StmtResult ActOnOpenMPParallelForSimdDirective( |
10310 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10311 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10312 | /// Called on well-formed '\#pragma omp parallel master' after |
10313 | /// parsing of the associated statement. |
10314 | StmtResult ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, |
10315 | Stmt *AStmt, |
10316 | SourceLocation StartLoc, |
10317 | SourceLocation EndLoc); |
10318 | /// Called on well-formed '\#pragma omp parallel sections' after |
10319 | /// parsing of the associated statement. |
10320 | StmtResult ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, |
10321 | Stmt *AStmt, |
10322 | SourceLocation StartLoc, |
10323 | SourceLocation EndLoc); |
10324 | /// Called on well-formed '\#pragma omp task' after parsing of the |
10325 | /// associated statement. |
10326 | StmtResult ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, |
10327 | Stmt *AStmt, SourceLocation StartLoc, |
10328 | SourceLocation EndLoc); |
10329 | /// Called on well-formed '\#pragma omp taskyield'. |
10330 | StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, |
10331 | SourceLocation EndLoc); |
10332 | /// Called on well-formed '\#pragma omp barrier'. |
10333 | StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc, |
10334 | SourceLocation EndLoc); |
10335 | /// Called on well-formed '\#pragma omp taskwait'. |
10336 | StmtResult ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, |
10337 | SourceLocation EndLoc); |
10338 | /// Called on well-formed '\#pragma omp taskgroup'. |
10339 | StmtResult ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, |
10340 | Stmt *AStmt, SourceLocation StartLoc, |
10341 | SourceLocation EndLoc); |
10342 | /// Called on well-formed '\#pragma omp flush'. |
10343 | StmtResult ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, |
10344 | SourceLocation StartLoc, |
10345 | SourceLocation EndLoc); |
10346 | /// Called on well-formed '\#pragma omp depobj'. |
10347 | StmtResult ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, |
10348 | SourceLocation StartLoc, |
10349 | SourceLocation EndLoc); |
10350 | /// Called on well-formed '\#pragma omp scan'. |
10351 | StmtResult ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, |
10352 | SourceLocation StartLoc, |
10353 | SourceLocation EndLoc); |
10354 | /// Called on well-formed '\#pragma omp ordered' after parsing of the |
10355 | /// associated statement. |
10356 | StmtResult ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, |
10357 | Stmt *AStmt, SourceLocation StartLoc, |
10358 | SourceLocation EndLoc); |
10359 | /// Called on well-formed '\#pragma omp atomic' after parsing of the |
10360 | /// associated statement. |
10361 | StmtResult ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, |
10362 | Stmt *AStmt, SourceLocation StartLoc, |
10363 | SourceLocation EndLoc); |
10364 | /// Called on well-formed '\#pragma omp target' after parsing of the |
10365 | /// associated statement. |
10366 | StmtResult ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, |
10367 | Stmt *AStmt, SourceLocation StartLoc, |
10368 | SourceLocation EndLoc); |
10369 | /// Called on well-formed '\#pragma omp target data' after parsing of |
10370 | /// the associated statement. |
10371 | StmtResult ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, |
10372 | Stmt *AStmt, SourceLocation StartLoc, |
10373 | SourceLocation EndLoc); |
10374 | /// Called on well-formed '\#pragma omp target enter data' after |
10375 | /// parsing of the associated statement. |
10376 | StmtResult ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, |
10377 | SourceLocation StartLoc, |
10378 | SourceLocation EndLoc, |
10379 | Stmt *AStmt); |
10380 | /// Called on well-formed '\#pragma omp target exit data' after |
10381 | /// parsing of the associated statement. |
10382 | StmtResult ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, |
10383 | SourceLocation StartLoc, |
10384 | SourceLocation EndLoc, |
10385 | Stmt *AStmt); |
10386 | /// Called on well-formed '\#pragma omp target parallel' after |
10387 | /// parsing of the associated statement. |
10388 | StmtResult ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, |
10389 | Stmt *AStmt, |
10390 | SourceLocation StartLoc, |
10391 | SourceLocation EndLoc); |
10392 | /// Called on well-formed '\#pragma omp target parallel for' after |
10393 | /// parsing of the associated statement. |
10394 | StmtResult ActOnOpenMPTargetParallelForDirective( |
10395 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10396 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10397 | /// Called on well-formed '\#pragma omp teams' after parsing of the |
10398 | /// associated statement. |
10399 | StmtResult ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, |
10400 | Stmt *AStmt, SourceLocation StartLoc, |
10401 | SourceLocation EndLoc); |
10402 | /// Called on well-formed '\#pragma omp cancellation point'. |
10403 | StmtResult |
10404 | ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, |
10405 | SourceLocation EndLoc, |
10406 | OpenMPDirectiveKind CancelRegion); |
10407 | /// Called on well-formed '\#pragma omp cancel'. |
10408 | StmtResult ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, |
10409 | SourceLocation StartLoc, |
10410 | SourceLocation EndLoc, |
10411 | OpenMPDirectiveKind CancelRegion); |
10412 | /// Called on well-formed '\#pragma omp taskloop' after parsing of the |
10413 | /// associated statement. |
10414 | StmtResult |
10415 | ActOnOpenMPTaskLoopDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, |
10416 | SourceLocation StartLoc, SourceLocation EndLoc, |
10417 | VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10418 | /// Called on well-formed '\#pragma omp taskloop simd' after parsing of |
10419 | /// the associated statement. |
10420 | StmtResult ActOnOpenMPTaskLoopSimdDirective( |
10421 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10422 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10423 | /// Called on well-formed '\#pragma omp master taskloop' after parsing of the |
10424 | /// associated statement. |
10425 | StmtResult ActOnOpenMPMasterTaskLoopDirective( |
10426 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10427 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10428 | /// Called on well-formed '\#pragma omp master taskloop simd' after parsing of |
10429 | /// the associated statement. |
10430 | StmtResult ActOnOpenMPMasterTaskLoopSimdDirective( |
10431 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10432 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10433 | /// Called on well-formed '\#pragma omp parallel master taskloop' after |
10434 | /// parsing of the associated statement. |
10435 | StmtResult ActOnOpenMPParallelMasterTaskLoopDirective( |
10436 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10437 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10438 | /// Called on well-formed '\#pragma omp parallel master taskloop simd' after |
10439 | /// parsing of the associated statement. |
10440 | StmtResult ActOnOpenMPParallelMasterTaskLoopSimdDirective( |
10441 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10442 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10443 | /// Called on well-formed '\#pragma omp distribute' after parsing |
10444 | /// of the associated statement. |
10445 | StmtResult |
10446 | ActOnOpenMPDistributeDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, |
10447 | SourceLocation StartLoc, SourceLocation EndLoc, |
10448 | VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10449 | /// Called on well-formed '\#pragma omp target update'. |
10450 | StmtResult ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, |
10451 | SourceLocation StartLoc, |
10452 | SourceLocation EndLoc, |
10453 | Stmt *AStmt); |
10454 | /// Called on well-formed '\#pragma omp distribute parallel for' after |
10455 | /// parsing of the associated statement. |
10456 | StmtResult ActOnOpenMPDistributeParallelForDirective( |
10457 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10458 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10459 | /// Called on well-formed '\#pragma omp distribute parallel for simd' |
10460 | /// after parsing of the associated statement. |
10461 | StmtResult ActOnOpenMPDistributeParallelForSimdDirective( |
10462 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10463 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10464 | /// Called on well-formed '\#pragma omp distribute simd' after |
10465 | /// parsing of the associated statement. |
10466 | StmtResult ActOnOpenMPDistributeSimdDirective( |
10467 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10468 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10469 | /// Called on well-formed '\#pragma omp target parallel for simd' after |
10470 | /// parsing of the associated statement. |
10471 | StmtResult ActOnOpenMPTargetParallelForSimdDirective( |
10472 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10473 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10474 | /// Called on well-formed '\#pragma omp target simd' after parsing of |
10475 | /// the associated statement. |
10476 | StmtResult |
10477 | ActOnOpenMPTargetSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, |
10478 | SourceLocation StartLoc, SourceLocation EndLoc, |
10479 | VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10480 | /// Called on well-formed '\#pragma omp teams distribute' after parsing of |
10481 | /// the associated statement. |
10482 | StmtResult ActOnOpenMPTeamsDistributeDirective( |
10483 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10484 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10485 | /// Called on well-formed '\#pragma omp teams distribute simd' after parsing |
10486 | /// of the associated statement. |
10487 | StmtResult ActOnOpenMPTeamsDistributeSimdDirective( |
10488 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10489 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10490 | /// Called on well-formed '\#pragma omp teams distribute parallel for simd' |
10491 | /// after parsing of the associated statement. |
10492 | StmtResult ActOnOpenMPTeamsDistributeParallelForSimdDirective( |
10493 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10494 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10495 | /// Called on well-formed '\#pragma omp teams distribute parallel for' |
10496 | /// after parsing of the associated statement. |
10497 | StmtResult ActOnOpenMPTeamsDistributeParallelForDirective( |
10498 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10499 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10500 | /// Called on well-formed '\#pragma omp target teams' after parsing of the |
10501 | /// associated statement. |
10502 | StmtResult ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, |
10503 | Stmt *AStmt, |
10504 | SourceLocation StartLoc, |
10505 | SourceLocation EndLoc); |
10506 | /// Called on well-formed '\#pragma omp target teams distribute' after parsing |
10507 | /// of the associated statement. |
10508 | StmtResult ActOnOpenMPTargetTeamsDistributeDirective( |
10509 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10510 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10511 | /// Called on well-formed '\#pragma omp target teams distribute parallel for' |
10512 | /// after parsing of the associated statement. |
10513 | StmtResult ActOnOpenMPTargetTeamsDistributeParallelForDirective( |
10514 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10515 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10516 | /// Called on well-formed '\#pragma omp target teams distribute parallel for |
10517 | /// simd' after parsing of the associated statement. |
10518 | StmtResult ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( |
10519 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10520 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10521 | /// Called on well-formed '\#pragma omp target teams distribute simd' after |
10522 | /// parsing of the associated statement. |
10523 | StmtResult ActOnOpenMPTargetTeamsDistributeSimdDirective( |
10524 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10525 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10526 | |
10527 | /// Checks correctness of linear modifiers. |
10528 | bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, |
10529 | SourceLocation LinLoc); |
10530 | /// Checks that the specified declaration matches requirements for the linear |
10531 | /// decls. |
10532 | bool CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, |
10533 | OpenMPLinearClauseKind LinKind, QualType Type, |
10534 | bool IsDeclareSimd = false); |
10535 | |
10536 | /// Called on well-formed '\#pragma omp declare simd' after parsing of |
10537 | /// the associated method/function. |
10538 | DeclGroupPtrTy ActOnOpenMPDeclareSimdDirective( |
10539 | DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, |
10540 | Expr *Simdlen, ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, |
10541 | ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, |
10542 | ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR); |
10543 | |
10544 | /// Checks '\#pragma omp declare variant' variant function and original |
10545 | /// functions after parsing of the associated method/function. |
10546 | /// \param DG Function declaration to which declare variant directive is |
10547 | /// applied to. |
10548 | /// \param VariantRef Expression that references the variant function, which |
10549 | /// must be used instead of the original one, specified in \p DG. |
10550 | /// \param TI The trait info object representing the match clause. |
10551 | /// \returns None, if the function/variant function are not compatible with |
10552 | /// the pragma, pair of original function/variant ref expression otherwise. |
10553 | Optional<std::pair<FunctionDecl *, Expr *>> |
10554 | checkOpenMPDeclareVariantFunction(DeclGroupPtrTy DG, Expr *VariantRef, |
10555 | OMPTraitInfo &TI, SourceRange SR); |
10556 | |
10557 | /// Called on well-formed '\#pragma omp declare variant' after parsing of |
10558 | /// the associated method/function. |
10559 | /// \param FD Function declaration to which declare variant directive is |
10560 | /// applied to. |
10561 | /// \param VariantRef Expression that references the variant function, which |
10562 | /// must be used instead of the original one, specified in \p DG. |
10563 | /// \param TI The context traits associated with the function variant. |
10564 | void ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, Expr *VariantRef, |
10565 | OMPTraitInfo &TI, SourceRange SR); |
10566 | |
10567 | OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, |
10568 | Expr *Expr, |
10569 | SourceLocation StartLoc, |
10570 | SourceLocation LParenLoc, |
10571 | SourceLocation EndLoc); |
10572 | /// Called on well-formed 'allocator' clause. |
10573 | OMPClause *ActOnOpenMPAllocatorClause(Expr *Allocator, |
10574 | SourceLocation StartLoc, |
10575 | SourceLocation LParenLoc, |
10576 | SourceLocation EndLoc); |
10577 | /// Called on well-formed 'if' clause. |
10578 | OMPClause *ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, |
10579 | Expr *Condition, SourceLocation StartLoc, |
10580 | SourceLocation LParenLoc, |
10581 | SourceLocation NameModifierLoc, |
10582 | SourceLocation ColonLoc, |
10583 | SourceLocation EndLoc); |
10584 | /// Called on well-formed 'final' clause. |
10585 | OMPClause *ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc, |
10586 | SourceLocation LParenLoc, |
10587 | SourceLocation EndLoc); |
10588 | /// Called on well-formed 'num_threads' clause. |
10589 | OMPClause *ActOnOpenMPNumThreadsClause(Expr *NumThreads, |
10590 | SourceLocation StartLoc, |
10591 | SourceLocation LParenLoc, |
10592 | SourceLocation EndLoc); |
10593 | /// Called on well-formed 'safelen' clause. |
10594 | OMPClause *ActOnOpenMPSafelenClause(Expr *Length, |
10595 | SourceLocation StartLoc, |
10596 | SourceLocation LParenLoc, |
10597 | SourceLocation EndLoc); |
10598 | /// Called on well-formed 'simdlen' clause. |
10599 | OMPClause *ActOnOpenMPSimdlenClause(Expr *Length, SourceLocation StartLoc, |
10600 | SourceLocation LParenLoc, |
10601 | SourceLocation EndLoc); |
10602 | /// Called on well-formed 'collapse' clause. |
10603 | OMPClause *ActOnOpenMPCollapseClause(Expr *NumForLoops, |
10604 | SourceLocation StartLoc, |
10605 | SourceLocation LParenLoc, |
10606 | SourceLocation EndLoc); |
10607 | /// Called on well-formed 'ordered' clause. |
10608 | OMPClause * |
10609 | ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc, |
10610 | SourceLocation LParenLoc = SourceLocation(), |
10611 | Expr *NumForLoops = nullptr); |
10612 | /// Called on well-formed 'grainsize' clause. |
10613 | OMPClause *ActOnOpenMPGrainsizeClause(Expr *Size, SourceLocation StartLoc, |
10614 | SourceLocation LParenLoc, |
10615 | SourceLocation EndLoc); |
10616 | /// Called on well-formed 'num_tasks' clause. |
10617 | OMPClause *ActOnOpenMPNumTasksClause(Expr *NumTasks, SourceLocation StartLoc, |
10618 | SourceLocation LParenLoc, |
10619 | SourceLocation EndLoc); |
10620 | /// Called on well-formed 'hint' clause. |
10621 | OMPClause *ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, |
10622 | SourceLocation LParenLoc, |
10623 | SourceLocation EndLoc); |
10624 | /// Called on well-formed 'detach' clause. |
10625 | OMPClause *ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, |
10626 | SourceLocation LParenLoc, |
10627 | SourceLocation EndLoc); |
10628 | |
10629 | OMPClause *ActOnOpenMPSimpleClause(OpenMPClauseKind Kind, |
10630 | unsigned Argument, |
10631 | SourceLocation ArgumentLoc, |
10632 | SourceLocation StartLoc, |
10633 | SourceLocation LParenLoc, |
10634 | SourceLocation EndLoc); |
10635 | /// Called on well-formed 'default' clause. |
10636 | OMPClause *ActOnOpenMPDefaultClause(llvm::omp::DefaultKind Kind, |
10637 | SourceLocation KindLoc, |
10638 | SourceLocation StartLoc, |
10639 | SourceLocation LParenLoc, |
10640 | SourceLocation EndLoc); |
10641 | /// Called on well-formed 'proc_bind' clause. |
10642 | OMPClause *ActOnOpenMPProcBindClause(llvm::omp::ProcBindKind Kind, |
10643 | SourceLocation KindLoc, |
10644 | SourceLocation StartLoc, |
10645 | SourceLocation LParenLoc, |
10646 | SourceLocation EndLoc); |
10647 | /// Called on well-formed 'order' clause. |
10648 | OMPClause *ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, |
10649 | SourceLocation KindLoc, |
10650 | SourceLocation StartLoc, |
10651 | SourceLocation LParenLoc, |
10652 | SourceLocation EndLoc); |
10653 | /// Called on well-formed 'update' clause. |
10654 | OMPClause *ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, |
10655 | SourceLocation KindLoc, |
10656 | SourceLocation StartLoc, |
10657 | SourceLocation LParenLoc, |
10658 | SourceLocation EndLoc); |
10659 | |
10660 | OMPClause *ActOnOpenMPSingleExprWithArgClause( |
10661 | OpenMPClauseKind Kind, ArrayRef<unsigned> Arguments, Expr *Expr, |
10662 | SourceLocation StartLoc, SourceLocation LParenLoc, |
10663 | ArrayRef<SourceLocation> ArgumentsLoc, SourceLocation DelimLoc, |
10664 | SourceLocation EndLoc); |
10665 | /// Called on well-formed 'schedule' clause. |
10666 | OMPClause *ActOnOpenMPScheduleClause( |
10667 | OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, |
10668 | OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, |
10669 | SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, |
10670 | SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc); |
10671 | |
10672 | OMPClause *ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, |
10673 | SourceLocation EndLoc); |
10674 | /// Called on well-formed 'nowait' clause. |
10675 | OMPClause *ActOnOpenMPNowaitClause(SourceLocation StartLoc, |
10676 | SourceLocation EndLoc); |
10677 | /// Called on well-formed 'untied' clause. |
10678 | OMPClause *ActOnOpenMPUntiedClause(SourceLocation StartLoc, |
10679 | SourceLocation EndLoc); |
10680 | /// Called on well-formed 'mergeable' clause. |
10681 | OMPClause *ActOnOpenMPMergeableClause(SourceLocation StartLoc, |
10682 | SourceLocation EndLoc); |
10683 | /// Called on well-formed 'read' clause. |
10684 | OMPClause *ActOnOpenMPReadClause(SourceLocation StartLoc, |
10685 | SourceLocation EndLoc); |
10686 | /// Called on well-formed 'write' clause. |
10687 | OMPClause *ActOnOpenMPWriteClause(SourceLocation StartLoc, |
10688 | SourceLocation EndLoc); |
10689 | /// Called on well-formed 'update' clause. |
10690 | OMPClause *ActOnOpenMPUpdateClause(SourceLocation StartLoc, |
10691 | SourceLocation EndLoc); |
10692 | /// Called on well-formed 'capture' clause. |
10693 | OMPClause *ActOnOpenMPCaptureClause(SourceLocation StartLoc, |
10694 | SourceLocation EndLoc); |
10695 | /// Called on well-formed 'seq_cst' clause. |
10696 | OMPClause *ActOnOpenMPSeqCstClause(SourceLocation StartLoc, |
10697 | SourceLocation EndLoc); |
10698 | /// Called on well-formed 'acq_rel' clause. |
10699 | OMPClause *ActOnOpenMPAcqRelClause(SourceLocation StartLoc, |
10700 | SourceLocation EndLoc); |
10701 | /// Called on well-formed 'acquire' clause. |
10702 | OMPClause *ActOnOpenMPAcquireClause(SourceLocation StartLoc, |
10703 | SourceLocation EndLoc); |
10704 | /// Called on well-formed 'release' clause. |
10705 | OMPClause *ActOnOpenMPReleaseClause(SourceLocation StartLoc, |
10706 | SourceLocation EndLoc); |
10707 | /// Called on well-formed 'relaxed' clause. |
10708 | OMPClause *ActOnOpenMPRelaxedClause(SourceLocation StartLoc, |
10709 | SourceLocation EndLoc); |
10710 | /// Called on well-formed 'destroy' clause. |
10711 | OMPClause *ActOnOpenMPDestroyClause(SourceLocation StartLoc, |
10712 | SourceLocation EndLoc); |
10713 | /// Called on well-formed 'threads' clause. |
10714 | OMPClause *ActOnOpenMPThreadsClause(SourceLocation StartLoc, |
10715 | SourceLocation EndLoc); |
10716 | /// Called on well-formed 'simd' clause. |
10717 | OMPClause *ActOnOpenMPSIMDClause(SourceLocation StartLoc, |
10718 | SourceLocation EndLoc); |
10719 | /// Called on well-formed 'nogroup' clause. |
10720 | OMPClause *ActOnOpenMPNogroupClause(SourceLocation StartLoc, |
10721 | SourceLocation EndLoc); |
10722 | /// Called on well-formed 'unified_address' clause. |
10723 | OMPClause *ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, |
10724 | SourceLocation EndLoc); |
10725 | |
10726 | /// Called on well-formed 'unified_address' clause. |
10727 | OMPClause *ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, |
10728 | SourceLocation EndLoc); |
10729 | |
10730 | /// Called on well-formed 'reverse_offload' clause. |
10731 | OMPClause *ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, |
10732 | SourceLocation EndLoc); |
10733 | |
10734 | /// Called on well-formed 'dynamic_allocators' clause. |
10735 | OMPClause *ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, |
10736 | SourceLocation EndLoc); |
10737 | |
10738 | /// Called on well-formed 'atomic_default_mem_order' clause. |
10739 | OMPClause *ActOnOpenMPAtomicDefaultMemOrderClause( |
10740 | OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindLoc, |
10741 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc); |
10742 | |
10743 | OMPClause *ActOnOpenMPVarListClause( |
10744 | OpenMPClauseKind Kind, ArrayRef<Expr *> Vars, Expr *DepModOrTailExpr, |
10745 | const OMPVarListLocTy &Locs, SourceLocation ColonLoc, |
10746 | CXXScopeSpec &ReductionOrMapperIdScopeSpec, |
10747 | DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, |
10748 | ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, |
10749 | ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, |
10750 | SourceLocation ExtraModifierLoc, |
10751 | ArrayRef<OpenMPMotionModifierKind> MotionModifiers, |
10752 | ArrayRef<SourceLocation> MotionModifiersLoc); |
10753 | /// Called on well-formed 'inclusive' clause. |
10754 | OMPClause *ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, |
10755 | SourceLocation StartLoc, |
10756 | SourceLocation LParenLoc, |
10757 | SourceLocation EndLoc); |
10758 | /// Called on well-formed 'exclusive' clause. |
10759 | OMPClause *ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList, |
10760 | SourceLocation StartLoc, |
10761 | SourceLocation LParenLoc, |
10762 | SourceLocation EndLoc); |
10763 | /// Called on well-formed 'allocate' clause. |
10764 | OMPClause * |
10765 | ActOnOpenMPAllocateClause(Expr *Allocator, ArrayRef<Expr *> VarList, |
10766 | SourceLocation StartLoc, SourceLocation ColonLoc, |
10767 | SourceLocation LParenLoc, SourceLocation EndLoc); |
10768 | /// Called on well-formed 'private' clause. |
10769 | OMPClause *ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, |
10770 | SourceLocation StartLoc, |
10771 | SourceLocation LParenLoc, |
10772 | SourceLocation EndLoc); |
10773 | /// Called on well-formed 'firstprivate' clause. |
10774 | OMPClause *ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, |
10775 | SourceLocation StartLoc, |
10776 | SourceLocation LParenLoc, |
10777 | SourceLocation EndLoc); |
10778 | /// Called on well-formed 'lastprivate' clause. |
10779 | OMPClause *ActOnOpenMPLastprivateClause( |
10780 | ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, |
10781 | SourceLocation LPKindLoc, SourceLocation ColonLoc, |
10782 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc); |
10783 | /// Called on well-formed 'shared' clause. |
10784 | OMPClause *ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, |
10785 | SourceLocation StartLoc, |
10786 | SourceLocation LParenLoc, |
10787 | SourceLocation EndLoc); |
10788 | /// Called on well-formed 'reduction' clause. |
10789 | OMPClause *ActOnOpenMPReductionClause( |
10790 | ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, |
10791 | SourceLocation StartLoc, SourceLocation LParenLoc, |
10792 | SourceLocation ModifierLoc, SourceLocation ColonLoc, |
10793 | SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, |
10794 | const DeclarationNameInfo &ReductionId, |
10795 | ArrayRef<Expr *> UnresolvedReductions = llvm::None); |
10796 | /// Called on well-formed 'task_reduction' clause. |
10797 | OMPClause *ActOnOpenMPTaskReductionClause( |
10798 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, |
10799 | SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, |
10800 | CXXScopeSpec &ReductionIdScopeSpec, |
10801 | const DeclarationNameInfo &ReductionId, |
10802 | ArrayRef<Expr *> UnresolvedReductions = llvm::None); |
10803 | /// Called on well-formed 'in_reduction' clause. |
10804 | OMPClause *ActOnOpenMPInReductionClause( |
10805 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, |
10806 | SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, |
10807 | CXXScopeSpec &ReductionIdScopeSpec, |
10808 | const DeclarationNameInfo &ReductionId, |
10809 | ArrayRef<Expr *> UnresolvedReductions = llvm::None); |
10810 | /// Called on well-formed 'linear' clause. |
10811 | OMPClause * |
10812 | ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step, |
10813 | SourceLocation StartLoc, SourceLocation LParenLoc, |
10814 | OpenMPLinearClauseKind LinKind, SourceLocation LinLoc, |
10815 | SourceLocation ColonLoc, SourceLocation EndLoc); |
10816 | /// Called on well-formed 'aligned' clause. |
10817 | OMPClause *ActOnOpenMPAlignedClause(ArrayRef<Expr *> VarList, |
10818 | Expr *Alignment, |
10819 | SourceLocation StartLoc, |
10820 | SourceLocation LParenLoc, |
10821 | SourceLocation ColonLoc, |
10822 | SourceLocation EndLoc); |
10823 | /// Called on well-formed 'copyin' clause. |
10824 | OMPClause *ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, |
10825 | SourceLocation StartLoc, |
10826 | SourceLocation LParenLoc, |
10827 | SourceLocation EndLoc); |
10828 | /// Called on well-formed 'copyprivate' clause. |
10829 | OMPClause *ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, |
10830 | SourceLocation StartLoc, |
10831 | SourceLocation LParenLoc, |
10832 | SourceLocation EndLoc); |
10833 | /// Called on well-formed 'flush' pseudo clause. |
10834 | OMPClause *ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, |
10835 | SourceLocation StartLoc, |
10836 | SourceLocation LParenLoc, |
10837 | SourceLocation EndLoc); |
10838 | /// Called on well-formed 'depobj' pseudo clause. |
10839 | OMPClause *ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, |
10840 | SourceLocation LParenLoc, |
10841 | SourceLocation EndLoc); |
10842 | /// Called on well-formed 'depend' clause. |
10843 | OMPClause * |
10844 | ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, |
10845 | SourceLocation DepLoc, SourceLocation ColonLoc, |
10846 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, |
10847 | SourceLocation LParenLoc, SourceLocation EndLoc); |
10848 | /// Called on well-formed 'device' clause. |
10849 | OMPClause *ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, |
10850 | Expr *Device, SourceLocation StartLoc, |
10851 | SourceLocation LParenLoc, |
10852 | SourceLocation ModifierLoc, |
10853 | SourceLocation EndLoc); |
10854 | /// Called on well-formed 'map' clause. |
10855 | OMPClause * |
10856 | ActOnOpenMPMapClause(ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, |
10857 | ArrayRef<SourceLocation> MapTypeModifiersLoc, |
10858 | CXXScopeSpec &MapperIdScopeSpec, |
10859 | DeclarationNameInfo &MapperId, |
10860 | OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, |
10861 | SourceLocation MapLoc, SourceLocation ColonLoc, |
10862 | ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs, |
10863 | ArrayRef<Expr *> UnresolvedMappers = llvm::None); |
10864 | /// Called on well-formed 'num_teams' clause. |
10865 | OMPClause *ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, |
10866 | SourceLocation LParenLoc, |
10867 | SourceLocation EndLoc); |
10868 | /// Called on well-formed 'thread_limit' clause. |
10869 | OMPClause *ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, |
10870 | SourceLocation StartLoc, |
10871 | SourceLocation LParenLoc, |
10872 | SourceLocation EndLoc); |
10873 | /// Called on well-formed 'priority' clause. |
10874 | OMPClause *ActOnOpenMPPriorityClause(Expr *Priority, SourceLocation StartLoc, |
10875 | SourceLocation LParenLoc, |
10876 | SourceLocation EndLoc); |
10877 | /// Called on well-formed 'dist_schedule' clause. |
10878 | OMPClause *ActOnOpenMPDistScheduleClause( |
10879 | OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, |
10880 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KindLoc, |
10881 | SourceLocation CommaLoc, SourceLocation EndLoc); |
10882 | /// Called on well-formed 'defaultmap' clause. |
10883 | OMPClause *ActOnOpenMPDefaultmapClause( |
10884 | OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, |
10885 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, |
10886 | SourceLocation KindLoc, SourceLocation EndLoc); |
10887 | /// Called on well-formed 'to' clause. |
10888 | OMPClause * |
10889 | ActOnOpenMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers, |
10890 | ArrayRef<SourceLocation> MotionModifiersLoc, |
10891 | CXXScopeSpec &MapperIdScopeSpec, |
10892 | DeclarationNameInfo &MapperId, SourceLocation ColonLoc, |
10893 | ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs, |
10894 | ArrayRef<Expr *> UnresolvedMappers = llvm::None); |
10895 | /// Called on well-formed 'from' clause. |
10896 | OMPClause * |
10897 | ActOnOpenMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers, |
10898 | ArrayRef<SourceLocation> MotionModifiersLoc, |
10899 | CXXScopeSpec &MapperIdScopeSpec, |
10900 | DeclarationNameInfo &MapperId, SourceLocation ColonLoc, |
10901 | ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs, |
10902 | ArrayRef<Expr *> UnresolvedMappers = llvm::None); |
10903 | /// Called on well-formed 'use_device_ptr' clause. |
10904 | OMPClause *ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, |
10905 | const OMPVarListLocTy &Locs); |
10906 | /// Called on well-formed 'use_device_addr' clause. |
10907 | OMPClause *ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList, |
10908 | const OMPVarListLocTy &Locs); |
10909 | /// Called on well-formed 'is_device_ptr' clause. |
10910 | OMPClause *ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, |
10911 | const OMPVarListLocTy &Locs); |
10912 | /// Called on well-formed 'nontemporal' clause. |
10913 | OMPClause *ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, |
10914 | SourceLocation StartLoc, |
10915 | SourceLocation LParenLoc, |
10916 | SourceLocation EndLoc); |
10917 | |
10918 | /// Data for list of allocators. |
10919 | struct UsesAllocatorsData { |
10920 | /// Allocator. |
10921 | Expr *Allocator = nullptr; |
10922 | /// Allocator traits. |
10923 | Expr *AllocatorTraits = nullptr; |
10924 | /// Locations of '(' and ')' symbols. |
10925 | SourceLocation LParenLoc, RParenLoc; |
10926 | }; |
10927 | /// Called on well-formed 'uses_allocators' clause. |
10928 | OMPClause *ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc, |
10929 | SourceLocation LParenLoc, |
10930 | SourceLocation EndLoc, |
10931 | ArrayRef<UsesAllocatorsData> Data); |
10932 | /// Called on well-formed 'affinity' clause. |
10933 | OMPClause *ActOnOpenMPAffinityClause(SourceLocation StartLoc, |
10934 | SourceLocation LParenLoc, |
10935 | SourceLocation ColonLoc, |
10936 | SourceLocation EndLoc, Expr *Modifier, |
10937 | ArrayRef<Expr *> Locators); |
10938 | |
10939 | /// The kind of conversion being performed. |
10940 | enum CheckedConversionKind { |
10941 | /// An implicit conversion. |
10942 | CCK_ImplicitConversion, |
10943 | /// A C-style cast. |
10944 | CCK_CStyleCast, |
10945 | /// A functional-style cast. |
10946 | CCK_FunctionalCast, |
10947 | /// A cast other than a C-style cast. |
10948 | CCK_OtherCast, |
10949 | /// A conversion for an operand of a builtin overloaded operator. |
10950 | CCK_ForBuiltinOverloadedOp |
10951 | }; |
10952 | |
10953 | static bool isCast(CheckedConversionKind CCK) { |
10954 | return CCK == CCK_CStyleCast || CCK == CCK_FunctionalCast || |
10955 | CCK == CCK_OtherCast; |
10956 | } |
10957 | |
10958 | /// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit |
10959 | /// cast. If there is already an implicit cast, merge into the existing one. |
10960 | /// If isLvalue, the result of the cast is an lvalue. |
10961 | ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, |
10962 | ExprValueKind VK = VK_RValue, |
10963 | const CXXCastPath *BasePath = nullptr, |
10964 | CheckedConversionKind CCK |
10965 | = CCK_ImplicitConversion); |
10966 | |
10967 | /// ScalarTypeToBooleanCastKind - Returns the cast kind corresponding |
10968 | /// to the conversion from scalar type ScalarTy to the Boolean type. |
10969 | static CastKind ScalarTypeToBooleanCastKind(QualType ScalarTy); |
10970 | |
10971 | /// IgnoredValueConversions - Given that an expression's result is |
10972 | /// syntactically ignored, perform any conversions that are |
10973 | /// required. |
10974 | ExprResult IgnoredValueConversions(Expr *E); |
10975 | |
10976 | // UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts |
10977 | // functions and arrays to their respective pointers (C99 6.3.2.1). |
10978 | ExprResult UsualUnaryConversions(Expr *E); |
10979 | |
10980 | /// CallExprUnaryConversions - a special case of an unary conversion |
10981 | /// performed on a function designator of a call expression. |
10982 | ExprResult CallExprUnaryConversions(Expr *E); |
10983 | |
10984 | // DefaultFunctionArrayConversion - converts functions and arrays |
10985 | // to their respective pointers (C99 6.3.2.1). |
10986 | ExprResult DefaultFunctionArrayConversion(Expr *E, bool Diagnose = true); |
10987 | |
10988 | // DefaultFunctionArrayLvalueConversion - converts functions and |
10989 | // arrays to their respective pointers and performs the |
10990 | // lvalue-to-rvalue conversion. |
10991 | ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, |
10992 | bool Diagnose = true); |
10993 | |
10994 | // DefaultLvalueConversion - performs lvalue-to-rvalue conversion on |
10995 | // the operand. This function is a no-op if the operand has a function type |
10996 | // or an array type. |
10997 | ExprResult DefaultLvalueConversion(Expr *E); |
10998 | |
10999 | // DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that |
11000 | // do not have a prototype. Integer promotions are performed on each |
11001 | // argument, and arguments that have type float are promoted to double. |
11002 | ExprResult DefaultArgumentPromotion(Expr *E); |
11003 | |
11004 | /// If \p E is a prvalue denoting an unmaterialized temporary, materialize |
11005 | /// it as an xvalue. In C++98, the result will still be a prvalue, because |
11006 | /// we don't have xvalues there. |
11007 | ExprResult TemporaryMaterializationConversion(Expr *E); |
11008 | |
11009 | // Used for emitting the right warning by DefaultVariadicArgumentPromotion |
11010 | enum VariadicCallType { |
11011 | VariadicFunction, |
11012 | VariadicBlock, |
11013 | VariadicMethod, |
11014 | VariadicConstructor, |
11015 | VariadicDoesNotApply |
11016 | }; |
11017 | |
11018 | VariadicCallType getVariadicCallType(FunctionDecl *FDecl, |
11019 | const FunctionProtoType *Proto, |
11020 | Expr *Fn); |
11021 | |
11022 | // Used for determining in which context a type is allowed to be passed to a |
11023 | // vararg function. |
11024 | enum VarArgKind { |
11025 | VAK_Valid, |
11026 | VAK_ValidInCXX11, |
11027 | VAK_Undefined, |
11028 | VAK_MSVCUndefined, |
11029 | VAK_Invalid |
11030 | }; |
11031 | |
11032 | // Determines which VarArgKind fits an expression. |
11033 | VarArgKind isValidVarArgType(const QualType &Ty); |
11034 | |
11035 | /// Check to see if the given expression is a valid argument to a variadic |
11036 | /// function, issuing a diagnostic if not. |
11037 | void checkVariadicArgument(const Expr *E, VariadicCallType CT); |
11038 | |
11039 | /// Check to see if a given expression could have '.c_str()' called on it. |
11040 | bool hasCStrMethod(const Expr *E); |
11041 | |
11042 | /// GatherArgumentsForCall - Collector argument expressions for various |
11043 | /// form of call prototypes. |
11044 | bool GatherArgumentsForCall(SourceLocation CallLoc, FunctionDecl *FDecl, |
11045 | const FunctionProtoType *Proto, |
11046 | unsigned FirstParam, ArrayRef<Expr *> Args, |
11047 | SmallVectorImpl<Expr *> &AllArgs, |
11048 | VariadicCallType CallType = VariadicDoesNotApply, |
11049 | bool AllowExplicit = false, |
11050 | bool IsListInitialization = false); |
11051 | |
11052 | // DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but |
11053 | // will create a runtime trap if the resulting type is not a POD type. |
11054 | ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, |
11055 | FunctionDecl *FDecl); |
11056 | |
11057 | /// Context in which we're performing a usual arithmetic conversion. |
11058 | enum ArithConvKind { |
11059 | /// An arithmetic operation. |
11060 | ACK_Arithmetic, |
11061 | /// A bitwise operation. |
11062 | ACK_BitwiseOp, |
11063 | /// A comparison. |
11064 | ACK_Comparison, |
11065 | /// A conditional (?:) operator. |
11066 | ACK_Conditional, |
11067 | /// A compound assignment expression. |
11068 | ACK_CompAssign, |
11069 | }; |
11070 | |
11071 | // UsualArithmeticConversions - performs the UsualUnaryConversions on it's |
11072 | // operands and then handles various conversions that are common to binary |
11073 | // operators (C99 6.3.1.8). If both operands aren't arithmetic, this |
11074 | // routine returns the first non-arithmetic type found. The client is |
11075 | // responsible for emitting appropriate error diagnostics. |
11076 | QualType UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS, |
11077 | SourceLocation Loc, ArithConvKind ACK); |
11078 | |
11079 | /// AssignConvertType - All of the 'assignment' semantic checks return this |
11080 | /// enum to indicate whether the assignment was allowed. These checks are |
11081 | /// done for simple assignments, as well as initialization, return from |
11082 | /// function, argument passing, etc. The query is phrased in terms of a |
11083 | /// source and destination type. |
11084 | enum AssignConvertType { |
11085 | /// Compatible - the types are compatible according to the standard. |
11086 | Compatible, |
11087 | |
11088 | /// PointerToInt - The assignment converts a pointer to an int, which we |
11089 | /// accept as an extension. |
11090 | PointerToInt, |
11091 | |
11092 | /// IntToPointer - The assignment converts an int to a pointer, which we |
11093 | /// accept as an extension. |
11094 | IntToPointer, |
11095 | |
11096 | /// FunctionVoidPointer - The assignment is between a function pointer and |
11097 | /// void*, which the standard doesn't allow, but we accept as an extension. |
11098 | FunctionVoidPointer, |
11099 | |
11100 | /// IncompatiblePointer - The assignment is between two pointers types that |
11101 | /// are not compatible, but we accept them as an extension. |
11102 | IncompatiblePointer, |
11103 | |
11104 | /// IncompatibleFunctionPointer - The assignment is between two function |
11105 | /// pointers types that are not compatible, but we accept them as an |
11106 | /// extension. |
11107 | IncompatibleFunctionPointer, |
11108 | |
11109 | /// IncompatiblePointerSign - The assignment is between two pointers types |
11110 | /// which point to integers which have a different sign, but are otherwise |
11111 | /// identical. This is a subset of the above, but broken out because it's by |
11112 | /// far the most common case of incompatible pointers. |
11113 | IncompatiblePointerSign, |
11114 | |
11115 | /// CompatiblePointerDiscardsQualifiers - The assignment discards |
11116 | /// c/v/r qualifiers, which we accept as an extension. |
11117 | CompatiblePointerDiscardsQualifiers, |
11118 | |
11119 | /// IncompatiblePointerDiscardsQualifiers - The assignment |
11120 | /// discards qualifiers that we don't permit to be discarded, |
11121 | /// like address spaces. |
11122 | IncompatiblePointerDiscardsQualifiers, |
11123 | |
11124 | /// IncompatibleNestedPointerAddressSpaceMismatch - The assignment |
11125 | /// changes address spaces in nested pointer types which is not allowed. |
11126 | /// For instance, converting __private int ** to __generic int ** is |
11127 | /// illegal even though __private could be converted to __generic. |
11128 | IncompatibleNestedPointerAddressSpaceMismatch, |
11129 | |
11130 | /// IncompatibleNestedPointerQualifiers - The assignment is between two |
11131 | /// nested pointer types, and the qualifiers other than the first two |
11132 | /// levels differ e.g. char ** -> const char **, but we accept them as an |
11133 | /// extension. |
11134 | IncompatibleNestedPointerQualifiers, |
11135 | |
11136 | /// IncompatibleVectors - The assignment is between two vector types that |
11137 | /// have the same size, which we accept as an extension. |
11138 | IncompatibleVectors, |
11139 | |
11140 | /// IntToBlockPointer - The assignment converts an int to a block |
11141 | /// pointer. We disallow this. |
11142 | IntToBlockPointer, |
11143 | |
11144 | /// IncompatibleBlockPointer - The assignment is between two block |
11145 | /// pointers types that are not compatible. |
11146 | IncompatibleBlockPointer, |
11147 | |
11148 | /// IncompatibleObjCQualifiedId - The assignment is between a qualified |
11149 | /// id type and something else (that is incompatible with it). For example, |
11150 | /// "id <XXX>" = "Foo *", where "Foo *" doesn't implement the XXX protocol. |
11151 | IncompatibleObjCQualifiedId, |
11152 | |
11153 | /// IncompatibleObjCWeakRef - Assigning a weak-unavailable object to an |
11154 | /// object with __weak qualifier. |
11155 | IncompatibleObjCWeakRef, |
11156 | |
11157 | /// Incompatible - We reject this conversion outright, it is invalid to |
11158 | /// represent it in the AST. |
11159 | Incompatible |
11160 | }; |
11161 | |
11162 | /// DiagnoseAssignmentResult - Emit a diagnostic, if required, for the |
11163 | /// assignment conversion type specified by ConvTy. This returns true if the |
11164 | /// conversion was invalid or false if the conversion was accepted. |
11165 | bool DiagnoseAssignmentResult(AssignConvertType ConvTy, |
11166 | SourceLocation Loc, |
11167 | QualType DstType, QualType SrcType, |
11168 | Expr *SrcExpr, AssignmentAction Action, |
11169 | bool *Complained = nullptr); |
11170 | |
11171 | /// IsValueInFlagEnum - Determine if a value is allowed as part of a flag |
11172 | /// enum. If AllowMask is true, then we also allow the complement of a valid |
11173 | /// value, to be used as a mask. |
11174 | bool IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val, |
11175 | bool AllowMask) const; |
11176 | |
11177 | /// DiagnoseAssignmentEnum - Warn if assignment to enum is a constant |
11178 | /// integer not in the range of enum values. |
11179 | void DiagnoseAssignmentEnum(QualType DstType, QualType SrcType, |
11180 | Expr *SrcExpr); |
11181 | |
11182 | /// CheckAssignmentConstraints - Perform type checking for assignment, |
11183 | /// argument passing, variable initialization, and function return values. |
11184 | /// C99 6.5.16. |
11185 | AssignConvertType CheckAssignmentConstraints(SourceLocation Loc, |
11186 | QualType LHSType, |
11187 | QualType RHSType); |
11188 | |
11189 | /// Check assignment constraints and optionally prepare for a conversion of |
11190 | /// the RHS to the LHS type. The conversion is prepared for if ConvertRHS |
11191 | /// is true. |
11192 | AssignConvertType CheckAssignmentConstraints(QualType LHSType, |
11193 | ExprResult &RHS, |
11194 | CastKind &Kind, |
11195 | bool ConvertRHS = true); |
11196 | |
11197 | /// Check assignment constraints for an assignment of RHS to LHSType. |
11198 | /// |
11199 | /// \param LHSType The destination type for the assignment. |
11200 | /// \param RHS The source expression for the assignment. |
11201 | /// \param Diagnose If \c true, diagnostics may be produced when checking |
11202 | /// for assignability. If a diagnostic is produced, \p RHS will be |
11203 | /// set to ExprError(). Note that this function may still return |
11204 | /// without producing a diagnostic, even for an invalid assignment. |
11205 | /// \param DiagnoseCFAudited If \c true, the target is a function parameter |
11206 | /// in an audited Core Foundation API and does not need to be checked |
11207 | /// for ARC retain issues. |
11208 | /// \param ConvertRHS If \c true, \p RHS will be updated to model the |
11209 | /// conversions necessary to perform the assignment. If \c false, |
11210 | /// \p Diagnose must also be \c false. |
11211 | AssignConvertType CheckSingleAssignmentConstraints( |
11212 | QualType LHSType, ExprResult &RHS, bool Diagnose = true, |
11213 | bool DiagnoseCFAudited = false, bool ConvertRHS = true); |
11214 | |
11215 | // If the lhs type is a transparent union, check whether we |
11216 | // can initialize the transparent union with the given expression. |
11217 | AssignConvertType CheckTransparentUnionArgumentConstraints(QualType ArgType, |
11218 | ExprResult &RHS); |
11219 | |
11220 | bool IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType); |
11221 | |
11222 | bool CheckExceptionSpecCompatibility(Expr *From, QualType ToType); |
11223 | |
11224 | ExprResult PerformImplicitConversion(Expr *From, QualType ToType, |
11225 | AssignmentAction Action, |
11226 | bool AllowExplicit = false); |
11227 | ExprResult PerformImplicitConversion(Expr *From, QualType ToType, |
11228 | const ImplicitConversionSequence& ICS, |
11229 | AssignmentAction Action, |
11230 | CheckedConversionKind CCK |
11231 | = CCK_ImplicitConversion); |
11232 | ExprResult PerformImplicitConversion(Expr *From, QualType ToType, |
11233 | const StandardConversionSequence& SCS, |
11234 | AssignmentAction Action, |
11235 | CheckedConversionKind CCK); |
11236 | |
11237 | ExprResult PerformQualificationConversion( |
11238 | Expr *E, QualType Ty, ExprValueKind VK = VK_RValue, |
11239 | CheckedConversionKind CCK = CCK_ImplicitConversion); |
11240 | |
11241 | /// the following "Check" methods will return a valid/converted QualType |
11242 | /// or a null QualType (indicating an error diagnostic was issued). |
11243 | |
11244 | /// type checking binary operators (subroutines of CreateBuiltinBinOp). |
11245 | QualType InvalidOperands(SourceLocation Loc, ExprResult &LHS, |
11246 | ExprResult &RHS); |
11247 | QualType InvalidLogicalVectorOperands(SourceLocation Loc, ExprResult &LHS, |
11248 | ExprResult &RHS); |
11249 | QualType CheckPointerToMemberOperands( // C++ 5.5 |
11250 | ExprResult &LHS, ExprResult &RHS, ExprValueKind &VK, |
11251 | SourceLocation OpLoc, bool isIndirect); |
11252 | QualType CheckMultiplyDivideOperands( // C99 6.5.5 |
11253 | ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, bool IsCompAssign, |
11254 | bool IsDivide); |
11255 | QualType CheckRemainderOperands( // C99 6.5.5 |
11256 | ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, |
11257 | bool IsCompAssign = false); |
11258 | QualType CheckAdditionOperands( // C99 6.5.6 |
11259 | ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, |
11260 | BinaryOperatorKind Opc, QualType* CompLHSTy = nullptr); |
11261 | QualType CheckSubtractionOperands( // C99 6.5.6 |
11262 | ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, |
11263 | QualType* CompLHSTy = nullptr); |
11264 | QualType CheckShiftOperands( // C99 6.5.7 |
11265 | ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, |
11266 | BinaryOperatorKind Opc, bool IsCompAssign = false); |
11267 | void CheckPtrComparisonWithNullChar(ExprResult &E, ExprResult &NullE); |
11268 | QualType CheckCompareOperands( // C99 6.5.8/9 |
11269 | ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, |
11270 | BinaryOperatorKind Opc); |
11271 | QualType CheckBitwiseOperands( // C99 6.5.[10...12] |
11272 | ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, |
11273 | BinaryOperatorKind Opc); |
11274 | QualType CheckLogicalOperands( // C99 6.5.[13,14] |
11275 | ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, |
11276 | BinaryOperatorKind Opc); |
11277 | // CheckAssignmentOperands is used for both simple and compound assignment. |
11278 | // For simple assignment, pass both expressions and a null converted type. |
11279 | // For compound assignment, pass both expressions and the converted type. |
11280 | QualType CheckAssignmentOperands( // C99 6.5.16.[1,2] |
11281 | Expr *LHSExpr, ExprResult &RHS, SourceLocation Loc, QualType CompoundType); |
11282 | |
11283 | ExprResult checkPseudoObjectIncDec(Scope *S, SourceLocation OpLoc, |
11284 | UnaryOperatorKind Opcode, Expr *Op); |
11285 | ExprResult checkPseudoObjectAssignment(Scope *S, SourceLocation OpLoc, |
11286 | BinaryOperatorKind Opcode, |
11287 | Expr *LHS, Expr *RHS); |
11288 | ExprResult checkPseudoObjectRValue(Expr *E); |
11289 | Expr *recreateSyntacticForm(PseudoObjectExpr *E); |
11290 | |
11291 | QualType CheckConditionalOperands( // C99 6.5.15 |
11292 | ExprResult &Cond, ExprResult &LHS, ExprResult &RHS, |
11293 | ExprValueKind &VK, ExprObjectKind &OK, SourceLocation QuestionLoc); |
11294 | QualType CXXCheckConditionalOperands( // C++ 5.16 |
11295 | ExprResult &cond, ExprResult &lhs, ExprResult &rhs, |
11296 | ExprValueKind &VK, ExprObjectKind &OK, SourceLocation questionLoc); |
11297 | QualType CheckGNUVectorConditionalTypes(ExprResult &Cond, ExprResult &LHS, |
11298 | ExprResult &RHS, |
11299 | SourceLocation QuestionLoc); |
11300 | QualType FindCompositePointerType(SourceLocation Loc, Expr *&E1, Expr *&E2, |
11301 | bool ConvertArgs = true); |
11302 | QualType FindCompositePointerType(SourceLocation Loc, |
11303 | ExprResult &E1, ExprResult &E2, |
11304 | bool ConvertArgs = true) { |
11305 | Expr *E1Tmp = E1.get(), *E2Tmp = E2.get(); |
11306 | QualType Composite = |
11307 | FindCompositePointerType(Loc, E1Tmp, E2Tmp, ConvertArgs); |
11308 | E1 = E1Tmp; |
11309 | E2 = E2Tmp; |
11310 | return Composite; |
11311 | } |
11312 | |
11313 | QualType FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS, |
11314 | SourceLocation QuestionLoc); |
11315 | |
11316 | bool DiagnoseConditionalForNull(Expr *LHSExpr, Expr *RHSExpr, |
11317 | SourceLocation QuestionLoc); |
11318 | |
11319 | void DiagnoseAlwaysNonNullPointer(Expr *E, |
11320 | Expr::NullPointerConstantKind NullType, |
11321 | bool IsEqual, SourceRange Range); |
11322 | |
11323 | /// type checking for vector binary operators. |
11324 | QualType CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, |
11325 | SourceLocation Loc, bool IsCompAssign, |
11326 | bool AllowBothBool, bool AllowBoolConversion); |
11327 | QualType GetSignedVectorType(QualType V); |
11328 | QualType CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS, |
11329 | SourceLocation Loc, |
11330 | BinaryOperatorKind Opc); |
11331 | QualType CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS, |
11332 | SourceLocation Loc); |
11333 | |
11334 | /// Type checking for matrix binary operators. |
11335 | QualType CheckMatrixElementwiseOperands(ExprResult &LHS, ExprResult &RHS, |
11336 | SourceLocation Loc, |
11337 | bool IsCompAssign); |
11338 | QualType CheckMatrixMultiplyOperands(ExprResult &LHS, ExprResult &RHS, |
11339 | SourceLocation Loc, bool IsCompAssign); |
11340 | |
11341 | bool areLaxCompatibleVectorTypes(QualType srcType, QualType destType); |
11342 | bool isLaxVectorConversion(QualType srcType, QualType destType); |
11343 | |
11344 | /// type checking declaration initializers (C99 6.7.8) |
11345 | bool CheckForConstantInitializer(Expr *e, QualType t); |
11346 | |
11347 | // type checking C++ declaration initializers (C++ [dcl.init]). |
11348 | |
11349 | /// ReferenceCompareResult - Expresses the result of comparing two |
11350 | /// types (cv1 T1 and cv2 T2) to determine their compatibility for the |
11351 | /// purposes of initialization by reference (C++ [dcl.init.ref]p4). |
11352 | enum ReferenceCompareResult { |
11353 | /// Ref_Incompatible - The two types are incompatible, so direct |
11354 | /// reference binding is not possible. |
11355 | Ref_Incompatible = 0, |
11356 | /// Ref_Related - The two types are reference-related, which means |
11357 | /// that their unqualified forms (T1 and T2) are either the same |
11358 | /// or T1 is a base class of T2. |
11359 | Ref_Related, |
11360 | /// Ref_Compatible - The two types are reference-compatible. |
11361 | Ref_Compatible |
11362 | }; |
11363 | |
11364 | // Fake up a scoped enumeration that still contextually converts to bool. |
11365 | struct ReferenceConversionsScope { |
11366 | /// The conversions that would be performed on an lvalue of type T2 when |
11367 | /// binding a reference of type T1 to it, as determined when evaluating |
11368 | /// whether T1 is reference-compatible with T2. |
11369 | enum ReferenceConversions { |
11370 | Qualification = 0x1, |
11371 | NestedQualification = 0x2, |
11372 | Function = 0x4, |
11373 | DerivedToBase = 0x8, |
11374 | ObjC = 0x10, |
11375 | ObjCLifetime = 0x20, |
11376 | |
11377 | LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/ObjCLifetime)LLVM_BITMASK_LARGEST_ENUMERATOR = ObjCLifetime |
11378 | }; |
11379 | }; |
11380 | using ReferenceConversions = ReferenceConversionsScope::ReferenceConversions; |
11381 | |
11382 | ReferenceCompareResult |
11383 | CompareReferenceRelationship(SourceLocation Loc, QualType T1, QualType T2, |
11384 | ReferenceConversions *Conv = nullptr); |
11385 | |
11386 | ExprResult checkUnknownAnyCast(SourceRange TypeRange, QualType CastType, |
11387 | Expr *CastExpr, CastKind &CastKind, |
11388 | ExprValueKind &VK, CXXCastPath &Path); |
11389 | |
11390 | /// Force an expression with unknown-type to an expression of the |
11391 | /// given type. |
11392 | ExprResult forceUnknownAnyToType(Expr *E, QualType ToType); |
11393 | |
11394 | /// Type-check an expression that's being passed to an |
11395 | /// __unknown_anytype parameter. |
11396 | ExprResult checkUnknownAnyArg(SourceLocation callLoc, |
11397 | Expr *result, QualType ¶mType); |
11398 | |
11399 | // CheckVectorCast - check type constraints for vectors. |
11400 | // Since vectors are an extension, there are no C standard reference for this. |
11401 | // We allow casting between vectors and integer datatypes of the same size. |
11402 | // returns true if the cast is invalid |
11403 | bool CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty, |
11404 | CastKind &Kind); |
11405 | |
11406 | /// Prepare `SplattedExpr` for a vector splat operation, adding |
11407 | /// implicit casts if necessary. |
11408 | ExprResult prepareVectorSplat(QualType VectorTy, Expr *SplattedExpr); |
11409 | |
11410 | // CheckExtVectorCast - check type constraints for extended vectors. |
11411 | // Since vectors are an extension, there are no C standard reference for this. |
11412 | // We allow casting between vectors and integer datatypes of the same size, |
11413 | // or vectors and the element type of that vector. |
11414 | // returns the cast expr |
11415 | ExprResult CheckExtVectorCast(SourceRange R, QualType DestTy, Expr *CastExpr, |
11416 | CastKind &Kind); |
11417 | |
11418 | ExprResult BuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo, QualType Type, |
11419 | SourceLocation LParenLoc, |
11420 | Expr *CastExpr, |
11421 | SourceLocation RParenLoc); |
11422 | |
11423 | enum ARCConversionResult { ACR_okay, ACR_unbridged, ACR_error }; |
11424 | |
11425 | /// Checks for invalid conversions and casts between |
11426 | /// retainable pointers and other pointer kinds for ARC and Weak. |
11427 | ARCConversionResult CheckObjCConversion(SourceRange castRange, |
11428 | QualType castType, Expr *&op, |
11429 | CheckedConversionKind CCK, |
11430 | bool Diagnose = true, |
11431 | bool DiagnoseCFAudited = false, |
11432 | BinaryOperatorKind Opc = BO_PtrMemD |
11433 | ); |
11434 | |
11435 | Expr *stripARCUnbridgedCast(Expr *e); |
11436 | void diagnoseARCUnbridgedCast(Expr *e); |
11437 | |
11438 | bool CheckObjCARCUnavailableWeakConversion(QualType castType, |
11439 | QualType ExprType); |
11440 | |
11441 | /// checkRetainCycles - Check whether an Objective-C message send |
11442 | /// might create an obvious retain cycle. |
11443 | void checkRetainCycles(ObjCMessageExpr *msg); |
11444 | void checkRetainCycles(Expr *receiver, Expr *argument); |
11445 | void checkRetainCycles(VarDecl *Var, Expr *Init); |
11446 | |
11447 | /// checkUnsafeAssigns - Check whether +1 expr is being assigned |
11448 | /// to weak/__unsafe_unretained type. |
11449 | bool checkUnsafeAssigns(SourceLocation Loc, QualType LHS, Expr *RHS); |
11450 | |
11451 | /// checkUnsafeExprAssigns - Check whether +1 expr is being assigned |
11452 | /// to weak/__unsafe_unretained expression. |
11453 | void checkUnsafeExprAssigns(SourceLocation Loc, Expr *LHS, Expr *RHS); |
11454 | |
11455 | /// CheckMessageArgumentTypes - Check types in an Obj-C message send. |
11456 | /// \param Method - May be null. |
11457 | /// \param [out] ReturnType - The return type of the send. |
11458 | /// \return true iff there were any incompatible types. |
11459 | bool CheckMessageArgumentTypes(const Expr *Receiver, QualType ReceiverType, |
11460 | MultiExprArg Args, Selector Sel, |
11461 | ArrayRef<SourceLocation> SelectorLocs, |
11462 | ObjCMethodDecl *Method, bool isClassMessage, |
11463 | bool isSuperMessage, SourceLocation lbrac, |
11464 | SourceLocation rbrac, SourceRange RecRange, |
11465 | QualType &ReturnType, ExprValueKind &VK); |
11466 | |
11467 | /// Determine the result of a message send expression based on |
11468 | /// the type of the receiver, the method expected to receive the message, |
11469 | /// and the form of the message send. |
11470 | QualType getMessageSendResultType(const Expr *Receiver, QualType ReceiverType, |
11471 | ObjCMethodDecl *Method, bool isClassMessage, |
11472 | bool isSuperMessage); |
11473 | |
11474 | /// If the given expression involves a message send to a method |
11475 | /// with a related result type, emit a note describing what happened. |
11476 | void EmitRelatedResultTypeNote(const Expr *E); |
11477 | |
11478 | /// Given that we had incompatible pointer types in a return |
11479 | /// statement, check whether we're in a method with a related result |
11480 | /// type, and if so, emit a note describing what happened. |
11481 | void EmitRelatedResultTypeNoteForReturn(QualType destType); |
11482 | |
11483 | class ConditionResult { |
11484 | Decl *ConditionVar; |
11485 | FullExprArg Condition; |
11486 | bool Invalid; |
11487 | bool HasKnownValue; |
11488 | bool KnownValue; |
11489 | |
11490 | friend class Sema; |
11491 | ConditionResult(Sema &S, Decl *ConditionVar, FullExprArg Condition, |
11492 | bool IsConstexpr) |
11493 | : ConditionVar(ConditionVar), Condition(Condition), Invalid(false), |
11494 | HasKnownValue(IsConstexpr && Condition.get() && |
11495 | !Condition.get()->isValueDependent()), |
11496 | KnownValue(HasKnownValue && |
11497 | !!Condition.get()->EvaluateKnownConstInt(S.Context)) {} |
11498 | explicit ConditionResult(bool Invalid) |
11499 | : ConditionVar(nullptr), Condition(nullptr), Invalid(Invalid), |
11500 | HasKnownValue(false), KnownValue(false) {} |
11501 | |
11502 | public: |
11503 | ConditionResult() : ConditionResult(false) {} |
11504 | bool isInvalid() const { return Invalid; } |
11505 | std::pair<VarDecl *, Expr *> get() const { |
11506 | return std::make_pair(cast_or_null<VarDecl>(ConditionVar), |
11507 | Condition.get()); |
11508 | } |
11509 | llvm::Optional<bool> getKnownValue() const { |
11510 | if (!HasKnownValue) |
11511 | return None; |
11512 | return KnownValue; |
11513 | } |
11514 | }; |
11515 | static ConditionResult ConditionError() { return ConditionResult(true); } |
11516 | |
11517 | enum class ConditionKind { |
11518 | Boolean, ///< A boolean condition, from 'if', 'while', 'for', or 'do'. |
11519 | ConstexprIf, ///< A constant boolean condition from 'if constexpr'. |
11520 | Switch ///< An integral condition for a 'switch' statement. |
11521 | }; |
11522 | |
11523 | ConditionResult ActOnCondition(Scope *S, SourceLocation Loc, |
11524 | Expr *SubExpr, ConditionKind CK); |
11525 | |
11526 | ConditionResult ActOnConditionVariable(Decl *ConditionVar, |
11527 | SourceLocation StmtLoc, |
11528 | ConditionKind CK); |
11529 | |
11530 | DeclResult ActOnCXXConditionDeclaration(Scope *S, Declarator &D); |
11531 | |
11532 | ExprResult CheckConditionVariable(VarDecl *ConditionVar, |
11533 | SourceLocation StmtLoc, |
11534 | ConditionKind CK); |
11535 | ExprResult CheckSwitchCondition(SourceLocation SwitchLoc, Expr *Cond); |
11536 | |
11537 | /// CheckBooleanCondition - Diagnose problems involving the use of |
11538 | /// the given expression as a boolean condition (e.g. in an if |
11539 | /// statement). Also performs the standard function and array |
11540 | /// decays, possibly changing the input variable. |
11541 | /// |
11542 | /// \param Loc - A location associated with the condition, e.g. the |
11543 | /// 'if' keyword. |
11544 | /// \return true iff there were any errors |
11545 | ExprResult CheckBooleanCondition(SourceLocation Loc, Expr *E, |
11546 | bool IsConstexpr = false); |
11547 | |
11548 | /// ActOnExplicitBoolSpecifier - Build an ExplicitSpecifier from an expression |
11549 | /// found in an explicit(bool) specifier. |
11550 | ExplicitSpecifier ActOnExplicitBoolSpecifier(Expr *E); |
11551 | |
11552 | /// tryResolveExplicitSpecifier - Attempt to resolve the explict specifier. |
11553 | /// Returns true if the explicit specifier is now resolved. |
11554 | bool tryResolveExplicitSpecifier(ExplicitSpecifier &ExplicitSpec); |
11555 | |
11556 | /// DiagnoseAssignmentAsCondition - Given that an expression is |
11557 | /// being used as a boolean condition, warn if it's an assignment. |
11558 | void DiagnoseAssignmentAsCondition(Expr *E); |
11559 | |
11560 | /// Redundant parentheses over an equality comparison can indicate |
11561 | /// that the user intended an assignment used as condition. |
11562 | void DiagnoseEqualityWithExtraParens(ParenExpr *ParenE); |
11563 | |
11564 | /// CheckCXXBooleanCondition - Returns true if conversion to bool is invalid. |
11565 | ExprResult CheckCXXBooleanCondition(Expr *CondExpr, bool IsConstexpr = false); |
11566 | |
11567 | /// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have |
11568 | /// the specified width and sign. If an overflow occurs, detect it and emit |
11569 | /// the specified diagnostic. |
11570 | void ConvertIntegerToTypeWarnOnOverflow(llvm::APSInt &OldVal, |
11571 | unsigned NewWidth, bool NewSign, |
11572 | SourceLocation Loc, unsigned DiagID); |
11573 | |
11574 | /// Checks that the Objective-C declaration is declared in the global scope. |
11575 | /// Emits an error and marks the declaration as invalid if it's not declared |
11576 | /// in the global scope. |
11577 | bool CheckObjCDeclScope(Decl *D); |
11578 | |
11579 | /// Abstract base class used for diagnosing integer constant |
11580 | /// expression violations. |
11581 | class VerifyICEDiagnoser { |
11582 | public: |
11583 | bool Suppress; |
11584 | |
11585 | VerifyICEDiagnoser(bool Suppress = false) : Suppress(Suppress) { } |
11586 | |
11587 | virtual SemaDiagnosticBuilder |
11588 | diagnoseNotICEType(Sema &S, SourceLocation Loc, QualType T); |
11589 | virtual SemaDiagnosticBuilder diagnoseNotICE(Sema &S, |
11590 | SourceLocation Loc) = 0; |
11591 | virtual SemaDiagnosticBuilder diagnoseFold(Sema &S, SourceLocation Loc); |
11592 | virtual ~VerifyICEDiagnoser() {} |
11593 | }; |
11594 | |
11595 | /// VerifyIntegerConstantExpression - Verifies that an expression is an ICE, |
11596 | /// and reports the appropriate diagnostics. Returns false on success. |
11597 | /// Can optionally return the value of the expression. |
11598 | ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, |
11599 | VerifyICEDiagnoser &Diagnoser, |
11600 | bool AllowFold = true); |
11601 | ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, |
11602 | unsigned DiagID, |
11603 | bool AllowFold = true); |
11604 | ExprResult VerifyIntegerConstantExpression(Expr *E, |
11605 | llvm::APSInt *Result = nullptr); |
11606 | |
11607 | /// VerifyBitField - verifies that a bit field expression is an ICE and has |
11608 | /// the correct width, and that the field type is valid. |
11609 | /// Returns false on success. |
11610 | /// Can optionally return whether the bit-field is of width 0 |
11611 | ExprResult VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName, |
11612 | QualType FieldTy, bool IsMsStruct, |
11613 | Expr *BitWidth, bool *ZeroWidth = nullptr); |
11614 | |
11615 | private: |
11616 | unsigned ForceCUDAHostDeviceDepth = 0; |
11617 | |
11618 | public: |
11619 | /// Increments our count of the number of times we've seen a pragma forcing |
11620 | /// functions to be __host__ __device__. So long as this count is greater |
11621 | /// than zero, all functions encountered will be __host__ __device__. |
11622 | void PushForceCUDAHostDevice(); |
11623 | |
11624 | /// Decrements our count of the number of times we've seen a pragma forcing |
11625 | /// functions to be __host__ __device__. Returns false if the count is 0 |
11626 | /// before incrementing, so you can emit an error. |
11627 | bool PopForceCUDAHostDevice(); |
11628 | |
11629 | /// Diagnostics that are emitted only if we discover that the given function |
11630 | /// must be codegen'ed. Because handling these correctly adds overhead to |
11631 | /// compilation, this is currently only enabled for CUDA compilations. |
11632 | llvm::DenseMap<CanonicalDeclPtr<FunctionDecl>, |
11633 | std::vector<PartialDiagnosticAt>> |
11634 | DeviceDeferredDiags; |
11635 | |
11636 | /// A pair of a canonical FunctionDecl and a SourceLocation. When used as the |
11637 | /// key in a hashtable, both the FD and location are hashed. |
11638 | struct FunctionDeclAndLoc { |
11639 | CanonicalDeclPtr<FunctionDecl> FD; |
11640 | SourceLocation Loc; |
11641 | }; |
11642 | |
11643 | /// FunctionDecls and SourceLocations for which CheckCUDACall has emitted a |
11644 | /// (maybe deferred) "bad call" diagnostic. We use this to avoid emitting the |
11645 | /// same deferred diag twice. |
11646 | llvm::DenseSet<FunctionDeclAndLoc> LocsWithCUDACallDiags; |
11647 | |
11648 | /// An inverse call graph, mapping known-emitted functions to one of their |
11649 | /// known-emitted callers (plus the location of the call). |
11650 | /// |
11651 | /// Functions that we can tell a priori must be emitted aren't added to this |
11652 | /// map. |
11653 | llvm::DenseMap</* Callee = */ CanonicalDeclPtr<FunctionDecl>, |
11654 | /* Caller = */ FunctionDeclAndLoc> |
11655 | DeviceKnownEmittedFns; |
11656 | |
11657 | /// Diagnostic builder for CUDA/OpenMP devices errors which may or may not be |
11658 | /// deferred. |
11659 | /// |
11660 | /// In CUDA, there exist constructs (e.g. variable-length arrays, try/catch) |
11661 | /// which are not allowed to appear inside __device__ functions and are |
11662 | /// allowed to appear in __host__ __device__ functions only if the host+device |
11663 | /// function is never codegen'ed. |
11664 | /// |
11665 | /// To handle this, we use the notion of "deferred diagnostics", where we |
11666 | /// attach a diagnostic to a FunctionDecl that's emitted iff it's codegen'ed. |
11667 | /// |
11668 | /// This class lets you emit either a regular diagnostic, a deferred |
11669 | /// diagnostic, or no diagnostic at all, according to an argument you pass to |
11670 | /// its constructor, thus simplifying the process of creating these "maybe |
11671 | /// deferred" diagnostics. |
11672 | class DeviceDiagBuilder { |
11673 | public: |
11674 | enum Kind { |
11675 | /// Emit no diagnostics. |
11676 | K_Nop, |
11677 | /// Emit the diagnostic immediately (i.e., behave like Sema::Diag()). |
11678 | K_Immediate, |
11679 | /// Emit the diagnostic immediately, and, if it's a warning or error, also |
11680 | /// emit a call stack showing how this function can be reached by an a |
11681 | /// priori known-emitted function. |
11682 | K_ImmediateWithCallStack, |
11683 | /// Create a deferred diagnostic, which is emitted only if the function |
11684 | /// it's attached to is codegen'ed. Also emit a call stack as with |
11685 | /// K_ImmediateWithCallStack. |
11686 | K_Deferred |
11687 | }; |
11688 | |
11689 | DeviceDiagBuilder(Kind K, SourceLocation Loc, unsigned DiagID, |
11690 | FunctionDecl *Fn, Sema &S); |
11691 | DeviceDiagBuilder(DeviceDiagBuilder &&D); |
11692 | DeviceDiagBuilder(const DeviceDiagBuilder &) = default; |
11693 | ~DeviceDiagBuilder(); |
11694 | |
11695 | /// Convertible to bool: True if we immediately emitted an error, false if |
11696 | /// we didn't emit an error or we created a deferred error. |
11697 | /// |
11698 | /// Example usage: |
11699 | /// |
11700 | /// if (DeviceDiagBuilder(...) << foo << bar) |
11701 | /// return ExprError(); |
11702 | /// |
11703 | /// But see CUDADiagIfDeviceCode() and CUDADiagIfHostCode() -- you probably |
11704 | /// want to use these instead of creating a DeviceDiagBuilder yourself. |
11705 | operator bool() const { return ImmediateDiag.hasValue(); } |
11706 | |
11707 | template <typename T> |
11708 | friend const DeviceDiagBuilder &operator<<(const DeviceDiagBuilder &Diag, |
11709 | const T &Value) { |
11710 | if (Diag.ImmediateDiag.hasValue()) |
11711 | *Diag.ImmediateDiag << Value; |
11712 | else if (Diag.PartialDiagId.hasValue()) |
11713 | Diag.S.DeviceDeferredDiags[Diag.Fn][*Diag.PartialDiagId].second |
11714 | << Value; |
11715 | return Diag; |
11716 | } |
11717 | |
11718 | private: |
11719 | Sema &S; |
11720 | SourceLocation Loc; |
11721 | unsigned DiagID; |
11722 | FunctionDecl *Fn; |
11723 | bool ShowCallStack; |
11724 | |
11725 | // Invariant: At most one of these Optionals has a value. |
11726 | // FIXME: Switch these to a Variant once that exists. |
11727 | llvm::Optional<SemaDiagnosticBuilder> ImmediateDiag; |
11728 | llvm::Optional<unsigned> PartialDiagId; |
11729 | }; |
11730 | |
11731 | /// Creates a DeviceDiagBuilder that emits the diagnostic if the current context |
11732 | /// is "used as device code". |
11733 | /// |
11734 | /// - If CurContext is a __host__ function, does not emit any diagnostics. |
11735 | /// - If CurContext is a __device__ or __global__ function, emits the |
11736 | /// diagnostics immediately. |
11737 | /// - If CurContext is a __host__ __device__ function and we are compiling for |
11738 | /// the device, creates a diagnostic which is emitted if and when we realize |
11739 | /// that the function will be codegen'ed. |
11740 | /// |
11741 | /// Example usage: |
11742 | /// |
11743 | /// // Variable-length arrays are not allowed in CUDA device code. |
11744 | /// if (CUDADiagIfDeviceCode(Loc, diag::err_cuda_vla) << CurrentCUDATarget()) |
11745 | /// return ExprError(); |
11746 | /// // Otherwise, continue parsing as normal. |
11747 | DeviceDiagBuilder CUDADiagIfDeviceCode(SourceLocation Loc, unsigned DiagID); |
11748 | |
11749 | /// Creates a DeviceDiagBuilder that emits the diagnostic if the current context |
11750 | /// is "used as host code". |
11751 | /// |
11752 | /// Same as CUDADiagIfDeviceCode, with "host" and "device" switched. |
11753 | DeviceDiagBuilder CUDADiagIfHostCode(SourceLocation Loc, unsigned DiagID); |
11754 | |
11755 | /// Creates a DeviceDiagBuilder that emits the diagnostic if the current |
11756 | /// context is "used as device code". |
11757 | /// |
11758 | /// - If CurContext is a `declare target` function or it is known that the |
11759 | /// function is emitted for the device, emits the diagnostics immediately. |
11760 | /// - If CurContext is a non-`declare target` function and we are compiling |
11761 | /// for the device, creates a diagnostic which is emitted if and when we |
11762 | /// realize that the function will be codegen'ed. |
11763 | /// |
11764 | /// Example usage: |
11765 | /// |
11766 | /// // Variable-length arrays are not allowed in NVPTX device code. |
11767 | /// if (diagIfOpenMPDeviceCode(Loc, diag::err_vla_unsupported)) |
11768 | /// return ExprError(); |
11769 | /// // Otherwise, continue parsing as normal. |
11770 | DeviceDiagBuilder diagIfOpenMPDeviceCode(SourceLocation Loc, unsigned DiagID); |
11771 | |
11772 | /// Creates a DeviceDiagBuilder that emits the diagnostic if the current |
11773 | /// context is "used as host code". |
11774 | /// |
11775 | /// - If CurContext is a `declare target` function or it is known that the |
11776 | /// function is emitted for the host, emits the diagnostics immediately. |
11777 | /// - If CurContext is a non-host function, just ignore it. |
11778 | /// |
11779 | /// Example usage: |
11780 | /// |
11781 | /// // Variable-length arrays are not allowed in NVPTX device code. |
11782 | /// if (diagIfOpenMPHostode(Loc, diag::err_vla_unsupported)) |
11783 | /// return ExprError(); |
11784 | /// // Otherwise, continue parsing as normal. |
11785 | DeviceDiagBuilder diagIfOpenMPHostCode(SourceLocation Loc, unsigned DiagID); |
11786 | |
11787 | DeviceDiagBuilder targetDiag(SourceLocation Loc, unsigned DiagID); |
11788 | |
11789 | /// Check if the expression is allowed to be used in expressions for the |
11790 | /// offloading devices. |
11791 | void checkDeviceDecl(const ValueDecl *D, SourceLocation Loc); |
11792 | |
11793 | enum CUDAFunctionTarget { |
11794 | CFT_Device, |
11795 | CFT_Global, |
11796 | CFT_Host, |
11797 | CFT_HostDevice, |
11798 | CFT_InvalidTarget |
11799 | }; |
11800 | |
11801 | /// Determines whether the given function is a CUDA device/host/kernel/etc. |
11802 | /// function. |
11803 | /// |
11804 | /// Use this rather than examining the function's attributes yourself -- you |
11805 | /// will get it wrong. Returns CFT_Host if D is null. |
11806 | CUDAFunctionTarget IdentifyCUDATarget(const FunctionDecl *D, |
11807 | bool IgnoreImplicitHDAttr = false); |
11808 | CUDAFunctionTarget IdentifyCUDATarget(const ParsedAttributesView &Attrs); |
11809 | |
11810 | /// Gets the CUDA target for the current context. |
11811 | CUDAFunctionTarget CurrentCUDATarget() { |
11812 | return IdentifyCUDATarget(dyn_cast<FunctionDecl>(CurContext)); |
11813 | } |
11814 | |
11815 | static bool isCUDAImplicitHostDeviceFunction(const FunctionDecl *D); |
11816 | |
11817 | // CUDA function call preference. Must be ordered numerically from |
11818 | // worst to best. |
11819 | enum CUDAFunctionPreference { |
11820 | CFP_Never, // Invalid caller/callee combination. |
11821 | CFP_WrongSide, // Calls from host-device to host or device |
11822 | // function that do not match current compilation |
11823 | // mode. |
11824 | CFP_HostDevice, // Any calls to host/device functions. |
11825 | CFP_SameSide, // Calls from host-device to host or device |
11826 | // function matching current compilation mode. |
11827 | CFP_Native, // host-to-host or device-to-device calls. |
11828 | }; |
11829 | |
11830 | /// Identifies relative preference of a given Caller/Callee |
11831 | /// combination, based on their host/device attributes. |
11832 | /// \param Caller function which needs address of \p Callee. |
11833 | /// nullptr in case of global context. |
11834 | /// \param Callee target function |
11835 | /// |
11836 | /// \returns preference value for particular Caller/Callee combination. |
11837 | CUDAFunctionPreference IdentifyCUDAPreference(const FunctionDecl *Caller, |
11838 | const FunctionDecl *Callee); |
11839 | |
11840 | /// Determines whether Caller may invoke Callee, based on their CUDA |
11841 | /// host/device attributes. Returns false if the call is not allowed. |
11842 | /// |
11843 | /// Note: Will return true for CFP_WrongSide calls. These may appear in |
11844 | /// semantically correct CUDA programs, but only if they're never codegen'ed. |
11845 | bool IsAllowedCUDACall(const FunctionDecl *Caller, |
11846 | const FunctionDecl *Callee) { |
11847 | return IdentifyCUDAPreference(Caller, Callee) != CFP_Never; |
11848 | } |
11849 | |
11850 | /// May add implicit CUDAHostAttr and CUDADeviceAttr attributes to FD, |
11851 | /// depending on FD and the current compilation settings. |
11852 | void maybeAddCUDAHostDeviceAttrs(FunctionDecl *FD, |
11853 | const LookupResult &Previous); |
11854 | |
11855 | /// May add implicit CUDAConstantAttr attribute to VD, depending on VD |
11856 | /// and current compilation settings. |
11857 | void MaybeAddCUDAConstantAttr(VarDecl *VD); |
11858 | |
11859 | public: |
11860 | /// Check whether we're allowed to call Callee from the current context. |
11861 | /// |
11862 | /// - If the call is never allowed in a semantically-correct program |
11863 | /// (CFP_Never), emits an error and returns false. |
11864 | /// |
11865 | /// - If the call is allowed in semantically-correct programs, but only if |
11866 | /// it's never codegen'ed (CFP_WrongSide), creates a deferred diagnostic to |
11867 | /// be emitted if and when the caller is codegen'ed, and returns true. |
11868 | /// |
11869 | /// Will only create deferred diagnostics for a given SourceLocation once, |
11870 | /// so you can safely call this multiple times without generating duplicate |
11871 | /// deferred errors. |
11872 | /// |
11873 | /// - Otherwise, returns true without emitting any diagnostics. |
11874 | bool CheckCUDACall(SourceLocation Loc, FunctionDecl *Callee); |
11875 | |
11876 | void CUDACheckLambdaCapture(CXXMethodDecl *D, const sema::Capture &Capture); |
11877 | |
11878 | /// Set __device__ or __host__ __device__ attributes on the given lambda |
11879 | /// operator() method. |
11880 | /// |
11881 | /// CUDA lambdas by default is host device function unless it has explicit |
11882 | /// host or device attribute. |
11883 | void CUDASetLambdaAttrs(CXXMethodDecl *Method); |
11884 | |
11885 | /// Finds a function in \p Matches with highest calling priority |
11886 | /// from \p Caller context and erases all functions with lower |
11887 | /// calling priority. |
11888 | void EraseUnwantedCUDAMatches( |
11889 | const FunctionDecl *Caller, |
11890 | SmallVectorImpl<std::pair<DeclAccessPair, FunctionDecl *>> &Matches); |
11891 | |
11892 | /// Given a implicit special member, infer its CUDA target from the |
11893 | /// calls it needs to make to underlying base/field special members. |
11894 | /// \param ClassDecl the class for which the member is being created. |
11895 | /// \param CSM the kind of special member. |
11896 | /// \param MemberDecl the special member itself. |
11897 | /// \param ConstRHS true if this is a copy operation with a const object on |
11898 | /// its RHS. |
11899 | /// \param Diagnose true if this call should emit diagnostics. |
11900 | /// \return true if there was an error inferring. |
11901 | /// The result of this call is implicit CUDA target attribute(s) attached to |
11902 | /// the member declaration. |
11903 | bool inferCUDATargetForImplicitSpecialMember(CXXRecordDecl *ClassDecl, |
11904 | CXXSpecialMember CSM, |
11905 | CXXMethodDecl *MemberDecl, |
11906 | bool ConstRHS, |
11907 | bool Diagnose); |
11908 | |
11909 | /// \return true if \p CD can be considered empty according to CUDA |
11910 | /// (E.2.3.1 in CUDA 7.5 Programming guide). |
11911 | bool isEmptyCudaConstructor(SourceLocation Loc, CXXConstructorDecl *CD); |
11912 | bool isEmptyCudaDestructor(SourceLocation Loc, CXXDestructorDecl *CD); |
11913 | |
11914 | // \brief Checks that initializers of \p Var satisfy CUDA restrictions. In |
11915 | // case of error emits appropriate diagnostic and invalidates \p Var. |
11916 | // |
11917 | // \details CUDA allows only empty constructors as initializers for global |
11918 | // variables (see E.2.3.1, CUDA 7.5). The same restriction also applies to all |
11919 | // __shared__ variables whether they are local or not (they all are implicitly |
11920 | // static in CUDA). One exception is that CUDA allows constant initializers |
11921 | // for __constant__ and __device__ variables. |
11922 | void checkAllowedCUDAInitializer(VarDecl *VD); |
11923 | |
11924 | /// Check whether NewFD is a valid overload for CUDA. Emits |
11925 | /// diagnostics and invalidates NewFD if not. |
11926 | void checkCUDATargetOverload(FunctionDecl *NewFD, |
11927 | const LookupResult &Previous); |
11928 | /// Copies target attributes from the template TD to the function FD. |
11929 | void inheritCUDATargetAttrs(FunctionDecl *FD, const FunctionTemplateDecl &TD); |
11930 | |
11931 | /// Returns the name of the launch configuration function. This is the name |
11932 | /// of the function that will be called to configure kernel call, with the |
11933 | /// parameters specified via <<<>>>. |
11934 | std::string getCudaConfigureFuncName() const; |
11935 | |
11936 | /// \name Code completion |
11937 | //@{ |
11938 | /// Describes the context in which code completion occurs. |
11939 | enum ParserCompletionContext { |
11940 | /// Code completion occurs at top-level or namespace context. |
11941 | PCC_Namespace, |
11942 | /// Code completion occurs within a class, struct, or union. |
11943 | PCC_Class, |
11944 | /// Code completion occurs within an Objective-C interface, protocol, |
11945 | /// or category. |
11946 | PCC_ObjCInterface, |
11947 | /// Code completion occurs within an Objective-C implementation or |
11948 | /// category implementation |
11949 | PCC_ObjCImplementation, |
11950 | /// Code completion occurs within the list of instance variables |
11951 | /// in an Objective-C interface, protocol, category, or implementation. |
11952 | PCC_ObjCInstanceVariableList, |
11953 | /// Code completion occurs following one or more template |
11954 | /// headers. |
11955 | PCC_Template, |
11956 | /// Code completion occurs following one or more template |
11957 | /// headers within a class. |
11958 | PCC_MemberTemplate, |
11959 | /// Code completion occurs within an expression. |
11960 | PCC_Expression, |
11961 | /// Code completion occurs within a statement, which may |
11962 | /// also be an expression or a declaration. |
11963 | PCC_Statement, |
11964 | /// Code completion occurs at the beginning of the |
11965 | /// initialization statement (or expression) in a for loop. |
11966 | PCC_ForInit, |
11967 | /// Code completion occurs within the condition of an if, |
11968 | /// while, switch, or for statement. |
11969 | PCC_Condition, |
11970 | /// Code completion occurs within the body of a function on a |
11971 | /// recovery path, where we do not have a specific handle on our position |
11972 | /// in the grammar. |
11973 | PCC_RecoveryInFunction, |
11974 | /// Code completion occurs where only a type is permitted. |
11975 | PCC_Type, |
11976 | /// Code completion occurs in a parenthesized expression, which |
11977 | /// might also be a type cast. |
11978 | PCC_ParenthesizedExpression, |
11979 | /// Code completion occurs within a sequence of declaration |
11980 | /// specifiers within a function, method, or block. |
11981 | PCC_LocalDeclarationSpecifiers |
11982 | }; |
11983 | |
11984 | void CodeCompleteModuleImport(SourceLocation ImportLoc, ModuleIdPath Path); |
11985 | void CodeCompleteOrdinaryName(Scope *S, |
11986 | ParserCompletionContext CompletionContext); |
11987 | void CodeCompleteDeclSpec(Scope *S, DeclSpec &DS, |
11988 | bool AllowNonIdentifiers, |
11989 | bool AllowNestedNameSpecifiers); |
11990 | |
11991 | struct CodeCompleteExpressionData; |
11992 | void CodeCompleteExpression(Scope *S, |
11993 | const CodeCompleteExpressionData &Data); |
11994 | void CodeCompleteExpression(Scope *S, QualType PreferredType, |
11995 | bool IsParenthesized = false); |
11996 | void CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, Expr *OtherOpBase, |
11997 | SourceLocation OpLoc, bool IsArrow, |
11998 | bool IsBaseExprStatement, |
11999 | QualType PreferredType); |
12000 | void CodeCompletePostfixExpression(Scope *S, ExprResult LHS, |
12001 | QualType PreferredType); |
12002 | void CodeCompleteTag(Scope *S, unsigned TagSpec); |
12003 | void CodeCompleteTypeQualifiers(DeclSpec &DS); |
12004 | void CodeCompleteFunctionQualifiers(DeclSpec &DS, Declarator &D, |
12005 | const VirtSpecifiers *VS = nullptr); |
12006 | void CodeCompleteBracketDeclarator(Scope *S); |
12007 | void CodeCompleteCase(Scope *S); |
12008 | /// Reports signatures for a call to CodeCompleteConsumer and returns the |
12009 | /// preferred type for the current argument. Returned type can be null. |
12010 | QualType ProduceCallSignatureHelp(Scope *S, Expr *Fn, ArrayRef<Expr *> Args, |
12011 | SourceLocation OpenParLoc); |
12012 | QualType ProduceConstructorSignatureHelp(Scope *S, QualType Type, |
12013 | SourceLocation Loc, |
12014 | ArrayRef<Expr *> Args, |
12015 | SourceLocation OpenParLoc); |
12016 | QualType ProduceCtorInitMemberSignatureHelp(Scope *S, Decl *ConstructorDecl, |
12017 | CXXScopeSpec SS, |
12018 | ParsedType TemplateTypeTy, |
12019 | ArrayRef<Expr *> ArgExprs, |
12020 | IdentifierInfo *II, |
12021 | SourceLocation OpenParLoc); |
12022 | void CodeCompleteInitializer(Scope *S, Decl *D); |
12023 | /// Trigger code completion for a record of \p BaseType. \p InitExprs are |
12024 | /// expressions in the initializer list seen so far and \p D is the current |
12025 | /// Designation being parsed. |
12026 | void CodeCompleteDesignator(const QualType BaseType, |
12027 | llvm::ArrayRef<Expr *> InitExprs, |
12028 | const Designation &D); |
12029 | void CodeCompleteAfterIf(Scope *S, bool IsBracedThen); |
12030 | |
12031 | void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, bool EnteringContext, |
12032 | bool IsUsingDeclaration, QualType BaseType, |
12033 | QualType PreferredType); |
12034 | void CodeCompleteUsing(Scope *S); |
12035 | void CodeCompleteUsingDirective(Scope *S); |
12036 | void CodeCompleteNamespaceDecl(Scope *S); |
12037 | void CodeCompleteNamespaceAliasDecl(Scope *S); |
12038 | void CodeCompleteOperatorName(Scope *S); |
12039 | void CodeCompleteConstructorInitializer( |
12040 | Decl *Constructor, |
12041 | ArrayRef<CXXCtorInitializer *> Initializers); |
12042 | |
12043 | void CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro, |
12044 | bool AfterAmpersand); |
12045 | void CodeCompleteAfterFunctionEquals(Declarator &D); |
12046 | |
12047 | void CodeCompleteObjCAtDirective(Scope *S); |
12048 | void CodeCompleteObjCAtVisibility(Scope *S); |
12049 | void CodeCompleteObjCAtStatement(Scope *S); |
12050 | void CodeCompleteObjCAtExpression(Scope *S); |
12051 | void CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS); |
12052 | void CodeCompleteObjCPropertyGetter(Scope *S); |
12053 | void CodeCompleteObjCPropertySetter(Scope *S); |
12054 | void CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS, |
12055 | bool IsParameter); |
12056 | void CodeCompleteObjCMessageReceiver(Scope *S); |
12057 | void CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc, |
12058 | ArrayRef<IdentifierInfo *> SelIdents, |
12059 | bool AtArgumentExpression); |
12060 | void CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver, |
12061 | ArrayRef<IdentifierInfo *> SelIdents, |
12062 | bool AtArgumentExpression, |
12063 | bool IsSuper = false); |
12064 | void CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver, |
12065 | ArrayRef<IdentifierInfo *> SelIdents, |
12066 | bool AtArgumentExpression, |
12067 | ObjCInterfaceDecl *Super = nullptr); |
12068 | void CodeCompleteObjCForCollection(Scope *S, |
12069 | DeclGroupPtrTy IterationVar); |
12070 | void CodeCompleteObjCSelector(Scope *S, |
12071 | ArrayRef<IdentifierInfo *> SelIdents); |
12072 | void CodeCompleteObjCProtocolReferences( |
12073 | ArrayRef<IdentifierLocPair> Protocols); |
12074 | void CodeCompleteObjCProtocolDecl(Scope *S); |
12075 | void CodeCompleteObjCInterfaceDecl(Scope *S); |
12076 | void CodeCompleteObjCSuperclass(Scope *S, |
12077 | IdentifierInfo *ClassName, |
12078 | SourceLocation ClassNameLoc); |
12079 | void CodeCompleteObjCImplementationDecl(Scope *S); |
12080 | void CodeCompleteObjCInterfaceCategory(Scope *S, |
12081 | IdentifierInfo *ClassName, |
12082 | SourceLocation ClassNameLoc); |
12083 | void CodeCompleteObjCImplementationCategory(Scope *S, |
12084 | IdentifierInfo *ClassName, |
12085 | SourceLocation ClassNameLoc); |
12086 | void CodeCompleteObjCPropertyDefinition(Scope *S); |
12087 | void CodeCompleteObjCPropertySynthesizeIvar(Scope *S, |
12088 | IdentifierInfo *PropertyName); |
12089 | void CodeCompleteObjCMethodDecl(Scope *S, Optional<bool> IsInstanceMethod, |
12090 | ParsedType ReturnType); |
12091 | void CodeCompleteObjCMethodDeclSelector(Scope *S, |
12092 | bool IsInstanceMethod, |
12093 | bool AtParameterName, |
12094 | ParsedType ReturnType, |
12095 | ArrayRef<IdentifierInfo *> SelIdents); |
12096 | void CodeCompleteObjCClassPropertyRefExpr(Scope *S, IdentifierInfo &ClassName, |
12097 | SourceLocation ClassNameLoc, |
12098 | bool IsBaseExprStatement); |
12099 | void CodeCompletePreprocessorDirective(bool InConditional); |
12100 | void CodeCompleteInPreprocessorConditionalExclusion(Scope *S); |
12101 | void CodeCompletePreprocessorMacroName(bool IsDefinition); |
12102 | void CodeCompletePreprocessorExpression(); |
12103 | void CodeCompletePreprocessorMacroArgument(Scope *S, |
12104 | IdentifierInfo *Macro, |
12105 | MacroInfo *MacroInfo, |
12106 | unsigned Argument); |
12107 | void CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled); |
12108 | void CodeCompleteNaturalLanguage(); |
12109 | void CodeCompleteAvailabilityPlatformName(); |
12110 | void GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator, |
12111 | CodeCompletionTUInfo &CCTUInfo, |
12112 | SmallVectorImpl<CodeCompletionResult> &Results); |
12113 | //@} |
12114 | |
12115 | //===--------------------------------------------------------------------===// |
12116 | // Extra semantic analysis beyond the C type system |
12117 | |
12118 | public: |
12119 | SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL, |
12120 | unsigned ByteNo) const; |
12121 | |
12122 | private: |
12123 | void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr, |
12124 | const ArraySubscriptExpr *ASE=nullptr, |
12125 | bool AllowOnePastEnd=true, bool IndexNegated=false); |
12126 | void CheckArrayAccess(const Expr *E); |
12127 | // Used to grab the relevant information from a FormatAttr and a |
12128 | // FunctionDeclaration. |
12129 | struct FormatStringInfo { |
12130 | unsigned FormatIdx; |
12131 | unsigned FirstDataArg; |
12132 | bool HasVAListArg; |
12133 | }; |
12134 | |
12135 | static bool getFormatStringInfo(const FormatAttr *Format, bool IsCXXMember, |
12136 | FormatStringInfo *FSI); |
12137 | bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, |
12138 | const FunctionProtoType *Proto); |
12139 | bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc, |
12140 | ArrayRef<const Expr *> Args); |
12141 | bool CheckPointerCall(NamedDecl *NDecl, CallExpr *TheCall, |
12142 | const FunctionProtoType *Proto); |
12143 | bool CheckOtherCall(CallExpr *TheCall, const FunctionProtoType *Proto); |
12144 | void CheckConstructorCall(FunctionDecl *FDecl, |
12145 | ArrayRef<const Expr *> Args, |
12146 | const FunctionProtoType *Proto, |
12147 | SourceLocation Loc); |
12148 | |
12149 | void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, |
12150 | const Expr *ThisArg, ArrayRef<const Expr *> Args, |
12151 | bool IsMemberFunction, SourceLocation Loc, SourceRange Range, |
12152 | VariadicCallType CallType); |
12153 | |
12154 | bool CheckObjCString(Expr *Arg); |
12155 | ExprResult CheckOSLogFormatStringArg(Expr *Arg); |
12156 | |
12157 | ExprResult CheckBuiltinFunctionCall(FunctionDecl *FDecl, |
12158 | unsigned BuiltinID, CallExpr *TheCall); |
12159 | |
12160 | bool CheckTSBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, |
12161 | CallExpr *TheCall); |
12162 | |
12163 | void checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, CallExpr *TheCall); |
12164 | |
12165 | bool CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall, |
12166 | unsigned MaxWidth); |
12167 | bool CheckNeonBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, |
12168 | CallExpr *TheCall); |
12169 | bool CheckMVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); |
12170 | bool CheckSVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); |
12171 | bool CheckCDEBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, |
12172 | CallExpr *TheCall); |
12173 | bool CheckARMCoprocessorImmediate(const TargetInfo &TI, const Expr *CoprocArg, |
12174 | bool WantCDE); |
12175 | bool CheckARMBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, |
12176 | CallExpr *TheCall); |
12177 | |
12178 | bool CheckAArch64BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, |
12179 | CallExpr *TheCall); |
12180 | bool CheckBPFBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); |
12181 | bool CheckHexagonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); |
12182 | bool CheckHexagonBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall); |
12183 | bool CheckMipsBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, |
12184 | CallExpr *TheCall); |
12185 | bool CheckMipsBuiltinCpu(const TargetInfo &TI, unsigned BuiltinID, |
12186 | CallExpr *TheCall); |
12187 | bool CheckMipsBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall); |
12188 | bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); |
12189 | bool CheckX86BuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall); |
12190 | bool CheckX86BuiltinGatherScatterScale(unsigned BuiltinID, CallExpr *TheCall); |
12191 | bool CheckX86BuiltinTileArguments(unsigned BuiltinID, CallExpr *TheCall); |
12192 | bool CheckX86BuiltinTileArgumentsRange(CallExpr *TheCall, |
12193 | ArrayRef<int> ArgNums); |
12194 | bool CheckX86BuiltinTileDuplicate(CallExpr *TheCall, ArrayRef<int> ArgNums); |
12195 | bool CheckX86BuiltinTileRangeAndDuplicate(CallExpr *TheCall, |
12196 | ArrayRef<int> ArgNums); |
12197 | bool CheckX86BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, |
12198 | CallExpr *TheCall); |
12199 | bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, |
12200 | CallExpr *TheCall); |
12201 | bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); |
12202 | |
12203 | bool SemaBuiltinVAStart(unsigned BuiltinID, CallExpr *TheCall); |
12204 | bool SemaBuiltinVAStartARMMicrosoft(CallExpr *Call); |
12205 | bool SemaBuiltinUnorderedCompare(CallExpr *TheCall); |
12206 | bool SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs); |
12207 | bool SemaBuiltinComplex(CallExpr *TheCall); |
12208 | bool SemaBuiltinVSX(CallExpr *TheCall); |
12209 | bool SemaBuiltinOSLogFormat(CallExpr *TheCall); |
12210 | |
12211 | public: |
12212 | // Used by C++ template instantiation. |
12213 | ExprResult SemaBuiltinShuffleVector(CallExpr *TheCall); |
12214 | ExprResult SemaConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo, |
12215 | SourceLocation BuiltinLoc, |
12216 | SourceLocation RParenLoc); |
12217 | |
12218 | private: |
12219 | bool SemaBuiltinPrefetch(CallExpr *TheCall); |
12220 | bool SemaBuiltinAllocaWithAlign(CallExpr *TheCall); |
12221 | bool SemaBuiltinAssume(CallExpr *TheCall); |
12222 | bool SemaBuiltinAssumeAligned(CallExpr *TheCall); |
12223 | bool SemaBuiltinLongjmp(CallExpr *TheCall); |
12224 | bool SemaBuiltinSetjmp(CallExpr *TheCall); |
12225 | ExprResult SemaBuiltinAtomicOverloaded(ExprResult TheCallResult); |
12226 | ExprResult SemaBuiltinNontemporalOverloaded(ExprResult TheCallResult); |
12227 | ExprResult SemaAtomicOpsOverloaded(ExprResult TheCallResult, |
12228 | AtomicExpr::AtomicOp Op); |
12229 | ExprResult SemaBuiltinOperatorNewDeleteOverloaded(ExprResult TheCallResult, |
12230 | bool IsDelete); |
12231 | bool SemaBuiltinConstantArg(CallExpr *TheCall, int ArgNum, |
12232 | llvm::APSInt &Result); |
12233 | bool SemaBuiltinConstantArgRange(CallExpr *TheCall, int ArgNum, int Low, |
12234 | int High, bool RangeIsError = true); |
12235 | bool SemaBuiltinConstantArgMultiple(CallExpr *TheCall, int ArgNum, |
12236 | unsigned Multiple); |
12237 | bool SemaBuiltinConstantArgPower2(CallExpr *TheCall, int ArgNum); |
12238 | bool SemaBuiltinConstantArgShiftedByte(CallExpr *TheCall, int ArgNum, |
12239 | unsigned ArgBits); |
12240 | bool SemaBuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, int ArgNum, |
12241 | unsigned ArgBits); |
12242 | bool SemaBuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall, |
12243 | int ArgNum, unsigned ExpectedFieldNum, |
12244 | bool AllowName); |
12245 | bool SemaBuiltinARMMemoryTaggingCall(unsigned BuiltinID, CallExpr *TheCall); |
12246 | |
12247 | // Matrix builtin handling. |
12248 | ExprResult SemaBuiltinMatrixTranspose(CallExpr *TheCall, |
12249 | ExprResult CallResult); |
12250 | ExprResult SemaBuiltinMatrixColumnMajorLoad(CallExpr *TheCall, |
12251 | ExprResult CallResult); |
12252 | ExprResult SemaBuiltinMatrixColumnMajorStore(CallExpr *TheCall, |
12253 | ExprResult CallResult); |
12254 | |
12255 | public: |
12256 | enum FormatStringType { |
12257 | FST_Scanf, |
12258 | FST_Printf, |
12259 | FST_NSString, |
12260 | FST_Strftime, |
12261 | FST_Strfmon, |
12262 | FST_Kprintf, |
12263 | FST_FreeBSDKPrintf, |
12264 | FST_OSTrace, |
12265 | FST_OSLog, |
12266 | FST_Unknown |
12267 | }; |
12268 | static FormatStringType GetFormatStringType(const FormatAttr *Format); |
12269 | |
12270 | bool FormatStringHasSArg(const StringLiteral *FExpr); |
12271 | |
12272 | static bool GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx); |
12273 | |
12274 | private: |
12275 | bool CheckFormatArguments(const FormatAttr *Format, |
12276 | ArrayRef<const Expr *> Args, |
12277 | bool IsCXXMember, |
12278 | VariadicCallType CallType, |
12279 | SourceLocation Loc, SourceRange Range, |
12280 | llvm::SmallBitVector &CheckedVarArgs); |
12281 | bool CheckFormatArguments(ArrayRef<const Expr *> Args, |
12282 | bool HasVAListArg, unsigned format_idx, |
12283 | unsigned firstDataArg, FormatStringType Type, |
12284 | VariadicCallType CallType, |
12285 | SourceLocation Loc, SourceRange range, |
12286 | llvm::SmallBitVector &CheckedVarArgs); |
12287 | |
12288 | void CheckAbsoluteValueFunction(const CallExpr *Call, |
12289 | const FunctionDecl *FDecl); |
12290 | |
12291 | void CheckMaxUnsignedZero(const CallExpr *Call, const FunctionDecl *FDecl); |
12292 | |
12293 | void CheckMemaccessArguments(const CallExpr *Call, |
12294 | unsigned BId, |
12295 | IdentifierInfo *FnName); |
12296 | |
12297 | void CheckStrlcpycatArguments(const CallExpr *Call, |
12298 | IdentifierInfo *FnName); |
12299 | |
12300 | void CheckStrncatArguments(const CallExpr *Call, |
12301 | IdentifierInfo *FnName); |
12302 | |
12303 | void CheckReturnValExpr(Expr *RetValExp, QualType lhsType, |
12304 | SourceLocation ReturnLoc, |
12305 | bool isObjCMethod = false, |
12306 | const AttrVec *Attrs = nullptr, |
12307 | const FunctionDecl *FD = nullptr); |
12308 | |
12309 | public: |
12310 | void CheckFloatComparison(SourceLocation Loc, Expr *LHS, Expr *RHS); |
12311 | |
12312 | private: |
12313 | void CheckImplicitConversions(Expr *E, SourceLocation CC = SourceLocation()); |
12314 | void CheckBoolLikeConversion(Expr *E, SourceLocation CC); |
12315 | void CheckForIntOverflow(Expr *E); |
12316 | void CheckUnsequencedOperations(const Expr *E); |
12317 | |
12318 | /// Perform semantic checks on a completed expression. This will either |
12319 | /// be a full-expression or a default argument expression. |
12320 | void CheckCompletedExpr(Expr *E, SourceLocation CheckLoc = SourceLocation(), |
12321 | bool IsConstexpr = false); |
12322 | |
12323 | void CheckBitFieldInitialization(SourceLocation InitLoc, FieldDecl *Field, |
12324 | Expr *Init); |
12325 | |
12326 | /// Check if there is a field shadowing. |
12327 | void CheckShadowInheritedFields(const SourceLocation &Loc, |
12328 | DeclarationName FieldName, |
12329 | const CXXRecordDecl *RD, |
12330 | bool DeclIsField = true); |
12331 | |
12332 | /// Check if the given expression contains 'break' or 'continue' |
12333 | /// statement that produces control flow different from GCC. |
12334 | void CheckBreakContinueBinding(Expr *E); |
12335 | |
12336 | /// Check whether receiver is mutable ObjC container which |
12337 | /// attempts to add itself into the container |
12338 | void CheckObjCCircularContainer(ObjCMessageExpr *Message); |
12339 | |
12340 | void AnalyzeDeleteExprMismatch(const CXXDeleteExpr *DE); |
12341 | void AnalyzeDeleteExprMismatch(FieldDecl *Field, SourceLocation DeleteLoc, |
12342 | bool DeleteWasArrayForm); |
12343 | public: |
12344 | /// Register a magic integral constant to be used as a type tag. |
12345 | void RegisterTypeTagForDatatype(const IdentifierInfo *ArgumentKind, |
12346 | uint64_t MagicValue, QualType Type, |
12347 | bool LayoutCompatible, bool MustBeNull); |
12348 | |
12349 | struct TypeTagData { |
12350 | TypeTagData() {} |
12351 | |
12352 | TypeTagData(QualType Type, bool LayoutCompatible, bool MustBeNull) : |
12353 | Type(Type), LayoutCompatible(LayoutCompatible), |
12354 | MustBeNull(MustBeNull) |
12355 | {} |
12356 | |
12357 | QualType Type; |
12358 | |
12359 | /// If true, \c Type should be compared with other expression's types for |
12360 | /// layout-compatibility. |
12361 | unsigned LayoutCompatible : 1; |
12362 | unsigned MustBeNull : 1; |
12363 | }; |
12364 | |
12365 | /// A pair of ArgumentKind identifier and magic value. This uniquely |
12366 | /// identifies the magic value. |
12367 | typedef std::pair<const IdentifierInfo *, uint64_t> TypeTagMagicValue; |
12368 | |
12369 | private: |
12370 | /// A map from magic value to type information. |
12371 | std::unique_ptr<llvm::DenseMap<TypeTagMagicValue, TypeTagData>> |
12372 | TypeTagForDatatypeMagicValues; |
12373 | |
12374 | /// Peform checks on a call of a function with argument_with_type_tag |
12375 | /// or pointer_with_type_tag attributes. |
12376 | void CheckArgumentWithTypeTag(const ArgumentWithTypeTagAttr *Attr, |
12377 | const ArrayRef<const Expr *> ExprArgs, |
12378 | SourceLocation CallSiteLoc); |
12379 | |
12380 | /// Check if we are taking the address of a packed field |
12381 | /// as this may be a problem if the pointer value is dereferenced. |
12382 | void CheckAddressOfPackedMember(Expr *rhs); |
12383 | |
12384 | /// The parser's current scope. |
12385 | /// |
12386 | /// The parser maintains this state here. |
12387 | Scope *CurScope; |
12388 | |
12389 | mutable IdentifierInfo *Ident_super; |
12390 | mutable IdentifierInfo *Ident___float128; |
12391 | |
12392 | /// Nullability type specifiers. |
12393 | IdentifierInfo *Ident__Nonnull = nullptr; |
12394 | IdentifierInfo *Ident__Nullable = nullptr; |
12395 | IdentifierInfo *Ident__Null_unspecified = nullptr; |
12396 | |
12397 | IdentifierInfo *Ident_NSError = nullptr; |
12398 | |
12399 | /// The handler for the FileChanged preprocessor events. |
12400 | /// |
12401 | /// Used for diagnostics that implement custom semantic analysis for #include |
12402 | /// directives, like -Wpragma-pack. |
12403 | sema::SemaPPCallbacks *SemaPPCallbackHandler; |
12404 | |
12405 | protected: |
12406 | friend class Parser; |
12407 | friend class InitializationSequence; |
12408 | friend class ASTReader; |
12409 | friend class ASTDeclReader; |
12410 | friend class ASTWriter; |
12411 | |
12412 | public: |
12413 | /// Retrieve the keyword associated |
12414 | IdentifierInfo *getNullabilityKeyword(NullabilityKind nullability); |
12415 | |
12416 | /// The struct behind the CFErrorRef pointer. |
12417 | RecordDecl *CFError = nullptr; |
12418 | bool isCFError(RecordDecl *D); |
12419 | |
12420 | /// Retrieve the identifier "NSError". |
12421 | IdentifierInfo *getNSErrorIdent(); |
12422 | |
12423 | /// Retrieve the parser's current scope. |
12424 | /// |
12425 | /// This routine must only be used when it is certain that semantic analysis |
12426 | /// and the parser are in precisely the same context, which is not the case |
12427 | /// when, e.g., we are performing any kind of template instantiation. |
12428 | /// Therefore, the only safe places to use this scope are in the parser |
12429 | /// itself and in routines directly invoked from the parser and *never* from |
12430 | /// template substitution or instantiation. |
12431 | Scope *getCurScope() const { return CurScope; } |
12432 | |
12433 | void incrementMSManglingNumber() const { |
12434 | return CurScope->incrementMSManglingNumber(); |
12435 | } |
12436 | |
12437 | IdentifierInfo *getSuperIdentifier() const; |
12438 | IdentifierInfo *getFloat128Identifier() const; |
12439 | |
12440 | Decl *getObjCDeclContext() const; |
12441 | |
12442 | DeclContext *getCurLexicalContext() const { |
12443 | return OriginalLexicalContext ? OriginalLexicalContext : CurContext; |
12444 | } |
12445 | |
12446 | const DeclContext *getCurObjCLexicalContext() const { |
12447 | const DeclContext *DC = getCurLexicalContext(); |
12448 | // A category implicitly has the attribute of the interface. |
12449 | if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(DC)) |
12450 | DC = CatD->getClassInterface(); |
12451 | return DC; |
12452 | } |
12453 | |
12454 | /// Determine the number of levels of enclosing template parameters. This is |
12455 | /// only usable while parsing. Note that this does not include dependent |
12456 | /// contexts in which no template parameters have yet been declared, such as |
12457 | /// in a terse function template or generic lambda before the first 'auto' is |
12458 | /// encountered. |
12459 | unsigned getTemplateDepth(Scope *S) const; |
12460 | |
12461 | /// To be used for checking whether the arguments being passed to |
12462 | /// function exceeds the number of parameters expected for it. |
12463 | static bool TooManyArguments(size_t NumParams, size_t NumArgs, |
12464 | bool PartialOverloading = false) { |
12465 | // We check whether we're just after a comma in code-completion. |
12466 | if (NumArgs > 0 && PartialOverloading) |
12467 | return NumArgs + 1 > NumParams; // If so, we view as an extra argument. |
12468 | return NumArgs > NumParams; |
12469 | } |
12470 | |
12471 | // Emitting members of dllexported classes is delayed until the class |
12472 | // (including field initializers) is fully parsed. |
12473 | SmallVector<CXXRecordDecl*, 4> DelayedDllExportClasses; |
12474 | SmallVector<CXXMethodDecl*, 4> DelayedDllExportMemberFunctions; |
12475 | |
12476 | private: |
12477 | int ParsingClassDepth = 0; |
12478 | |
12479 | class SavePendingParsedClassStateRAII { |
12480 | public: |
12481 | SavePendingParsedClassStateRAII(Sema &S) : S(S) { swapSavedState(); } |
12482 | |
12483 | ~SavePendingParsedClassStateRAII() { |
12484 | assert(S.DelayedOverridingExceptionSpecChecks.empty() &&((S.DelayedOverridingExceptionSpecChecks.empty() && "there shouldn't be any pending delayed exception spec checks" ) ? static_cast<void> (0) : __assert_fail ("S.DelayedOverridingExceptionSpecChecks.empty() && \"there shouldn't be any pending delayed exception spec checks\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 12485, __PRETTY_FUNCTION__)) |
12485 | "there shouldn't be any pending delayed exception spec checks")((S.DelayedOverridingExceptionSpecChecks.empty() && "there shouldn't be any pending delayed exception spec checks" ) ? static_cast<void> (0) : __assert_fail ("S.DelayedOverridingExceptionSpecChecks.empty() && \"there shouldn't be any pending delayed exception spec checks\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 12485, __PRETTY_FUNCTION__)); |
12486 | assert(S.DelayedEquivalentExceptionSpecChecks.empty() &&((S.DelayedEquivalentExceptionSpecChecks.empty() && "there shouldn't be any pending delayed exception spec checks" ) ? static_cast<void> (0) : __assert_fail ("S.DelayedEquivalentExceptionSpecChecks.empty() && \"there shouldn't be any pending delayed exception spec checks\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 12487, __PRETTY_FUNCTION__)) |
12487 | "there shouldn't be any pending delayed exception spec checks")((S.DelayedEquivalentExceptionSpecChecks.empty() && "there shouldn't be any pending delayed exception spec checks" ) ? static_cast<void> (0) : __assert_fail ("S.DelayedEquivalentExceptionSpecChecks.empty() && \"there shouldn't be any pending delayed exception spec checks\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include/clang/Sema/Sema.h" , 12487, __PRETTY_FUNCTION__)); |
12488 | swapSavedState(); |
12489 | } |
12490 | |
12491 | private: |
12492 | Sema &S; |
12493 | decltype(DelayedOverridingExceptionSpecChecks) |
12494 | SavedOverridingExceptionSpecChecks; |
12495 | decltype(DelayedEquivalentExceptionSpecChecks) |
12496 | SavedEquivalentExceptionSpecChecks; |
12497 | |
12498 | void swapSavedState() { |
12499 | SavedOverridingExceptionSpecChecks.swap( |
12500 | S.DelayedOverridingExceptionSpecChecks); |
12501 | SavedEquivalentExceptionSpecChecks.swap( |
12502 | S.DelayedEquivalentExceptionSpecChecks); |
12503 | } |
12504 | }; |
12505 | |
12506 | /// Helper class that collects misaligned member designations and |
12507 | /// their location info for delayed diagnostics. |
12508 | struct MisalignedMember { |
12509 | Expr *E; |
12510 | RecordDecl *RD; |
12511 | ValueDecl *MD; |
12512 | CharUnits Alignment; |
12513 | |
12514 | MisalignedMember() : E(), RD(), MD(), Alignment() {} |
12515 | MisalignedMember(Expr *E, RecordDecl *RD, ValueDecl *MD, |
12516 | CharUnits Alignment) |
12517 | : E(E), RD(RD), MD(MD), Alignment(Alignment) {} |
12518 | explicit MisalignedMember(Expr *E) |
12519 | : MisalignedMember(E, nullptr, nullptr, CharUnits()) {} |
12520 | |
12521 | bool operator==(const MisalignedMember &m) { return this->E == m.E; } |
12522 | }; |
12523 | /// Small set of gathered accesses to potentially misaligned members |
12524 | /// due to the packed attribute. |
12525 | SmallVector<MisalignedMember, 4> MisalignedMembers; |
12526 | |
12527 | /// Adds an expression to the set of gathered misaligned members. |
12528 | void AddPotentialMisalignedMembers(Expr *E, RecordDecl *RD, ValueDecl *MD, |
12529 | CharUnits Alignment); |
12530 | |
12531 | public: |
12532 | /// Diagnoses the current set of gathered accesses. This typically |
12533 | /// happens at full expression level. The set is cleared after emitting the |
12534 | /// diagnostics. |
12535 | void DiagnoseMisalignedMembers(); |
12536 | |
12537 | /// This function checks if the expression is in the sef of potentially |
12538 | /// misaligned members and it is converted to some pointer type T with lower |
12539 | /// or equal alignment requirements. If so it removes it. This is used when |
12540 | /// we do not want to diagnose such misaligned access (e.g. in conversions to |
12541 | /// void*). |
12542 | void DiscardMisalignedMemberAddress(const Type *T, Expr *E); |
12543 | |
12544 | /// This function calls Action when it determines that E designates a |
12545 | /// misaligned member due to the packed attribute. This is used to emit |
12546 | /// local diagnostics like in reference binding. |
12547 | void RefersToMemberWithReducedAlignment( |
12548 | Expr *E, |
12549 | llvm::function_ref<void(Expr *, RecordDecl *, FieldDecl *, CharUnits)> |
12550 | Action); |
12551 | |
12552 | /// Describes the reason a calling convention specification was ignored, used |
12553 | /// for diagnostics. |
12554 | enum class CallingConventionIgnoredReason { |
12555 | ForThisTarget = 0, |
12556 | VariadicFunction, |
12557 | ConstructorDestructor, |
12558 | BuiltinFunction |
12559 | }; |
12560 | /// Creates a DeviceDiagBuilder that emits the diagnostic if the current |
12561 | /// context is "used as device code". |
12562 | /// |
12563 | /// - If CurLexicalContext is a kernel function or it is known that the |
12564 | /// function will be emitted for the device, emits the diagnostics |
12565 | /// immediately. |
12566 | /// - If CurLexicalContext is a function and we are compiling |
12567 | /// for the device, but we don't know that this function will be codegen'ed |
12568 | /// for devive yet, creates a diagnostic which is emitted if and when we |
12569 | /// realize that the function will be codegen'ed. |
12570 | /// |
12571 | /// Example usage: |
12572 | /// |
12573 | /// Diagnose __float128 type usage only from SYCL device code if the current |
12574 | /// target doesn't support it |
12575 | /// if (!S.Context.getTargetInfo().hasFloat128Type() && |
12576 | /// S.getLangOpts().SYCLIsDevice) |
12577 | /// SYCLDiagIfDeviceCode(Loc, diag::err_type_unsupported) << "__float128"; |
12578 | DeviceDiagBuilder SYCLDiagIfDeviceCode(SourceLocation Loc, unsigned DiagID); |
12579 | |
12580 | /// Check whether we're allowed to call Callee from the current context. |
12581 | /// |
12582 | /// - If the call is never allowed in a semantically-correct program |
12583 | /// emits an error and returns false. |
12584 | /// |
12585 | /// - If the call is allowed in semantically-correct programs, but only if |
12586 | /// it's never codegen'ed, creates a deferred diagnostic to be emitted if |
12587 | /// and when the caller is codegen'ed, and returns true. |
12588 | /// |
12589 | /// - Otherwise, returns true without emitting any diagnostics. |
12590 | /// |
12591 | /// Adds Callee to DeviceCallGraph if we don't know if its caller will be |
12592 | /// codegen'ed yet. |
12593 | bool checkSYCLDeviceFunction(SourceLocation Loc, FunctionDecl *Callee); |
12594 | }; |
12595 | |
12596 | /// RAII object that enters a new expression evaluation context. |
12597 | class EnterExpressionEvaluationContext { |
12598 | Sema &Actions; |
12599 | bool Entered = true; |
12600 | |
12601 | public: |
12602 | EnterExpressionEvaluationContext( |
12603 | Sema &Actions, Sema::ExpressionEvaluationContext NewContext, |
12604 | Decl *LambdaContextDecl = nullptr, |
12605 | Sema::ExpressionEvaluationContextRecord::ExpressionKind ExprContext = |
12606 | Sema::ExpressionEvaluationContextRecord::EK_Other, |
12607 | bool ShouldEnter = true) |
12608 | : Actions(Actions), Entered(ShouldEnter) { |
12609 | if (Entered) |
12610 | Actions.PushExpressionEvaluationContext(NewContext, LambdaContextDecl, |
12611 | ExprContext); |
12612 | } |
12613 | EnterExpressionEvaluationContext( |
12614 | Sema &Actions, Sema::ExpressionEvaluationContext NewContext, |
12615 | Sema::ReuseLambdaContextDecl_t, |
12616 | Sema::ExpressionEvaluationContextRecord::ExpressionKind ExprContext = |
12617 | Sema::ExpressionEvaluationContextRecord::EK_Other) |
12618 | : Actions(Actions) { |
12619 | Actions.PushExpressionEvaluationContext( |
12620 | NewContext, Sema::ReuseLambdaContextDecl, ExprContext); |
12621 | } |
12622 | |
12623 | enum InitListTag { InitList }; |
12624 | EnterExpressionEvaluationContext(Sema &Actions, InitListTag, |
12625 | bool ShouldEnter = true) |
12626 | : Actions(Actions), Entered(false) { |
12627 | // In C++11 onwards, narrowing checks are performed on the contents of |
12628 | // braced-init-lists, even when they occur within unevaluated operands. |
12629 | // Therefore we still need to instantiate constexpr functions used in such |
12630 | // a context. |
12631 | if (ShouldEnter && Actions.isUnevaluatedContext() && |
12632 | Actions.getLangOpts().CPlusPlus11) { |
12633 | Actions.PushExpressionEvaluationContext( |
12634 | Sema::ExpressionEvaluationContext::UnevaluatedList); |
12635 | Entered = true; |
12636 | } |
12637 | } |
12638 | |
12639 | ~EnterExpressionEvaluationContext() { |
12640 | if (Entered) |
12641 | Actions.PopExpressionEvaluationContext(); |
12642 | } |
12643 | }; |
12644 | |
12645 | DeductionFailureInfo |
12646 | MakeDeductionFailureInfo(ASTContext &Context, Sema::TemplateDeductionResult TDK, |
12647 | sema::TemplateDeductionInfo &Info); |
12648 | |
12649 | /// Contains a late templated function. |
12650 | /// Will be parsed at the end of the translation unit, used by Sema & Parser. |
12651 | struct LateParsedTemplate { |
12652 | CachedTokens Toks; |
12653 | /// The template function declaration to be late parsed. |
12654 | Decl *D; |
12655 | }; |
12656 | } // end namespace clang |
12657 | |
12658 | namespace llvm { |
12659 | // Hash a FunctionDeclAndLoc by looking at both its FunctionDecl and its |
12660 | // SourceLocation. |
12661 | template <> struct DenseMapInfo<clang::Sema::FunctionDeclAndLoc> { |
12662 | using FunctionDeclAndLoc = clang::Sema::FunctionDeclAndLoc; |
12663 | using FDBaseInfo = DenseMapInfo<clang::CanonicalDeclPtr<clang::FunctionDecl>>; |
12664 | |
12665 | static FunctionDeclAndLoc getEmptyKey() { |
12666 | return {FDBaseInfo::getEmptyKey(), clang::SourceLocation()}; |
12667 | } |
12668 | |
12669 | static FunctionDeclAndLoc getTombstoneKey() { |
12670 | return {FDBaseInfo::getTombstoneKey(), clang::SourceLocation()}; |
12671 | } |
12672 | |
12673 | static unsigned getHashValue(const FunctionDeclAndLoc &FDL) { |
12674 | return hash_combine(FDBaseInfo::getHashValue(FDL.FD), |
12675 | FDL.Loc.getRawEncoding()); |
12676 | } |
12677 | |
12678 | static bool isEqual(const FunctionDeclAndLoc &LHS, |
12679 | const FunctionDeclAndLoc &RHS) { |
12680 | return LHS.FD == RHS.FD && LHS.Loc == RHS.Loc; |
12681 | } |
12682 | }; |
12683 | } // namespace llvm |
12684 | |
12685 | #endif |
1 | //===- llvm/ADT/SmallVector.h - 'Normally small' vectors --------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file defines the SmallVector class. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #ifndef LLVM_ADT_SMALLVECTOR_H |
14 | #define LLVM_ADT_SMALLVECTOR_H |
15 | |
16 | #include "llvm/ADT/iterator_range.h" |
17 | #include "llvm/Support/AlignOf.h" |
18 | #include "llvm/Support/Compiler.h" |
19 | #include "llvm/Support/ErrorHandling.h" |
20 | #include "llvm/Support/MathExtras.h" |
21 | #include "llvm/Support/MemAlloc.h" |
22 | #include "llvm/Support/type_traits.h" |
23 | #include <algorithm> |
24 | #include <cassert> |
25 | #include <cstddef> |
26 | #include <cstdlib> |
27 | #include <cstring> |
28 | #include <initializer_list> |
29 | #include <iterator> |
30 | #include <limits> |
31 | #include <memory> |
32 | #include <new> |
33 | #include <type_traits> |
34 | #include <utility> |
35 | |
36 | namespace llvm { |
37 | |
38 | /// This is all the stuff common to all SmallVectors. |
39 | /// |
40 | /// The template parameter specifies the type which should be used to hold the |
41 | /// Size and Capacity of the SmallVector, so it can be adjusted. |
42 | /// Using 32 bit size is desirable to shrink the size of the SmallVector. |
43 | /// Using 64 bit size is desirable for cases like SmallVector<char>, where a |
44 | /// 32 bit size would limit the vector to ~4GB. SmallVectors are used for |
45 | /// buffering bitcode output - which can exceed 4GB. |
46 | template <class Size_T> class SmallVectorBase { |
47 | protected: |
48 | void *BeginX; |
49 | Size_T Size = 0, Capacity; |
50 | |
51 | /// The maximum value of the Size_T used. |
52 | static constexpr size_t SizeTypeMax() { |
53 | return std::numeric_limits<Size_T>::max(); |
54 | } |
55 | |
56 | SmallVectorBase() = delete; |
57 | SmallVectorBase(void *FirstEl, size_t TotalCapacity) |
58 | : BeginX(FirstEl), Capacity(TotalCapacity) {} |
59 | |
60 | /// This is an implementation of the grow() method which only works |
61 | /// on POD-like data types and is out of line to reduce code duplication. |
62 | /// This function will report a fatal error if it cannot increase capacity. |
63 | void grow_pod(void *FirstEl, size_t MinSize, size_t TSize); |
64 | |
65 | /// Report that MinSize doesn't fit into this vector's size type. Throws |
66 | /// std::length_error or calls report_fatal_error. |
67 | LLVM_ATTRIBUTE_NORETURN__attribute__((noreturn)) static void report_size_overflow(size_t MinSize); |
68 | /// Report that this vector is already at maximum capacity. Throws |
69 | /// std::length_error or calls report_fatal_error. |
70 | LLVM_ATTRIBUTE_NORETURN__attribute__((noreturn)) static void report_at_maximum_capacity(); |
71 | |
72 | public: |
73 | size_t size() const { return Size; } |
74 | size_t capacity() const { return Capacity; } |
75 | |
76 | LLVM_NODISCARD[[clang::warn_unused_result]] bool empty() const { return !Size; } |
77 | |
78 | /// Set the array size to \p N, which the current array must have enough |
79 | /// capacity for. |
80 | /// |
81 | /// This does not construct or destroy any elements in the vector. |
82 | /// |
83 | /// Clients can use this in conjunction with capacity() to write past the end |
84 | /// of the buffer when they know that more elements are available, and only |
85 | /// update the size later. This avoids the cost of value initializing elements |
86 | /// which will only be overwritten. |
87 | void set_size(size_t N) { |
88 | assert(N <= capacity())((N <= capacity()) ? static_cast<void> (0) : __assert_fail ("N <= capacity()", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/llvm/include/llvm/ADT/SmallVector.h" , 88, __PRETTY_FUNCTION__)); |
89 | Size = N; |
90 | } |
91 | }; |
92 | |
93 | template <class T> |
94 | using SmallVectorSizeType = |
95 | typename std::conditional<sizeof(T) < 4 && sizeof(void *) >= 8, uint64_t, |
96 | uint32_t>::type; |
97 | |
98 | /// Figure out the offset of the first element. |
99 | template <class T, typename = void> struct SmallVectorAlignmentAndSize { |
100 | AlignedCharArrayUnion<SmallVectorBase<SmallVectorSizeType<T>>> Base; |
101 | AlignedCharArrayUnion<T> FirstEl; |
102 | }; |
103 | |
104 | /// This is the part of SmallVectorTemplateBase which does not depend on whether |
105 | /// the type T is a POD. The extra dummy template argument is used by ArrayRef |
106 | /// to avoid unnecessarily requiring T to be complete. |
107 | template <typename T, typename = void> |
108 | class SmallVectorTemplateCommon |
109 | : public SmallVectorBase<SmallVectorSizeType<T>> { |
110 | using Base = SmallVectorBase<SmallVectorSizeType<T>>; |
111 | |
112 | /// Find the address of the first element. For this pointer math to be valid |
113 | /// with small-size of 0 for T with lots of alignment, it's important that |
114 | /// SmallVectorStorage is properly-aligned even for small-size of 0. |
115 | void *getFirstEl() const { |
116 | return const_cast<void *>(reinterpret_cast<const void *>( |
117 | reinterpret_cast<const char *>(this) + |
118 | offsetof(SmallVectorAlignmentAndSize<T>, FirstEl)__builtin_offsetof(SmallVectorAlignmentAndSize<T>, FirstEl ))); |
119 | } |
120 | // Space after 'FirstEl' is clobbered, do not add any instance vars after it. |
121 | |
122 | protected: |
123 | SmallVectorTemplateCommon(size_t Size) : Base(getFirstEl(), Size) {} |
124 | |
125 | void grow_pod(size_t MinSize, size_t TSize) { |
126 | Base::grow_pod(getFirstEl(), MinSize, TSize); |
127 | } |
128 | |
129 | /// Return true if this is a smallvector which has not had dynamic |
130 | /// memory allocated for it. |
131 | bool isSmall() const { return this->BeginX == getFirstEl(); } |
132 | |
133 | /// Put this vector in a state of being small. |
134 | void resetToSmall() { |
135 | this->BeginX = getFirstEl(); |
136 | this->Size = this->Capacity = 0; // FIXME: Setting Capacity to 0 is suspect. |
137 | } |
138 | |
139 | public: |
140 | using size_type = size_t; |
141 | using difference_type = ptrdiff_t; |
142 | using value_type = T; |
143 | using iterator = T *; |
144 | using const_iterator = const T *; |
145 | |
146 | using const_reverse_iterator = std::reverse_iterator<const_iterator>; |
147 | using reverse_iterator = std::reverse_iterator<iterator>; |
148 | |
149 | using reference = T &; |
150 | using const_reference = const T &; |
151 | using pointer = T *; |
152 | using const_pointer = const T *; |
153 | |
154 | using Base::capacity; |
155 | using Base::empty; |
156 | using Base::size; |
157 | |
158 | // forward iterator creation methods. |
159 | iterator begin() { return (iterator)this->BeginX; } |
160 | const_iterator begin() const { return (const_iterator)this->BeginX; } |
161 | iterator end() { return begin() + size(); } |
162 | const_iterator end() const { return begin() + size(); } |
163 | |
164 | // reverse iterator creation methods. |
165 | reverse_iterator rbegin() { return reverse_iterator(end()); } |
166 | const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); } |
167 | reverse_iterator rend() { return reverse_iterator(begin()); } |
168 | const_reverse_iterator rend() const { return const_reverse_iterator(begin());} |
169 | |
170 | size_type size_in_bytes() const { return size() * sizeof(T); } |
171 | size_type max_size() const { |
172 | return std::min(this->SizeTypeMax(), size_type(-1) / sizeof(T)); |
173 | } |
174 | |
175 | size_t capacity_in_bytes() const { return capacity() * sizeof(T); } |
176 | |
177 | /// Return a pointer to the vector's buffer, even if empty(). |
178 | pointer data() { return pointer(begin()); } |
179 | /// Return a pointer to the vector's buffer, even if empty(). |
180 | const_pointer data() const { return const_pointer(begin()); } |
181 | |
182 | reference operator[](size_type idx) { |
183 | assert(idx < size())((idx < size()) ? static_cast<void> (0) : __assert_fail ("idx < size()", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/llvm/include/llvm/ADT/SmallVector.h" , 183, __PRETTY_FUNCTION__)); |
184 | return begin()[idx]; |
185 | } |
186 | const_reference operator[](size_type idx) const { |
187 | assert(idx < size())((idx < size()) ? static_cast<void> (0) : __assert_fail ("idx < size()", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/llvm/include/llvm/ADT/SmallVector.h" , 187, __PRETTY_FUNCTION__)); |
188 | return begin()[idx]; |
189 | } |
190 | |
191 | reference front() { |
192 | assert(!empty())((!empty()) ? static_cast<void> (0) : __assert_fail ("!empty()" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/llvm/include/llvm/ADT/SmallVector.h" , 192, __PRETTY_FUNCTION__)); |
193 | return begin()[0]; |
194 | } |
195 | const_reference front() const { |
196 | assert(!empty())((!empty()) ? static_cast<void> (0) : __assert_fail ("!empty()" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/llvm/include/llvm/ADT/SmallVector.h" , 196, __PRETTY_FUNCTION__)); |
197 | return begin()[0]; |
198 | } |
199 | |
200 | reference back() { |
201 | assert(!empty())((!empty()) ? static_cast<void> (0) : __assert_fail ("!empty()" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/llvm/include/llvm/ADT/SmallVector.h" , 201, __PRETTY_FUNCTION__)); |
202 | return end()[-1]; |
203 | } |
204 | const_reference back() const { |
205 | assert(!empty())((!empty()) ? static_cast<void> (0) : __assert_fail ("!empty()" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/llvm/include/llvm/ADT/SmallVector.h" , 205, __PRETTY_FUNCTION__)); |
206 | return end()[-1]; |
207 | } |
208 | }; |
209 | |
210 | /// SmallVectorTemplateBase<TriviallyCopyable = false> - This is where we put |
211 | /// method implementations that are designed to work with non-trivial T's. |
212 | /// |
213 | /// We approximate is_trivially_copyable with trivial move/copy construction and |
214 | /// trivial destruction. While the standard doesn't specify that you're allowed |
215 | /// copy these types with memcpy, there is no way for the type to observe this. |
216 | /// This catches the important case of std::pair<POD, POD>, which is not |
217 | /// trivially assignable. |
218 | template <typename T, bool = (is_trivially_copy_constructible<T>::value) && |
219 | (is_trivially_move_constructible<T>::value) && |
220 | std::is_trivially_destructible<T>::value> |
221 | class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> { |
222 | protected: |
223 | SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {} |
224 | |
225 | static void destroy_range(T *S, T *E) { |
226 | while (S != E) { |
227 | --E; |
228 | E->~T(); |
229 | } |
230 | } |
231 | |
232 | /// Move the range [I, E) into the uninitialized memory starting with "Dest", |
233 | /// constructing elements as needed. |
234 | template<typename It1, typename It2> |
235 | static void uninitialized_move(It1 I, It1 E, It2 Dest) { |
236 | std::uninitialized_copy(std::make_move_iterator(I), |
237 | std::make_move_iterator(E), Dest); |
238 | } |
239 | |
240 | /// Copy the range [I, E) onto the uninitialized memory starting with "Dest", |
241 | /// constructing elements as needed. |
242 | template<typename It1, typename It2> |
243 | static void uninitialized_copy(It1 I, It1 E, It2 Dest) { |
244 | std::uninitialized_copy(I, E, Dest); |
245 | } |
246 | |
247 | /// Grow the allocated memory (without initializing new elements), doubling |
248 | /// the size of the allocated memory. Guarantees space for at least one more |
249 | /// element, or MinSize more elements if specified. |
250 | void grow(size_t MinSize = 0); |
251 | |
252 | public: |
253 | void push_back(const T &Elt) { |
254 | if (LLVM_UNLIKELY(this->size() >= this->capacity())__builtin_expect((bool)(this->size() >= this->capacity ()), false)) |
255 | this->grow(); |
256 | ::new ((void*) this->end()) T(Elt); |
257 | this->set_size(this->size() + 1); |
258 | } |
259 | |
260 | void push_back(T &&Elt) { |
261 | if (LLVM_UNLIKELY(this->size() >= this->capacity())__builtin_expect((bool)(this->size() >= this->capacity ()), false)) |
262 | this->grow(); |
263 | ::new ((void*) this->end()) T(::std::move(Elt)); |
264 | this->set_size(this->size() + 1); |
265 | } |
266 | |
267 | void pop_back() { |
268 | this->set_size(this->size() - 1); |
269 | this->end()->~T(); |
270 | } |
271 | }; |
272 | |
273 | // Define this out-of-line to dissuade the C++ compiler from inlining it. |
274 | template <typename T, bool TriviallyCopyable> |
275 | void SmallVectorTemplateBase<T, TriviallyCopyable>::grow(size_t MinSize) { |
276 | // Ensure we can fit the new capacity. |
277 | // This is only going to be applicable when the capacity is 32 bit. |
278 | if (MinSize > this->SizeTypeMax()) |
279 | this->report_size_overflow(MinSize); |
280 | |
281 | // Ensure we can meet the guarantee of space for at least one more element. |
282 | // The above check alone will not catch the case where grow is called with a |
283 | // default MinSize of 0, but the current capacity cannot be increased. |
284 | // This is only going to be applicable when the capacity is 32 bit. |
285 | if (this->capacity() == this->SizeTypeMax()) |
286 | this->report_at_maximum_capacity(); |
287 | |
288 | // Always grow, even from zero. |
289 | size_t NewCapacity = size_t(NextPowerOf2(this->capacity() + 2)); |
290 | NewCapacity = std::min(std::max(NewCapacity, MinSize), this->SizeTypeMax()); |
291 | T *NewElts = static_cast<T*>(llvm::safe_malloc(NewCapacity*sizeof(T))); |
292 | |
293 | // Move the elements over. |
294 | this->uninitialized_move(this->begin(), this->end(), NewElts); |
295 | |
296 | // Destroy the original elements. |
297 | destroy_range(this->begin(), this->end()); |
298 | |
299 | // If this wasn't grown from the inline copy, deallocate the old space. |
300 | if (!this->isSmall()) |
301 | free(this->begin()); |
302 | |
303 | this->BeginX = NewElts; |
304 | this->Capacity = NewCapacity; |
305 | } |
306 | |
307 | /// SmallVectorTemplateBase<TriviallyCopyable = true> - This is where we put |
308 | /// method implementations that are designed to work with trivially copyable |
309 | /// T's. This allows using memcpy in place of copy/move construction and |
310 | /// skipping destruction. |
311 | template <typename T> |
312 | class SmallVectorTemplateBase<T, true> : public SmallVectorTemplateCommon<T> { |
313 | protected: |
314 | SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {} |
315 | |
316 | // No need to do a destroy loop for POD's. |
317 | static void destroy_range(T *, T *) {} |
318 | |
319 | /// Move the range [I, E) onto the uninitialized memory |
320 | /// starting with "Dest", constructing elements into it as needed. |
321 | template<typename It1, typename It2> |
322 | static void uninitialized_move(It1 I, It1 E, It2 Dest) { |
323 | // Just do a copy. |
324 | uninitialized_copy(I, E, Dest); |
325 | } |
326 | |
327 | /// Copy the range [I, E) onto the uninitialized memory |
328 | /// starting with "Dest", constructing elements into it as needed. |
329 | template<typename It1, typename It2> |
330 | static void uninitialized_copy(It1 I, It1 E, It2 Dest) { |
331 | // Arbitrary iterator types; just use the basic implementation. |
332 | std::uninitialized_copy(I, E, Dest); |
333 | } |
334 | |
335 | /// Copy the range [I, E) onto the uninitialized memory |
336 | /// starting with "Dest", constructing elements into it as needed. |
337 | template <typename T1, typename T2> |
338 | static void uninitialized_copy( |
339 | T1 *I, T1 *E, T2 *Dest, |
340 | std::enable_if_t<std::is_same<typename std::remove_const<T1>::type, |
341 | T2>::value> * = nullptr) { |
342 | // Use memcpy for PODs iterated by pointers (which includes SmallVector |
343 | // iterators): std::uninitialized_copy optimizes to memmove, but we can |
344 | // use memcpy here. Note that I and E are iterators and thus might be |
345 | // invalid for memcpy if they are equal. |
346 | if (I != E) |
347 | memcpy(reinterpret_cast<void *>(Dest), I, (E - I) * sizeof(T)); |
348 | } |
349 | |
350 | /// Double the size of the allocated memory, guaranteeing space for at |
351 | /// least one more element or MinSize if specified. |
352 | void grow(size_t MinSize = 0) { this->grow_pod(MinSize, sizeof(T)); } |
353 | |
354 | public: |
355 | void push_back(const T &Elt) { |
356 | if (LLVM_UNLIKELY(this->size() >= this->capacity())__builtin_expect((bool)(this->size() >= this->capacity ()), false)) |
357 | this->grow(); |
358 | memcpy(reinterpret_cast<void *>(this->end()), &Elt, sizeof(T)); |
359 | this->set_size(this->size() + 1); |
360 | } |
361 | |
362 | void pop_back() { this->set_size(this->size() - 1); } |
363 | }; |
364 | |
365 | /// This class consists of common code factored out of the SmallVector class to |
366 | /// reduce code duplication based on the SmallVector 'N' template parameter. |
367 | template <typename T> |
368 | class SmallVectorImpl : public SmallVectorTemplateBase<T> { |
369 | using SuperClass = SmallVectorTemplateBase<T>; |
370 | |
371 | public: |
372 | using iterator = typename SuperClass::iterator; |
373 | using const_iterator = typename SuperClass::const_iterator; |
374 | using reference = typename SuperClass::reference; |
375 | using size_type = typename SuperClass::size_type; |
376 | |
377 | protected: |
378 | // Default ctor - Initialize to empty. |
379 | explicit SmallVectorImpl(unsigned N) |
380 | : SmallVectorTemplateBase<T>(N) {} |
381 | |
382 | public: |
383 | SmallVectorImpl(const SmallVectorImpl &) = delete; |
384 | |
385 | ~SmallVectorImpl() { |
386 | // Subclass has already destructed this vector's elements. |
387 | // If this wasn't grown from the inline copy, deallocate the old space. |
388 | if (!this->isSmall()) |
389 | free(this->begin()); |
390 | } |
391 | |
392 | void clear() { |
393 | this->destroy_range(this->begin(), this->end()); |
394 | this->Size = 0; |
395 | } |
396 | |
397 | void resize(size_type N) { |
398 | if (N < this->size()) { |
399 | this->destroy_range(this->begin()+N, this->end()); |
400 | this->set_size(N); |
401 | } else if (N > this->size()) { |
402 | if (this->capacity() < N) |
403 | this->grow(N); |
404 | for (auto I = this->end(), E = this->begin() + N; I != E; ++I) |
405 | new (&*I) T(); |
406 | this->set_size(N); |
407 | } |
408 | } |
409 | |
410 | void resize(size_type N, const T &NV) { |
411 | if (N < this->size()) { |
412 | this->destroy_range(this->begin()+N, this->end()); |
413 | this->set_size(N); |
414 | } else if (N > this->size()) { |
415 | if (this->capacity() < N) |
416 | this->grow(N); |
417 | std::uninitialized_fill(this->end(), this->begin()+N, NV); |
418 | this->set_size(N); |
419 | } |
420 | } |
421 | |
422 | void reserve(size_type N) { |
423 | if (this->capacity() < N) |
424 | this->grow(N); |
425 | } |
426 | |
427 | LLVM_NODISCARD[[clang::warn_unused_result]] T pop_back_val() { |
428 | T Result = ::std::move(this->back()); |
429 | this->pop_back(); |
430 | return Result; |
431 | } |
432 | |
433 | void swap(SmallVectorImpl &RHS); |
434 | |
435 | /// Add the specified range to the end of the SmallVector. |
436 | template <typename in_iter, |
437 | typename = std::enable_if_t<std::is_convertible< |
438 | typename std::iterator_traits<in_iter>::iterator_category, |
439 | std::input_iterator_tag>::value>> |
440 | void append(in_iter in_start, in_iter in_end) { |
441 | size_type NumInputs = std::distance(in_start, in_end); |
442 | if (NumInputs > this->capacity() - this->size()) |
443 | this->grow(this->size()+NumInputs); |
444 | |
445 | this->uninitialized_copy(in_start, in_end, this->end()); |
446 | this->set_size(this->size() + NumInputs); |
447 | } |
448 | |
449 | /// Append \p NumInputs copies of \p Elt to the end. |
450 | void append(size_type NumInputs, const T &Elt) { |
451 | if (NumInputs > this->capacity() - this->size()) |
452 | this->grow(this->size()+NumInputs); |
453 | |
454 | std::uninitialized_fill_n(this->end(), NumInputs, Elt); |
455 | this->set_size(this->size() + NumInputs); |
456 | } |
457 | |
458 | void append(std::initializer_list<T> IL) { |
459 | append(IL.begin(), IL.end()); |
460 | } |
461 | |
462 | // FIXME: Consider assigning over existing elements, rather than clearing & |
463 | // re-initializing them - for all assign(...) variants. |
464 | |
465 | void assign(size_type NumElts, const T &Elt) { |
466 | clear(); |
467 | if (this->capacity() < NumElts) |
468 | this->grow(NumElts); |
469 | this->set_size(NumElts); |
470 | std::uninitialized_fill(this->begin(), this->end(), Elt); |
471 | } |
472 | |
473 | template <typename in_iter, |
474 | typename = std::enable_if_t<std::is_convertible< |
475 | typename std::iterator_traits<in_iter>::iterator_category, |
476 | std::input_iterator_tag>::value>> |
477 | void assign(in_iter in_start, in_iter in_end) { |
478 | clear(); |
479 | append(in_start, in_end); |
480 | } |
481 | |
482 | void assign(std::initializer_list<T> IL) { |
483 | clear(); |
484 | append(IL); |
485 | } |
486 | |
487 | iterator erase(const_iterator CI) { |
488 | // Just cast away constness because this is a non-const member function. |
489 | iterator I = const_cast<iterator>(CI); |
490 | |
491 | assert(I >= this->begin() && "Iterator to erase is out of bounds.")((I >= this->begin() && "Iterator to erase is out of bounds." ) ? static_cast<void> (0) : __assert_fail ("I >= this->begin() && \"Iterator to erase is out of bounds.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/llvm/include/llvm/ADT/SmallVector.h" , 491, __PRETTY_FUNCTION__)); |
492 | assert(I < this->end() && "Erasing at past-the-end iterator.")((I < this->end() && "Erasing at past-the-end iterator." ) ? static_cast<void> (0) : __assert_fail ("I < this->end() && \"Erasing at past-the-end iterator.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/llvm/include/llvm/ADT/SmallVector.h" , 492, __PRETTY_FUNCTION__)); |
493 | |
494 | iterator N = I; |
495 | // Shift all elts down one. |
496 | std::move(I+1, this->end(), I); |
497 | // Drop the last elt. |
498 | this->pop_back(); |
499 | return(N); |
500 | } |
501 | |
502 | iterator erase(const_iterator CS, const_iterator CE) { |
503 | // Just cast away constness because this is a non-const member function. |
504 | iterator S = const_cast<iterator>(CS); |
505 | iterator E = const_cast<iterator>(CE); |
506 | |
507 | assert(S >= this->begin() && "Range to erase is out of bounds.")((S >= this->begin() && "Range to erase is out of bounds." ) ? static_cast<void> (0) : __assert_fail ("S >= this->begin() && \"Range to erase is out of bounds.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/llvm/include/llvm/ADT/SmallVector.h" , 507, __PRETTY_FUNCTION__)); |
508 | assert(S <= E && "Trying to erase invalid range.")((S <= E && "Trying to erase invalid range.") ? static_cast <void> (0) : __assert_fail ("S <= E && \"Trying to erase invalid range.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/llvm/include/llvm/ADT/SmallVector.h" , 508, __PRETTY_FUNCTION__)); |
509 | assert(E <= this->end() && "Trying to erase past the end.")((E <= this->end() && "Trying to erase past the end." ) ? static_cast<void> (0) : __assert_fail ("E <= this->end() && \"Trying to erase past the end.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/llvm/include/llvm/ADT/SmallVector.h" , 509, __PRETTY_FUNCTION__)); |
510 | |
511 | iterator N = S; |
512 | // Shift all elts down. |
513 | iterator I = std::move(E, this->end(), S); |
514 | // Drop the last elts. |
515 | this->destroy_range(I, this->end()); |
516 | this->set_size(I - this->begin()); |
517 | return(N); |
518 | } |
519 | |
520 | iterator insert(iterator I, T &&Elt) { |
521 | if (I == this->end()) { // Important special case for empty vector. |
522 | this->push_back(::std::move(Elt)); |
523 | return this->end()-1; |
524 | } |
525 | |
526 | assert(I >= this->begin() && "Insertion iterator is out of bounds.")((I >= this->begin() && "Insertion iterator is out of bounds." ) ? static_cast<void> (0) : __assert_fail ("I >= this->begin() && \"Insertion iterator is out of bounds.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/llvm/include/llvm/ADT/SmallVector.h" , 526, __PRETTY_FUNCTION__)); |
527 | assert(I <= this->end() && "Inserting past the end of the vector.")((I <= this->end() && "Inserting past the end of the vector." ) ? static_cast<void> (0) : __assert_fail ("I <= this->end() && \"Inserting past the end of the vector.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/llvm/include/llvm/ADT/SmallVector.h" , 527, __PRETTY_FUNCTION__)); |
528 | |
529 | if (this->size() >= this->capacity()) { |
530 | size_t EltNo = I-this->begin(); |
531 | this->grow(); |
532 | I = this->begin()+EltNo; |
533 | } |
534 | |
535 | ::new ((void*) this->end()) T(::std::move(this->back())); |
536 | // Push everything else over. |
537 | std::move_backward(I, this->end()-1, this->end()); |
538 | this->set_size(this->size() + 1); |
539 | |
540 | // If we just moved the element we're inserting, be sure to update |
541 | // the reference. |
542 | T *EltPtr = &Elt; |
543 | if (I <= EltPtr && EltPtr < this->end()) |
544 | ++EltPtr; |
545 | |
546 | *I = ::std::move(*EltPtr); |
547 | return I; |
548 | } |
549 | |
550 | iterator insert(iterator I, const T &Elt) { |
551 | if (I == this->end()) { // Important special case for empty vector. |
552 | this->push_back(Elt); |
553 | return this->end()-1; |
554 | } |
555 | |
556 | assert(I >= this->begin() && "Insertion iterator is out of bounds.")((I >= this->begin() && "Insertion iterator is out of bounds." ) ? static_cast<void> (0) : __assert_fail ("I >= this->begin() && \"Insertion iterator is out of bounds.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/llvm/include/llvm/ADT/SmallVector.h" , 556, __PRETTY_FUNCTION__)); |
557 | assert(I <= this->end() && "Inserting past the end of the vector.")((I <= this->end() && "Inserting past the end of the vector." ) ? static_cast<void> (0) : __assert_fail ("I <= this->end() && \"Inserting past the end of the vector.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/llvm/include/llvm/ADT/SmallVector.h" , 557, __PRETTY_FUNCTION__)); |
558 | |
559 | if (this->size() >= this->capacity()) { |
560 | size_t EltNo = I-this->begin(); |
561 | this->grow(); |
562 | I = this->begin()+EltNo; |
563 | } |
564 | ::new ((void*) this->end()) T(std::move(this->back())); |
565 | // Push everything else over. |
566 | std::move_backward(I, this->end()-1, this->end()); |
567 | this->set_size(this->size() + 1); |
568 | |
569 | // If we just moved the element we're inserting, be sure to update |
570 | // the reference. |
571 | const T *EltPtr = &Elt; |
572 | if (I <= EltPtr && EltPtr < this->end()) |
573 | ++EltPtr; |
574 | |
575 | *I = *EltPtr; |
576 | return I; |
577 | } |
578 | |
579 | iterator insert(iterator I, size_type NumToInsert, const T &Elt) { |
580 | // Convert iterator to elt# to avoid invalidating iterator when we reserve() |
581 | size_t InsertElt = I - this->begin(); |
582 | |
583 | if (I == this->end()) { // Important special case for empty vector. |
584 | append(NumToInsert, Elt); |
585 | return this->begin()+InsertElt; |
586 | } |
587 | |
588 | assert(I >= this->begin() && "Insertion iterator is out of bounds.")((I >= this->begin() && "Insertion iterator is out of bounds." ) ? static_cast<void> (0) : __assert_fail ("I >= this->begin() && \"Insertion iterator is out of bounds.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/llvm/include/llvm/ADT/SmallVector.h" , 588, __PRETTY_FUNCTION__)); |
589 | assert(I <= this->end() && "Inserting past the end of the vector.")((I <= this->end() && "Inserting past the end of the vector." ) ? static_cast<void> (0) : __assert_fail ("I <= this->end() && \"Inserting past the end of the vector.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/llvm/include/llvm/ADT/SmallVector.h" , 589, __PRETTY_FUNCTION__)); |
590 | |
591 | // Ensure there is enough space. |
592 | reserve(this->size() + NumToInsert); |
593 | |
594 | // Uninvalidate the iterator. |
595 | I = this->begin()+InsertElt; |
596 | |
597 | // If there are more elements between the insertion point and the end of the |
598 | // range than there are being inserted, we can use a simple approach to |
599 | // insertion. Since we already reserved space, we know that this won't |
600 | // reallocate the vector. |
601 | if (size_t(this->end()-I) >= NumToInsert) { |
602 | T *OldEnd = this->end(); |
603 | append(std::move_iterator<iterator>(this->end() - NumToInsert), |
604 | std::move_iterator<iterator>(this->end())); |
605 | |
606 | // Copy the existing elements that get replaced. |
607 | std::move_backward(I, OldEnd-NumToInsert, OldEnd); |
608 | |
609 | std::fill_n(I, NumToInsert, Elt); |
610 | return I; |
611 | } |
612 | |
613 | // Otherwise, we're inserting more elements than exist already, and we're |
614 | // not inserting at the end. |
615 | |
616 | // Move over the elements that we're about to overwrite. |
617 | T *OldEnd = this->end(); |
618 | this->set_size(this->size() + NumToInsert); |
619 | size_t NumOverwritten = OldEnd-I; |
620 | this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten); |
621 | |
622 | // Replace the overwritten part. |
623 | std::fill_n(I, NumOverwritten, Elt); |
624 | |
625 | // Insert the non-overwritten middle part. |
626 | std::uninitialized_fill_n(OldEnd, NumToInsert-NumOverwritten, Elt); |
627 | return I; |
628 | } |
629 | |
630 | template <typename ItTy, |
631 | typename = std::enable_if_t<std::is_convertible< |
632 | typename std::iterator_traits<ItTy>::iterator_category, |
633 | std::input_iterator_tag>::value>> |
634 | iterator insert(iterator I, ItTy From, ItTy To) { |
635 | // Convert iterator to elt# to avoid invalidating iterator when we reserve() |
636 | size_t InsertElt = I - this->begin(); |
637 | |
638 | if (I == this->end()) { // Important special case for empty vector. |
639 | append(From, To); |
640 | return this->begin()+InsertElt; |
641 | } |
642 | |
643 | assert(I >= this->begin() && "Insertion iterator is out of bounds.")((I >= this->begin() && "Insertion iterator is out of bounds." ) ? static_cast<void> (0) : __assert_fail ("I >= this->begin() && \"Insertion iterator is out of bounds.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/llvm/include/llvm/ADT/SmallVector.h" , 643, __PRETTY_FUNCTION__)); |
644 | assert(I <= this->end() && "Inserting past the end of the vector.")((I <= this->end() && "Inserting past the end of the vector." ) ? static_cast<void> (0) : __assert_fail ("I <= this->end() && \"Inserting past the end of the vector.\"" , "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/llvm/include/llvm/ADT/SmallVector.h" , 644, __PRETTY_FUNCTION__)); |
645 | |
646 | size_t NumToInsert = std::distance(From, To); |
647 | |
648 | // Ensure there is enough space. |
649 | reserve(this->size() + NumToInsert); |
650 | |
651 | // Uninvalidate the iterator. |
652 | I = this->begin()+InsertElt; |
653 | |
654 | // If there are more elements between the insertion point and the end of the |
655 | // range than there are being inserted, we can use a simple approach to |
656 | // insertion. Since we already reserved space, we know that this won't |
657 | // reallocate the vector. |
658 | if (size_t(this->end()-I) >= NumToInsert) { |
659 | T *OldEnd = this->end(); |
660 | append(std::move_iterator<iterator>(this->end() - NumToInsert), |
661 | std::move_iterator<iterator>(this->end())); |
662 | |
663 | // Copy the existing elements that get replaced. |
664 | std::move_backward(I, OldEnd-NumToInsert, OldEnd); |
665 | |
666 | std::copy(From, To, I); |
667 | return I; |
668 | } |
669 | |
670 | // Otherwise, we're inserting more elements than exist already, and we're |
671 | // not inserting at the end. |
672 | |
673 | // Move over the elements that we're about to overwrite. |
674 | T *OldEnd = this->end(); |
675 | this->set_size(this->size() + NumToInsert); |
676 | size_t NumOverwritten = OldEnd-I; |
677 | this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten); |
678 | |
679 | // Replace the overwritten part. |
680 | for (T *J = I; NumOverwritten > 0; --NumOverwritten) { |
681 | *J = *From; |
682 | ++J; ++From; |
683 | } |
684 | |
685 | // Insert the non-overwritten middle part. |
686 | this->uninitialized_copy(From, To, OldEnd); |
687 | return I; |
688 | } |
689 | |
690 | void insert(iterator I, std::initializer_list<T> IL) { |
691 | insert(I, IL.begin(), IL.end()); |
692 | } |
693 | |
694 | template <typename... ArgTypes> reference emplace_back(ArgTypes &&... Args) { |
695 | if (LLVM_UNLIKELY(this->size() >= this->capacity())__builtin_expect((bool)(this->size() >= this->capacity ()), false)) |
696 | this->grow(); |
697 | ::new ((void *)this->end()) T(std::forward<ArgTypes>(Args)...); |
698 | this->set_size(this->size() + 1); |
699 | return this->back(); |
700 | } |
701 | |
702 | SmallVectorImpl &operator=(const SmallVectorImpl &RHS); |
703 | |
704 | SmallVectorImpl &operator=(SmallVectorImpl &&RHS); |
705 | |
706 | bool operator==(const SmallVectorImpl &RHS) const { |
707 | if (this->size() != RHS.size()) return false; |
708 | return std::equal(this->begin(), this->end(), RHS.begin()); |
709 | } |
710 | bool operator!=(const SmallVectorImpl &RHS) const { |
711 | return !(*this == RHS); |
712 | } |
713 | |
714 | bool operator<(const SmallVectorImpl &RHS) const { |
715 | return std::lexicographical_compare(this->begin(), this->end(), |
716 | RHS.begin(), RHS.end()); |
717 | } |
718 | }; |
719 | |
720 | template <typename T> |
721 | void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) { |
722 | if (this == &RHS) return; |
723 | |
724 | // We can only avoid copying elements if neither vector is small. |
725 | if (!this->isSmall() && !RHS.isSmall()) { |
726 | std::swap(this->BeginX, RHS.BeginX); |
727 | std::swap(this->Size, RHS.Size); |
728 | std::swap(this->Capacity, RHS.Capacity); |
729 | return; |
730 | } |
731 | if (RHS.size() > this->capacity()) |
732 | this->grow(RHS.size()); |
733 | if (this->size() > RHS.capacity()) |
734 | RHS.grow(this->size()); |
735 | |
736 | // Swap the shared elements. |
737 | size_t NumShared = this->size(); |
738 | if (NumShared > RHS.size()) NumShared = RHS.size(); |
739 | for (size_type i = 0; i != NumShared; ++i) |
740 | std::swap((*this)[i], RHS[i]); |
741 | |
742 | // Copy over the extra elts. |
743 | if (this->size() > RHS.size()) { |
744 | size_t EltDiff = this->size() - RHS.size(); |
745 | this->uninitialized_copy(this->begin()+NumShared, this->end(), RHS.end()); |
746 | RHS.set_size(RHS.size() + EltDiff); |
747 | this->destroy_range(this->begin()+NumShared, this->end()); |
748 | this->set_size(NumShared); |
749 | } else if (RHS.size() > this->size()) { |
750 | size_t EltDiff = RHS.size() - this->size(); |
751 | this->uninitialized_copy(RHS.begin()+NumShared, RHS.end(), this->end()); |
752 | this->set_size(this->size() + EltDiff); |
753 | this->destroy_range(RHS.begin()+NumShared, RHS.end()); |
754 | RHS.set_size(NumShared); |
755 | } |
756 | } |
757 | |
758 | template <typename T> |
759 | SmallVectorImpl<T> &SmallVectorImpl<T>:: |
760 | operator=(const SmallVectorImpl<T> &RHS) { |
761 | // Avoid self-assignment. |
762 | if (this == &RHS) return *this; |
763 | |
764 | // If we already have sufficient space, assign the common elements, then |
765 | // destroy any excess. |
766 | size_t RHSSize = RHS.size(); |
767 | size_t CurSize = this->size(); |
768 | if (CurSize >= RHSSize) { |
769 | // Assign common elements. |
770 | iterator NewEnd; |
771 | if (RHSSize) |
772 | NewEnd = std::copy(RHS.begin(), RHS.begin()+RHSSize, this->begin()); |
773 | else |
774 | NewEnd = this->begin(); |
775 | |
776 | // Destroy excess elements. |
777 | this->destroy_range(NewEnd, this->end()); |
778 | |
779 | // Trim. |
780 | this->set_size(RHSSize); |
781 | return *this; |
782 | } |
783 | |
784 | // If we have to grow to have enough elements, destroy the current elements. |
785 | // This allows us to avoid copying them during the grow. |
786 | // FIXME: don't do this if they're efficiently moveable. |
787 | if (this->capacity() < RHSSize) { |
788 | // Destroy current elements. |
789 | this->destroy_range(this->begin(), this->end()); |
790 | this->set_size(0); |
791 | CurSize = 0; |
792 | this->grow(RHSSize); |
793 | } else if (CurSize) { |
794 | // Otherwise, use assignment for the already-constructed elements. |
795 | std::copy(RHS.begin(), RHS.begin()+CurSize, this->begin()); |
796 | } |
797 | |
798 | // Copy construct the new elements in place. |
799 | this->uninitialized_copy(RHS.begin()+CurSize, RHS.end(), |
800 | this->begin()+CurSize); |
801 | |
802 | // Set end. |
803 | this->set_size(RHSSize); |
804 | return *this; |
805 | } |
806 | |
807 | template <typename T> |
808 | SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) { |
809 | // Avoid self-assignment. |
810 | if (this == &RHS) return *this; |
811 | |
812 | // If the RHS isn't small, clear this vector and then steal its buffer. |
813 | if (!RHS.isSmall()) { |
814 | this->destroy_range(this->begin(), this->end()); |
815 | if (!this->isSmall()) free(this->begin()); |
816 | this->BeginX = RHS.BeginX; |
817 | this->Size = RHS.Size; |
818 | this->Capacity = RHS.Capacity; |
819 | RHS.resetToSmall(); |
820 | return *this; |
821 | } |
822 | |
823 | // If we already have sufficient space, assign the common elements, then |
824 | // destroy any excess. |
825 | size_t RHSSize = RHS.size(); |
826 | size_t CurSize = this->size(); |
827 | if (CurSize >= RHSSize) { |
828 | // Assign common elements. |
829 | iterator NewEnd = this->begin(); |
830 | if (RHSSize) |
831 | NewEnd = std::move(RHS.begin(), RHS.end(), NewEnd); |
832 | |
833 | // Destroy excess elements and trim the bounds. |
834 | this->destroy_range(NewEnd, this->end()); |
835 | this->set_size(RHSSize); |
836 | |
837 | // Clear the RHS. |
838 | RHS.clear(); |
839 | |
840 | return *this; |
841 | } |
842 | |
843 | // If we have to grow to have enough elements, destroy the current elements. |
844 | // This allows us to avoid copying them during the grow. |
845 | // FIXME: this may not actually make any sense if we can efficiently move |
846 | // elements. |
847 | if (this->capacity() < RHSSize) { |
848 | // Destroy current elements. |
849 | this->destroy_range(this->begin(), this->end()); |
850 | this->set_size(0); |
851 | CurSize = 0; |
852 | this->grow(RHSSize); |
853 | } else if (CurSize) { |
854 | // Otherwise, use assignment for the already-constructed elements. |
855 | std::move(RHS.begin(), RHS.begin()+CurSize, this->begin()); |
856 | } |
857 | |
858 | // Move-construct the new elements in place. |
859 | this->uninitialized_move(RHS.begin()+CurSize, RHS.end(), |
860 | this->begin()+CurSize); |
861 | |
862 | // Set end. |
863 | this->set_size(RHSSize); |
864 | |
865 | RHS.clear(); |
866 | return *this; |
867 | } |
868 | |
869 | /// Storage for the SmallVector elements. This is specialized for the N=0 case |
870 | /// to avoid allocating unnecessary storage. |
871 | template <typename T, unsigned N> |
872 | struct SmallVectorStorage { |
873 | AlignedCharArrayUnion<T> InlineElts[N]; |
874 | }; |
875 | |
876 | /// We need the storage to be properly aligned even for small-size of 0 so that |
877 | /// the pointer math in \a SmallVectorTemplateCommon::getFirstEl() is |
878 | /// well-defined. |
879 | template <typename T> struct alignas(alignof(T)) SmallVectorStorage<T, 0> {}; |
880 | |
881 | /// This is a 'vector' (really, a variable-sized array), optimized |
882 | /// for the case when the array is small. It contains some number of elements |
883 | /// in-place, which allows it to avoid heap allocation when the actual number of |
884 | /// elements is below that threshold. This allows normal "small" cases to be |
885 | /// fast without losing generality for large inputs. |
886 | /// |
887 | /// Note that this does not attempt to be exception safe. |
888 | /// |
889 | template <typename T, unsigned N> |
890 | class LLVM_GSL_OWNER[[gsl::Owner]] SmallVector : public SmallVectorImpl<T>, |
891 | SmallVectorStorage<T, N> { |
892 | public: |
893 | SmallVector() : SmallVectorImpl<T>(N) {} |
894 | |
895 | ~SmallVector() { |
896 | // Destroy the constructed elements in the vector. |
897 | this->destroy_range(this->begin(), this->end()); |
898 | } |
899 | |
900 | explicit SmallVector(size_t Size, const T &Value = T()) |
901 | : SmallVectorImpl<T>(N) { |
902 | this->assign(Size, Value); |
903 | } |
904 | |
905 | template <typename ItTy, |
906 | typename = std::enable_if_t<std::is_convertible< |
907 | typename std::iterator_traits<ItTy>::iterator_category, |
908 | std::input_iterator_tag>::value>> |
909 | SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(N) { |
910 | this->append(S, E); |
911 | } |
912 | |
913 | template <typename RangeTy> |
914 | explicit SmallVector(const iterator_range<RangeTy> &R) |
915 | : SmallVectorImpl<T>(N) { |
916 | this->append(R.begin(), R.end()); |
917 | } |
918 | |
919 | SmallVector(std::initializer_list<T> IL) : SmallVectorImpl<T>(N) { |
920 | this->assign(IL); |
921 | } |
922 | |
923 | SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(N) { |
924 | if (!RHS.empty()) |
925 | SmallVectorImpl<T>::operator=(RHS); |
926 | } |
927 | |
928 | const SmallVector &operator=(const SmallVector &RHS) { |
929 | SmallVectorImpl<T>::operator=(RHS); |
930 | return *this; |
931 | } |
932 | |
933 | SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(N) { |
934 | if (!RHS.empty()) |
935 | SmallVectorImpl<T>::operator=(::std::move(RHS)); |
936 | } |
937 | |
938 | SmallVector(SmallVectorImpl<T> &&RHS) : SmallVectorImpl<T>(N) { |
939 | if (!RHS.empty()) |
940 | SmallVectorImpl<T>::operator=(::std::move(RHS)); |
941 | } |
942 | |
943 | const SmallVector &operator=(SmallVector &&RHS) { |
944 | SmallVectorImpl<T>::operator=(::std::move(RHS)); |
945 | return *this; |
946 | } |
947 | |
948 | const SmallVector &operator=(SmallVectorImpl<T> &&RHS) { |
949 | SmallVectorImpl<T>::operator=(::std::move(RHS)); |
950 | return *this; |
951 | } |
952 | |
953 | const SmallVector &operator=(std::initializer_list<T> IL) { |
954 | this->assign(IL); |
955 | return *this; |
956 | } |
957 | }; |
958 | |
959 | template <typename T, unsigned N> |
960 | inline size_t capacity_in_bytes(const SmallVector<T, N> &X) { |
961 | return X.capacity_in_bytes(); |
962 | } |
963 | |
964 | /// Given a range of type R, iterate the entire range and return a |
965 | /// SmallVector with elements of the vector. This is useful, for example, |
966 | /// when you want to iterate a range and then sort the results. |
967 | template <unsigned Size, typename R> |
968 | SmallVector<typename std::remove_const<typename std::remove_reference< |
969 | decltype(*std::begin(std::declval<R &>()))>::type>::type, |
970 | Size> |
971 | to_vector(R &&Range) { |
972 | return {std::begin(Range), std::end(Range)}; |
973 | } |
974 | |
975 | } // end namespace llvm |
976 | |
977 | namespace std { |
978 | |
979 | /// Implement std::swap in terms of SmallVector swap. |
980 | template<typename T> |
981 | inline void |
982 | swap(llvm::SmallVectorImpl<T> &LHS, llvm::SmallVectorImpl<T> &RHS) { |
983 | LHS.swap(RHS); |
984 | } |
985 | |
986 | /// Implement std::swap in terms of SmallVector swap. |
987 | template<typename T, unsigned N> |
988 | inline void |
989 | swap(llvm::SmallVector<T, N> &LHS, llvm::SmallVector<T, N> &RHS) { |
990 | LHS.swap(RHS); |
991 | } |
992 | |
993 | } // end namespace std |
994 | |
995 | #endif // LLVM_ADT_SMALLVECTOR_H |