File: | clang/lib/Sema/SemaOpenMP.cpp |
Warning: | line 2164, 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 | DSAVarData() = default; | ||||||
74 | DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, | ||||||
75 | const Expr *RefExpr, DeclRefExpr *PrivateCopy, | ||||||
76 | SourceLocation ImplicitDSALoc, unsigned Modifier) | ||||||
77 | : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr), | ||||||
78 | PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} | ||||||
79 | }; | ||||||
80 | using OperatorOffsetTy = | ||||||
81 | llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; | ||||||
82 | using DoacrossDependMapTy = | ||||||
83 | llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; | ||||||
84 | /// Kind of the declaration used in the uses_allocators clauses. | ||||||
85 | enum class UsesAllocatorsDeclKind { | ||||||
86 | /// Predefined allocator | ||||||
87 | PredefinedAllocator, | ||||||
88 | /// User-defined allocator | ||||||
89 | UserDefinedAllocator, | ||||||
90 | /// The declaration that represent allocator trait | ||||||
91 | AllocatorTrait, | ||||||
92 | }; | ||||||
93 | |||||||
94 | private: | ||||||
95 | struct DSAInfo { | ||||||
96 | OpenMPClauseKind Attributes = OMPC_unknown; | ||||||
97 | unsigned Modifier = 0; | ||||||
98 | /// Pointer to a reference expression and a flag which shows that the | ||||||
99 | /// variable is marked as lastprivate(true) or not (false). | ||||||
100 | llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; | ||||||
101 | DeclRefExpr *PrivateCopy = nullptr; | ||||||
102 | }; | ||||||
103 | using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; | ||||||
104 | using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; | ||||||
105 | using LCDeclInfo = std::pair<unsigned, VarDecl *>; | ||||||
106 | using LoopControlVariablesMapTy = | ||||||
107 | llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; | ||||||
108 | /// Struct that associates a component with the clause kind where they are | ||||||
109 | /// found. | ||||||
110 | struct MappedExprComponentTy { | ||||||
111 | OMPClauseMappableExprCommon::MappableExprComponentLists Components; | ||||||
112 | OpenMPClauseKind Kind = OMPC_unknown; | ||||||
113 | }; | ||||||
114 | using MappedExprComponentsTy = | ||||||
115 | llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; | ||||||
116 | using CriticalsWithHintsTy = | ||||||
117 | llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; | ||||||
118 | struct ReductionData { | ||||||
119 | using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; | ||||||
120 | SourceRange ReductionRange; | ||||||
121 | llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; | ||||||
122 | ReductionData() = default; | ||||||
123 | void set(BinaryOperatorKind BO, SourceRange RR) { | ||||||
124 | ReductionRange = RR; | ||||||
125 | ReductionOp = BO; | ||||||
126 | } | ||||||
127 | void set(const Expr *RefExpr, SourceRange RR) { | ||||||
128 | ReductionRange = RR; | ||||||
129 | ReductionOp = RefExpr; | ||||||
130 | } | ||||||
131 | }; | ||||||
132 | using DeclReductionMapTy = | ||||||
133 | llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; | ||||||
134 | struct DefaultmapInfo { | ||||||
135 | OpenMPDefaultmapClauseModifier ImplicitBehavior = | ||||||
136 | OMPC_DEFAULTMAP_MODIFIER_unknown; | ||||||
137 | SourceLocation SLoc; | ||||||
138 | DefaultmapInfo() = default; | ||||||
139 | DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc) | ||||||
140 | : ImplicitBehavior(M), SLoc(Loc) {} | ||||||
141 | }; | ||||||
142 | |||||||
143 | struct SharingMapTy { | ||||||
144 | DeclSAMapTy SharingMap; | ||||||
145 | DeclReductionMapTy ReductionMap; | ||||||
146 | UsedRefMapTy AlignedMap; | ||||||
147 | UsedRefMapTy NontemporalMap; | ||||||
148 | MappedExprComponentsTy MappedExprComponents; | ||||||
149 | LoopControlVariablesMapTy LCVMap; | ||||||
150 | DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; | ||||||
151 | SourceLocation DefaultAttrLoc; | ||||||
152 | DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown]; | ||||||
153 | OpenMPDirectiveKind Directive = OMPD_unknown; | ||||||
154 | DeclarationNameInfo DirectiveName; | ||||||
155 | Scope *CurScope = nullptr; | ||||||
156 | SourceLocation ConstructLoc; | ||||||
157 | /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to | ||||||
158 | /// get the data (loop counters etc.) about enclosing loop-based construct. | ||||||
159 | /// This data is required during codegen. | ||||||
160 | DoacrossDependMapTy DoacrossDepends; | ||||||
161 | /// First argument (Expr *) contains optional argument of the | ||||||
162 | /// 'ordered' clause, the second one is true if the regions has 'ordered' | ||||||
163 | /// clause, false otherwise. | ||||||
164 | llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; | ||||||
165 | unsigned AssociatedLoops = 1; | ||||||
166 | bool HasMutipleLoops = false; | ||||||
167 | const Decl *PossiblyLoopCounter = nullptr; | ||||||
168 | bool NowaitRegion = false; | ||||||
169 | bool CancelRegion = false; | ||||||
170 | bool LoopStart = false; | ||||||
171 | bool BodyComplete = false; | ||||||
172 | SourceLocation PrevScanLocation; | ||||||
173 | SourceLocation PrevOrderedLocation; | ||||||
174 | SourceLocation InnerTeamsRegionLoc; | ||||||
175 | /// Reference to the taskgroup task_reduction reference expression. | ||||||
176 | Expr *TaskgroupReductionRef = nullptr; | ||||||
177 | llvm::DenseSet<QualType> MappedClassesQualTypes; | ||||||
178 | SmallVector<Expr *, 4> InnerUsedAllocators; | ||||||
179 | llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates; | ||||||
180 | /// List of globals marked as declare target link in this target region | ||||||
181 | /// (isOpenMPTargetExecutionDirective(Directive) == true). | ||||||
182 | llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; | ||||||
183 | /// List of decls used in inclusive/exclusive clauses of the scan directive. | ||||||
184 | llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective; | ||||||
185 | llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind> | ||||||
186 | UsesAllocatorsDecls; | ||||||
187 | SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, | ||||||
188 | Scope *CurScope, SourceLocation Loc) | ||||||
189 | : Directive(DKind), DirectiveName(Name), CurScope(CurScope), | ||||||
190 | ConstructLoc(Loc) {} | ||||||
191 | SharingMapTy() = default; | ||||||
192 | }; | ||||||
193 | |||||||
194 | using StackTy = SmallVector<SharingMapTy, 4>; | ||||||
195 | |||||||
196 | /// Stack of used declaration and their data-sharing attributes. | ||||||
197 | DeclSAMapTy Threadprivates; | ||||||
198 | const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; | ||||||
199 | SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; | ||||||
200 | /// true, if check for DSA must be from parent directive, false, if | ||||||
201 | /// from current directive. | ||||||
202 | OpenMPClauseKind ClauseKindMode = OMPC_unknown; | ||||||
203 | Sema &SemaRef; | ||||||
204 | bool ForceCapturing = false; | ||||||
205 | /// true if all the variables in the target executable directives must be | ||||||
206 | /// captured by reference. | ||||||
207 | bool ForceCaptureByReferenceInTargetExecutable = false; | ||||||
208 | CriticalsWithHintsTy Criticals; | ||||||
209 | unsigned IgnoredStackElements = 0; | ||||||
210 | |||||||
211 | /// Iterators over the stack iterate in order from innermost to outermost | ||||||
212 | /// directive. | ||||||
213 | using const_iterator = StackTy::const_reverse_iterator; | ||||||
214 | const_iterator begin() const { | ||||||
215 | return Stack.empty() ? const_iterator() | ||||||
216 | : Stack.back().first.rbegin() + IgnoredStackElements; | ||||||
217 | } | ||||||
218 | const_iterator end() const { | ||||||
219 | return Stack.empty() ? const_iterator() : Stack.back().first.rend(); | ||||||
220 | } | ||||||
221 | using iterator = StackTy::reverse_iterator; | ||||||
222 | iterator begin() { | ||||||
223 | return Stack.empty() ? iterator() | ||||||
224 | : Stack.back().first.rbegin() + IgnoredStackElements; | ||||||
225 | } | ||||||
226 | iterator end() { | ||||||
227 | return Stack.empty() ? iterator() : Stack.back().first.rend(); | ||||||
228 | } | ||||||
229 | |||||||
230 | // Convenience operations to get at the elements of the stack. | ||||||
231 | |||||||
232 | bool isStackEmpty() const { | ||||||
233 | return Stack.empty() || | ||||||
234 | Stack.back().second != CurrentNonCapturingFunctionScope || | ||||||
235 | Stack.back().first.size() <= IgnoredStackElements; | ||||||
236 | } | ||||||
237 | size_t getStackSize() const { | ||||||
238 | return isStackEmpty() ? 0 | ||||||
239 | : Stack.back().first.size() - IgnoredStackElements; | ||||||
240 | } | ||||||
241 | |||||||
242 | SharingMapTy *getTopOfStackOrNull() { | ||||||
243 | size_t Size = getStackSize(); | ||||||
244 | if (Size == 0) | ||||||
245 | return nullptr; | ||||||
246 | return &Stack.back().first[Size - 1]; | ||||||
247 | } | ||||||
248 | const SharingMapTy *getTopOfStackOrNull() const { | ||||||
249 | return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); | ||||||
250 | } | ||||||
251 | SharingMapTy &getTopOfStack() { | ||||||
252 | assert(!isStackEmpty() && "no current directive")((!isStackEmpty() && "no current directive") ? static_cast <void> (0) : __assert_fail ("!isStackEmpty() && \"no current directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 252, __PRETTY_FUNCTION__)); | ||||||
253 | return *getTopOfStackOrNull(); | ||||||
254 | } | ||||||
255 | const SharingMapTy &getTopOfStack() const { | ||||||
256 | return const_cast<DSAStackTy&>(*this).getTopOfStack(); | ||||||
257 | } | ||||||
258 | |||||||
259 | SharingMapTy *getSecondOnStackOrNull() { | ||||||
260 | size_t Size = getStackSize(); | ||||||
261 | if (Size <= 1) | ||||||
262 | return nullptr; | ||||||
263 | return &Stack.back().first[Size - 2]; | ||||||
264 | } | ||||||
265 | const SharingMapTy *getSecondOnStackOrNull() const { | ||||||
266 | return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); | ||||||
267 | } | ||||||
268 | |||||||
269 | /// Get the stack element at a certain level (previously returned by | ||||||
270 | /// \c getNestingLevel). | ||||||
271 | /// | ||||||
272 | /// Note that nesting levels count from outermost to innermost, and this is | ||||||
273 | /// the reverse of our iteration order where new inner levels are pushed at | ||||||
274 | /// the front of the stack. | ||||||
275 | SharingMapTy &getStackElemAtLevel(unsigned Level) { | ||||||
276 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 276, __PRETTY_FUNCTION__)); | ||||||
277 | return Stack.back().first[Level]; | ||||||
278 | } | ||||||
279 | const SharingMapTy &getStackElemAtLevel(unsigned Level) const { | ||||||
280 | return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); | ||||||
281 | } | ||||||
282 | |||||||
283 | DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; | ||||||
284 | |||||||
285 | /// Checks if the variable is a local for OpenMP region. | ||||||
286 | bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; | ||||||
287 | |||||||
288 | /// Vector of previously declared requires directives | ||||||
289 | SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; | ||||||
290 | /// omp_allocator_handle_t type. | ||||||
291 | QualType OMPAllocatorHandleT; | ||||||
292 | /// omp_depend_t type. | ||||||
293 | QualType OMPDependT; | ||||||
294 | /// omp_event_handle_t type. | ||||||
295 | QualType OMPEventHandleT; | ||||||
296 | /// omp_alloctrait_t type. | ||||||
297 | QualType OMPAlloctraitT; | ||||||
298 | /// Expression for the predefined allocators. | ||||||
299 | Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { | ||||||
300 | nullptr}; | ||||||
301 | /// Vector of previously encountered target directives | ||||||
302 | SmallVector<SourceLocation, 2> TargetLocations; | ||||||
303 | SourceLocation AtomicLocation; | ||||||
304 | |||||||
305 | public: | ||||||
306 | explicit DSAStackTy(Sema &S) : SemaRef(S) {} | ||||||
307 | |||||||
308 | /// Sets omp_allocator_handle_t type. | ||||||
309 | void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } | ||||||
310 | /// Gets omp_allocator_handle_t type. | ||||||
311 | QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } | ||||||
312 | /// Sets omp_alloctrait_t type. | ||||||
313 | void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; } | ||||||
314 | /// Gets omp_alloctrait_t type. | ||||||
315 | QualType getOMPAlloctraitT() const { return OMPAlloctraitT; } | ||||||
316 | /// Sets the given default allocator. | ||||||
317 | void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, | ||||||
318 | Expr *Allocator) { | ||||||
319 | OMPPredefinedAllocators[AllocatorKind] = Allocator; | ||||||
320 | } | ||||||
321 | /// Returns the specified default allocator. | ||||||
322 | Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { | ||||||
323 | return OMPPredefinedAllocators[AllocatorKind]; | ||||||
324 | } | ||||||
325 | /// Sets omp_depend_t type. | ||||||
326 | void setOMPDependT(QualType Ty) { OMPDependT = Ty; } | ||||||
327 | /// Gets omp_depend_t type. | ||||||
328 | QualType getOMPDependT() const { return OMPDependT; } | ||||||
329 | |||||||
330 | /// Sets omp_event_handle_t type. | ||||||
331 | void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; } | ||||||
332 | /// Gets omp_event_handle_t type. | ||||||
333 | QualType getOMPEventHandleT() const { return OMPEventHandleT; } | ||||||
334 | |||||||
335 | bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } | ||||||
336 | OpenMPClauseKind getClauseParsingMode() const { | ||||||
337 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 337, __PRETTY_FUNCTION__)); | ||||||
338 | return ClauseKindMode; | ||||||
339 | } | ||||||
340 | void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } | ||||||
341 | |||||||
342 | bool isBodyComplete() const { | ||||||
343 | const SharingMapTy *Top = getTopOfStackOrNull(); | ||||||
344 | return Top && Top->BodyComplete; | ||||||
345 | } | ||||||
346 | void setBodyComplete() { | ||||||
347 | getTopOfStack().BodyComplete = true; | ||||||
348 | } | ||||||
349 | |||||||
350 | bool isForceVarCapturing() const { return ForceCapturing; } | ||||||
351 | void setForceVarCapturing(bool V) { ForceCapturing = V; } | ||||||
352 | |||||||
353 | void setForceCaptureByReferenceInTargetExecutable(bool V) { | ||||||
354 | ForceCaptureByReferenceInTargetExecutable = V; | ||||||
355 | } | ||||||
356 | bool isForceCaptureByReferenceInTargetExecutable() const { | ||||||
357 | return ForceCaptureByReferenceInTargetExecutable; | ||||||
358 | } | ||||||
359 | |||||||
360 | void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, | ||||||
361 | Scope *CurScope, SourceLocation Loc) { | ||||||
362 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 363, __PRETTY_FUNCTION__)) | ||||||
363 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 363, __PRETTY_FUNCTION__)); | ||||||
364 | if (Stack.empty() || | ||||||
365 | Stack.back().second != CurrentNonCapturingFunctionScope) | ||||||
366 | Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); | ||||||
367 | Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); | ||||||
368 | Stack.back().first.back().DefaultAttrLoc = Loc; | ||||||
369 | } | ||||||
370 | |||||||
371 | void pop() { | ||||||
372 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 373, __PRETTY_FUNCTION__)) | ||||||
373 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 373, __PRETTY_FUNCTION__)); | ||||||
374 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 375, __PRETTY_FUNCTION__)) | ||||||
375 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 375, __PRETTY_FUNCTION__)); | ||||||
376 | Stack.back().first.pop_back(); | ||||||
377 | } | ||||||
378 | |||||||
379 | /// RAII object to temporarily leave the scope of a directive when we want to | ||||||
380 | /// logically operate in its parent. | ||||||
381 | class ParentDirectiveScope { | ||||||
382 | DSAStackTy &Self; | ||||||
383 | bool Active; | ||||||
384 | public: | ||||||
385 | ParentDirectiveScope(DSAStackTy &Self, bool Activate) | ||||||
386 | : Self(Self), Active(false) { | ||||||
387 | if (Activate) | ||||||
388 | enable(); | ||||||
389 | } | ||||||
390 | ~ParentDirectiveScope() { disable(); } | ||||||
391 | void disable() { | ||||||
392 | if (Active) { | ||||||
393 | --Self.IgnoredStackElements; | ||||||
394 | Active = false; | ||||||
395 | } | ||||||
396 | } | ||||||
397 | void enable() { | ||||||
398 | if (!Active) { | ||||||
399 | ++Self.IgnoredStackElements; | ||||||
400 | Active = true; | ||||||
401 | } | ||||||
402 | } | ||||||
403 | }; | ||||||
404 | |||||||
405 | /// Marks that we're started loop parsing. | ||||||
406 | void loopInit() { | ||||||
407 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 408, __PRETTY_FUNCTION__)) | ||||||
408 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 408, __PRETTY_FUNCTION__)); | ||||||
409 | getTopOfStack().LoopStart = true; | ||||||
410 | } | ||||||
411 | /// Start capturing of the variables in the loop context. | ||||||
412 | void loopStart() { | ||||||
413 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 414, __PRETTY_FUNCTION__)) | ||||||
414 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 414, __PRETTY_FUNCTION__)); | ||||||
415 | getTopOfStack().LoopStart = false; | ||||||
416 | } | ||||||
417 | /// true, if variables are captured, false otherwise. | ||||||
418 | bool isLoopStarted() const { | ||||||
419 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 420, __PRETTY_FUNCTION__)) | ||||||
420 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 420, __PRETTY_FUNCTION__)); | ||||||
421 | return !getTopOfStack().LoopStart; | ||||||
422 | } | ||||||
423 | /// Marks (or clears) declaration as possibly loop counter. | ||||||
424 | void resetPossibleLoopCounter(const Decl *D = nullptr) { | ||||||
425 | getTopOfStack().PossiblyLoopCounter = | ||||||
426 | D ? D->getCanonicalDecl() : D; | ||||||
427 | } | ||||||
428 | /// Gets the possible loop counter decl. | ||||||
429 | const Decl *getPossiblyLoopCunter() const { | ||||||
430 | return getTopOfStack().PossiblyLoopCounter; | ||||||
431 | } | ||||||
432 | /// Start new OpenMP region stack in new non-capturing function. | ||||||
433 | void pushFunction() { | ||||||
434 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 435, __PRETTY_FUNCTION__)) | ||||||
435 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 435, __PRETTY_FUNCTION__)); | ||||||
436 | const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); | ||||||
437 | assert(!isa<CapturingScopeInfo>(CurFnScope))((!isa<CapturingScopeInfo>(CurFnScope)) ? static_cast< void> (0) : __assert_fail ("!isa<CapturingScopeInfo>(CurFnScope)" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 437, __PRETTY_FUNCTION__)); | ||||||
438 | CurrentNonCapturingFunctionScope = CurFnScope; | ||||||
439 | } | ||||||
440 | /// Pop region stack for non-capturing function. | ||||||
441 | void popFunction(const FunctionScopeInfo *OldFSI) { | ||||||
442 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 443, __PRETTY_FUNCTION__)) | ||||||
443 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 443, __PRETTY_FUNCTION__)); | ||||||
444 | if (!Stack.empty() && Stack.back().second == OldFSI) { | ||||||
445 | assert(Stack.back().first.empty())((Stack.back().first.empty()) ? static_cast<void> (0) : __assert_fail ("Stack.back().first.empty()", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 445, __PRETTY_FUNCTION__)); | ||||||
446 | Stack.pop_back(); | ||||||
447 | } | ||||||
448 | CurrentNonCapturingFunctionScope = nullptr; | ||||||
449 | for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { | ||||||
450 | if (!isa<CapturingScopeInfo>(FSI)) { | ||||||
451 | CurrentNonCapturingFunctionScope = FSI; | ||||||
452 | break; | ||||||
453 | } | ||||||
454 | } | ||||||
455 | } | ||||||
456 | |||||||
457 | void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { | ||||||
458 | Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); | ||||||
459 | } | ||||||
460 | const std::pair<const OMPCriticalDirective *, llvm::APSInt> | ||||||
461 | getCriticalWithHint(const DeclarationNameInfo &Name) const { | ||||||
462 | auto I = Criticals.find(Name.getAsString()); | ||||||
463 | if (I != Criticals.end()) | ||||||
464 | return I->second; | ||||||
465 | return std::make_pair(nullptr, llvm::APSInt()); | ||||||
466 | } | ||||||
467 | /// If 'aligned' declaration for given variable \a D was not seen yet, | ||||||
468 | /// add it and return NULL; otherwise return previous occurrence's expression | ||||||
469 | /// for diagnostics. | ||||||
470 | const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); | ||||||
471 | /// If 'nontemporal' declaration for given variable \a D was not seen yet, | ||||||
472 | /// add it and return NULL; otherwise return previous occurrence's expression | ||||||
473 | /// for diagnostics. | ||||||
474 | const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE); | ||||||
475 | |||||||
476 | /// Register specified variable as loop control variable. | ||||||
477 | void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); | ||||||
478 | /// Check if the specified variable is a loop control variable for | ||||||
479 | /// current region. | ||||||
480 | /// \return The index of the loop control variable in the list of associated | ||||||
481 | /// for-loops (from outer to inner). | ||||||
482 | const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; | ||||||
483 | /// Check if the specified variable is a loop control variable for | ||||||
484 | /// parent region. | ||||||
485 | /// \return The index of the loop control variable in the list of associated | ||||||
486 | /// for-loops (from outer to inner). | ||||||
487 | const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; | ||||||
488 | /// Check if the specified variable is a loop control variable for | ||||||
489 | /// current region. | ||||||
490 | /// \return The index of the loop control variable in the list of associated | ||||||
491 | /// for-loops (from outer to inner). | ||||||
492 | const LCDeclInfo isLoopControlVariable(const ValueDecl *D, | ||||||
493 | unsigned Level) const; | ||||||
494 | /// Get the loop control variable for the I-th loop (or nullptr) in | ||||||
495 | /// parent directive. | ||||||
496 | const ValueDecl *getParentLoopControlVariable(unsigned I) const; | ||||||
497 | |||||||
498 | /// Marks the specified decl \p D as used in scan directive. | ||||||
499 | void markDeclAsUsedInScanDirective(ValueDecl *D) { | ||||||
500 | if (SharingMapTy *Stack = getSecondOnStackOrNull()) | ||||||
501 | Stack->UsedInScanDirective.insert(D); | ||||||
502 | } | ||||||
503 | |||||||
504 | /// Checks if the specified declaration was used in the inner scan directive. | ||||||
505 | bool isUsedInScanDirective(ValueDecl *D) const { | ||||||
506 | if (const SharingMapTy *Stack = getTopOfStackOrNull()) | ||||||
507 | return Stack->UsedInScanDirective.count(D) > 0; | ||||||
508 | return false; | ||||||
509 | } | ||||||
510 | |||||||
511 | /// Adds explicit data sharing attribute to the specified declaration. | ||||||
512 | void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, | ||||||
513 | DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0); | ||||||
514 | |||||||
515 | /// Adds additional information for the reduction items with the reduction id | ||||||
516 | /// represented as an operator. | ||||||
517 | void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, | ||||||
518 | BinaryOperatorKind BOK); | ||||||
519 | /// Adds additional information for the reduction items with the reduction id | ||||||
520 | /// represented as reduction identifier. | ||||||
521 | void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, | ||||||
522 | const Expr *ReductionRef); | ||||||
523 | /// Returns the location and reduction operation from the innermost parent | ||||||
524 | /// region for the given \p D. | ||||||
525 | const DSAVarData | ||||||
526 | getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, | ||||||
527 | BinaryOperatorKind &BOK, | ||||||
528 | Expr *&TaskgroupDescriptor) const; | ||||||
529 | /// Returns the location and reduction operation from the innermost parent | ||||||
530 | /// region for the given \p D. | ||||||
531 | const DSAVarData | ||||||
532 | getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, | ||||||
533 | const Expr *&ReductionRef, | ||||||
534 | Expr *&TaskgroupDescriptor) const; | ||||||
535 | /// Return reduction reference expression for the current taskgroup or | ||||||
536 | /// parallel/worksharing directives with task reductions. | ||||||
537 | Expr *getTaskgroupReductionRef() const { | ||||||
538 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 543, __PRETTY_FUNCTION__)) | ||||||
539 | ((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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 543, __PRETTY_FUNCTION__)) | ||||||
540 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 543, __PRETTY_FUNCTION__)) | ||||||
541 | !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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 543, __PRETTY_FUNCTION__)) | ||||||
542 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 543, __PRETTY_FUNCTION__)) | ||||||
543 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 543, __PRETTY_FUNCTION__)); | ||||||
544 | return getTopOfStack().TaskgroupReductionRef; | ||||||
545 | } | ||||||
546 | /// Checks if the given \p VD declaration is actually a taskgroup reduction | ||||||
547 | /// descriptor variable at the \p Level of OpenMP regions. | ||||||
548 | bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { | ||||||
549 | return getStackElemAtLevel(Level).TaskgroupReductionRef && | ||||||
550 | cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) | ||||||
551 | ->getDecl() == VD; | ||||||
552 | } | ||||||
553 | |||||||
554 | /// Returns data sharing attributes from top of the stack for the | ||||||
555 | /// specified declaration. | ||||||
556 | const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); | ||||||
557 | /// Returns data-sharing attributes for the specified declaration. | ||||||
558 | const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; | ||||||
559 | /// Returns data-sharing attributes for the specified declaration. | ||||||
560 | const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const; | ||||||
561 | /// Checks if the specified variables has data-sharing attributes which | ||||||
562 | /// match specified \a CPred predicate in any directive which matches \a DPred | ||||||
563 | /// predicate. | ||||||
564 | const DSAVarData | ||||||
565 | hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, | ||||||
566 | const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, | ||||||
567 | bool FromParent) const; | ||||||
568 | /// Checks if the specified variables has data-sharing attributes which | ||||||
569 | /// match specified \a CPred predicate in any innermost directive which | ||||||
570 | /// matches \a DPred predicate. | ||||||
571 | const DSAVarData | ||||||
572 | hasInnermostDSA(ValueDecl *D, | ||||||
573 | const llvm::function_ref<bool(OpenMPClauseKind)> CPred, | ||||||
574 | const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, | ||||||
575 | bool FromParent) const; | ||||||
576 | /// Checks if the specified variables has explicit data-sharing | ||||||
577 | /// attributes which match specified \a CPred predicate at the specified | ||||||
578 | /// OpenMP region. | ||||||
579 | bool hasExplicitDSA(const ValueDecl *D, | ||||||
580 | const llvm::function_ref<bool(OpenMPClauseKind)> CPred, | ||||||
581 | unsigned Level, bool NotLastprivate = false) const; | ||||||
582 | |||||||
583 | /// Returns true if the directive at level \Level matches in the | ||||||
584 | /// specified \a DPred predicate. | ||||||
585 | bool hasExplicitDirective( | ||||||
586 | const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, | ||||||
587 | unsigned Level) const; | ||||||
588 | |||||||
589 | /// Finds a directive which matches specified \a DPred predicate. | ||||||
590 | bool hasDirective( | ||||||
591 | const llvm::function_ref<bool( | ||||||
592 | OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> | ||||||
593 | DPred, | ||||||
594 | bool FromParent) const; | ||||||
595 | |||||||
596 | /// Returns currently analyzed directive. | ||||||
597 | OpenMPDirectiveKind getCurrentDirective() const { | ||||||
598 | const SharingMapTy *Top = getTopOfStackOrNull(); | ||||||
599 | return Top ? Top->Directive : OMPD_unknown; | ||||||
600 | } | ||||||
601 | /// Returns directive kind at specified level. | ||||||
602 | OpenMPDirectiveKind getDirective(unsigned Level) const { | ||||||
603 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 603, __PRETTY_FUNCTION__)); | ||||||
604 | return getStackElemAtLevel(Level).Directive; | ||||||
605 | } | ||||||
606 | /// Returns the capture region at the specified level. | ||||||
607 | OpenMPDirectiveKind getCaptureRegion(unsigned Level, | ||||||
608 | unsigned OpenMPCaptureLevel) const { | ||||||
609 | SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; | ||||||
610 | getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); | ||||||
611 | return CaptureRegions[OpenMPCaptureLevel]; | ||||||
612 | } | ||||||
613 | /// Returns parent directive. | ||||||
614 | OpenMPDirectiveKind getParentDirective() const { | ||||||
615 | const SharingMapTy *Parent = getSecondOnStackOrNull(); | ||||||
616 | return Parent ? Parent->Directive : OMPD_unknown; | ||||||
617 | } | ||||||
618 | |||||||
619 | /// Add requires decl to internal vector | ||||||
620 | void addRequiresDecl(OMPRequiresDecl *RD) { | ||||||
621 | RequiresDecls.push_back(RD); | ||||||
622 | } | ||||||
623 | |||||||
624 | /// Checks if the defined 'requires' directive has specified type of clause. | ||||||
625 | template <typename ClauseType> | ||||||
626 | bool hasRequiresDeclWithClause() const { | ||||||
627 | return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { | ||||||
628 | return llvm::any_of(D->clauselists(), [](const OMPClause *C) { | ||||||
629 | return isa<ClauseType>(C); | ||||||
630 | }); | ||||||
631 | }); | ||||||
632 | } | ||||||
633 | |||||||
634 | /// Checks for a duplicate clause amongst previously declared requires | ||||||
635 | /// directives | ||||||
636 | bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { | ||||||
637 | bool IsDuplicate = false; | ||||||
638 | for (OMPClause *CNew : ClauseList) { | ||||||
639 | for (const OMPRequiresDecl *D : RequiresDecls) { | ||||||
640 | for (const OMPClause *CPrev : D->clauselists()) { | ||||||
641 | if (CNew->getClauseKind() == CPrev->getClauseKind()) { | ||||||
642 | SemaRef.Diag(CNew->getBeginLoc(), | ||||||
643 | diag::err_omp_requires_clause_redeclaration) | ||||||
644 | << getOpenMPClauseName(CNew->getClauseKind()); | ||||||
645 | SemaRef.Diag(CPrev->getBeginLoc(), | ||||||
646 | diag::note_omp_requires_previous_clause) | ||||||
647 | << getOpenMPClauseName(CPrev->getClauseKind()); | ||||||
648 | IsDuplicate = true; | ||||||
649 | } | ||||||
650 | } | ||||||
651 | } | ||||||
652 | } | ||||||
653 | return IsDuplicate; | ||||||
654 | } | ||||||
655 | |||||||
656 | /// Add location of previously encountered target to internal vector | ||||||
657 | void addTargetDirLocation(SourceLocation LocStart) { | ||||||
658 | TargetLocations.push_back(LocStart); | ||||||
659 | } | ||||||
660 | |||||||
661 | /// Add location for the first encountered atomicc directive. | ||||||
662 | void addAtomicDirectiveLoc(SourceLocation Loc) { | ||||||
663 | if (AtomicLocation.isInvalid()) | ||||||
664 | AtomicLocation = Loc; | ||||||
665 | } | ||||||
666 | |||||||
667 | /// Returns the location of the first encountered atomic directive in the | ||||||
668 | /// module. | ||||||
669 | SourceLocation getAtomicDirectiveLoc() const { | ||||||
670 | return AtomicLocation; | ||||||
671 | } | ||||||
672 | |||||||
673 | // Return previously encountered target region locations. | ||||||
674 | ArrayRef<SourceLocation> getEncounteredTargetLocs() const { | ||||||
675 | return TargetLocations; | ||||||
676 | } | ||||||
677 | |||||||
678 | /// Set default data sharing attribute to none. | ||||||
679 | void setDefaultDSANone(SourceLocation Loc) { | ||||||
680 | getTopOfStack().DefaultAttr = DSA_none; | ||||||
681 | getTopOfStack().DefaultAttrLoc = Loc; | ||||||
682 | } | ||||||
683 | /// Set default data sharing attribute to shared. | ||||||
684 | void setDefaultDSAShared(SourceLocation Loc) { | ||||||
685 | getTopOfStack().DefaultAttr = DSA_shared; | ||||||
686 | getTopOfStack().DefaultAttrLoc = Loc; | ||||||
687 | } | ||||||
688 | /// Set default data sharing attribute to firstprivate. | ||||||
689 | void setDefaultDSAFirstPrivate(SourceLocation Loc) { | ||||||
690 | getTopOfStack().DefaultAttr = DSA_firstprivate; | ||||||
691 | getTopOfStack().DefaultAttrLoc = Loc; | ||||||
692 | } | ||||||
693 | /// Set default data mapping attribute to Modifier:Kind | ||||||
694 | void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, | ||||||
695 | OpenMPDefaultmapClauseKind Kind, | ||||||
696 | SourceLocation Loc) { | ||||||
697 | DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind]; | ||||||
698 | DMI.ImplicitBehavior = M; | ||||||
699 | DMI.SLoc = Loc; | ||||||
700 | } | ||||||
701 | /// Check whether the implicit-behavior has been set in defaultmap | ||||||
702 | bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) { | ||||||
703 | if (VariableCategory == OMPC_DEFAULTMAP_unknown) | ||||||
704 | return getTopOfStack() | ||||||
705 | .DefaultmapMap[OMPC_DEFAULTMAP_aggregate] | ||||||
706 | .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || | ||||||
707 | getTopOfStack() | ||||||
708 | .DefaultmapMap[OMPC_DEFAULTMAP_scalar] | ||||||
709 | .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || | ||||||
710 | getTopOfStack() | ||||||
711 | .DefaultmapMap[OMPC_DEFAULTMAP_pointer] | ||||||
712 | .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown; | ||||||
713 | return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior != | ||||||
714 | OMPC_DEFAULTMAP_MODIFIER_unknown; | ||||||
715 | } | ||||||
716 | |||||||
717 | DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const { | ||||||
718 | return getStackSize() <= Level ? DSA_unspecified | ||||||
719 | : getStackElemAtLevel(Level).DefaultAttr; | ||||||
720 | } | ||||||
721 | DefaultDataSharingAttributes getDefaultDSA() const { | ||||||
722 | return isStackEmpty() ? DSA_unspecified | ||||||
723 | : getTopOfStack().DefaultAttr; | ||||||
724 | } | ||||||
725 | SourceLocation getDefaultDSALocation() const { | ||||||
726 | return isStackEmpty() ? SourceLocation() | ||||||
727 | : getTopOfStack().DefaultAttrLoc; | ||||||
728 | } | ||||||
729 | OpenMPDefaultmapClauseModifier | ||||||
730 | getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const { | ||||||
731 | return isStackEmpty() | ||||||
732 | ? OMPC_DEFAULTMAP_MODIFIER_unknown | ||||||
733 | : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior; | ||||||
734 | } | ||||||
735 | OpenMPDefaultmapClauseModifier | ||||||
736 | getDefaultmapModifierAtLevel(unsigned Level, | ||||||
737 | OpenMPDefaultmapClauseKind Kind) const { | ||||||
738 | return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior; | ||||||
739 | } | ||||||
740 | bool isDefaultmapCapturedByRef(unsigned Level, | ||||||
741 | OpenMPDefaultmapClauseKind Kind) const { | ||||||
742 | OpenMPDefaultmapClauseModifier M = | ||||||
743 | getDefaultmapModifierAtLevel(Level, Kind); | ||||||
744 | if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) { | ||||||
745 | return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) || | ||||||
746 | (M == OMPC_DEFAULTMAP_MODIFIER_to) || | ||||||
747 | (M == OMPC_DEFAULTMAP_MODIFIER_from) || | ||||||
748 | (M == OMPC_DEFAULTMAP_MODIFIER_tofrom); | ||||||
749 | } | ||||||
750 | return true; | ||||||
751 | } | ||||||
752 | static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M, | ||||||
753 | OpenMPDefaultmapClauseKind Kind) { | ||||||
754 | switch (Kind) { | ||||||
755 | case OMPC_DEFAULTMAP_scalar: | ||||||
756 | case OMPC_DEFAULTMAP_pointer: | ||||||
757 | return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) || | ||||||
758 | (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) || | ||||||
759 | (M == OMPC_DEFAULTMAP_MODIFIER_default); | ||||||
760 | case OMPC_DEFAULTMAP_aggregate: | ||||||
761 | return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate; | ||||||
762 | default: | ||||||
763 | break; | ||||||
764 | } | ||||||
765 | llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum")::llvm::llvm_unreachable_internal("Unexpected OpenMPDefaultmapClauseKind enum" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 765); | ||||||
766 | } | ||||||
767 | bool mustBeFirstprivateAtLevel(unsigned Level, | ||||||
768 | OpenMPDefaultmapClauseKind Kind) const { | ||||||
769 | OpenMPDefaultmapClauseModifier M = | ||||||
770 | getDefaultmapModifierAtLevel(Level, Kind); | ||||||
771 | return mustBeFirstprivateBase(M, Kind); | ||||||
772 | } | ||||||
773 | bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const { | ||||||
774 | OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind); | ||||||
775 | return mustBeFirstprivateBase(M, Kind); | ||||||
776 | } | ||||||
777 | |||||||
778 | /// Checks if the specified variable is a threadprivate. | ||||||
779 | bool isThreadPrivate(VarDecl *D) { | ||||||
780 | const DSAVarData DVar = getTopDSA(D, false); | ||||||
781 | return isOpenMPThreadPrivate(DVar.CKind); | ||||||
782 | } | ||||||
783 | |||||||
784 | /// Marks current region as ordered (it has an 'ordered' clause). | ||||||
785 | void setOrderedRegion(bool IsOrdered, const Expr *Param, | ||||||
786 | OMPOrderedClause *Clause) { | ||||||
787 | if (IsOrdered) | ||||||
788 | getTopOfStack().OrderedRegion.emplace(Param, Clause); | ||||||
789 | else | ||||||
790 | getTopOfStack().OrderedRegion.reset(); | ||||||
791 | } | ||||||
792 | /// Returns true, if region is ordered (has associated 'ordered' clause), | ||||||
793 | /// false - otherwise. | ||||||
794 | bool isOrderedRegion() const { | ||||||
795 | if (const SharingMapTy *Top = getTopOfStackOrNull()) | ||||||
796 | return Top->OrderedRegion.hasValue(); | ||||||
797 | return false; | ||||||
798 | } | ||||||
799 | /// Returns optional parameter for the ordered region. | ||||||
800 | std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { | ||||||
801 | if (const SharingMapTy *Top = getTopOfStackOrNull()) | ||||||
802 | if (Top->OrderedRegion.hasValue()) | ||||||
803 | return Top->OrderedRegion.getValue(); | ||||||
804 | return std::make_pair(nullptr, nullptr); | ||||||
805 | } | ||||||
806 | /// Returns true, if parent region is ordered (has associated | ||||||
807 | /// 'ordered' clause), false - otherwise. | ||||||
808 | bool isParentOrderedRegion() const { | ||||||
809 | if (const SharingMapTy *Parent = getSecondOnStackOrNull()) | ||||||
810 | return Parent->OrderedRegion.hasValue(); | ||||||
811 | return false; | ||||||
812 | } | ||||||
813 | /// Returns optional parameter for the ordered region. | ||||||
814 | std::pair<const Expr *, OMPOrderedClause *> | ||||||
815 | getParentOrderedRegionParam() const { | ||||||
816 | if (const SharingMapTy *Parent = getSecondOnStackOrNull()) | ||||||
817 | if (Parent->OrderedRegion.hasValue()) | ||||||
818 | return Parent->OrderedRegion.getValue(); | ||||||
819 | return std::make_pair(nullptr, nullptr); | ||||||
820 | } | ||||||
821 | /// Marks current region as nowait (it has a 'nowait' clause). | ||||||
822 | void setNowaitRegion(bool IsNowait = true) { | ||||||
823 | getTopOfStack().NowaitRegion = IsNowait; | ||||||
824 | } | ||||||
825 | /// Returns true, if parent region is nowait (has associated | ||||||
826 | /// 'nowait' clause), false - otherwise. | ||||||
827 | bool isParentNowaitRegion() const { | ||||||
828 | if (const SharingMapTy *Parent = getSecondOnStackOrNull()) | ||||||
829 | return Parent->NowaitRegion; | ||||||
830 | return false; | ||||||
831 | } | ||||||
832 | /// Marks parent region as cancel region. | ||||||
833 | void setParentCancelRegion(bool Cancel = true) { | ||||||
834 | if (SharingMapTy *Parent = getSecondOnStackOrNull()) | ||||||
835 | Parent->CancelRegion |= Cancel; | ||||||
836 | } | ||||||
837 | /// Return true if current region has inner cancel construct. | ||||||
838 | bool isCancelRegion() const { | ||||||
839 | const SharingMapTy *Top = getTopOfStackOrNull(); | ||||||
840 | return Top ? Top->CancelRegion : false; | ||||||
841 | } | ||||||
842 | |||||||
843 | /// Mark that parent region already has scan directive. | ||||||
844 | void setParentHasScanDirective(SourceLocation Loc) { | ||||||
845 | if (SharingMapTy *Parent = getSecondOnStackOrNull()) | ||||||
846 | Parent->PrevScanLocation = Loc; | ||||||
847 | } | ||||||
848 | /// Return true if current region has inner cancel construct. | ||||||
849 | bool doesParentHasScanDirective() const { | ||||||
850 | const SharingMapTy *Top = getSecondOnStackOrNull(); | ||||||
851 | return Top ? Top->PrevScanLocation.isValid() : false; | ||||||
852 | } | ||||||
853 | /// Return true if current region has inner cancel construct. | ||||||
854 | SourceLocation getParentScanDirectiveLoc() const { | ||||||
855 | const SharingMapTy *Top = getSecondOnStackOrNull(); | ||||||
856 | return Top ? Top->PrevScanLocation : SourceLocation(); | ||||||
857 | } | ||||||
858 | /// Mark that parent region already has ordered directive. | ||||||
859 | void setParentHasOrderedDirective(SourceLocation Loc) { | ||||||
860 | if (SharingMapTy *Parent = getSecondOnStackOrNull()) | ||||||
861 | Parent->PrevOrderedLocation = Loc; | ||||||
862 | } | ||||||
863 | /// Return true if current region has inner ordered construct. | ||||||
864 | bool doesParentHasOrderedDirective() const { | ||||||
865 | const SharingMapTy *Top = getSecondOnStackOrNull(); | ||||||
866 | return Top ? Top->PrevOrderedLocation.isValid() : false; | ||||||
867 | } | ||||||
868 | /// Returns the location of the previously specified ordered directive. | ||||||
869 | SourceLocation getParentOrderedDirectiveLoc() const { | ||||||
870 | const SharingMapTy *Top = getSecondOnStackOrNull(); | ||||||
871 | return Top ? Top->PrevOrderedLocation : SourceLocation(); | ||||||
872 | } | ||||||
873 | |||||||
874 | /// Set collapse value for the region. | ||||||
875 | void setAssociatedLoops(unsigned Val) { | ||||||
876 | getTopOfStack().AssociatedLoops = Val; | ||||||
877 | if (Val > 1) | ||||||
878 | getTopOfStack().HasMutipleLoops = true; | ||||||
879 | } | ||||||
880 | /// Return collapse value for region. | ||||||
881 | unsigned getAssociatedLoops() const { | ||||||
882 | const SharingMapTy *Top = getTopOfStackOrNull(); | ||||||
883 | return Top ? Top->AssociatedLoops : 0; | ||||||
884 | } | ||||||
885 | /// Returns true if the construct is associated with multiple loops. | ||||||
886 | bool hasMutipleLoops() const { | ||||||
887 | const SharingMapTy *Top = getTopOfStackOrNull(); | ||||||
888 | return Top ? Top->HasMutipleLoops : false; | ||||||
889 | } | ||||||
890 | |||||||
891 | /// Marks current target region as one with closely nested teams | ||||||
892 | /// region. | ||||||
893 | void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { | ||||||
894 | if (SharingMapTy *Parent = getSecondOnStackOrNull()) | ||||||
895 | Parent->InnerTeamsRegionLoc = TeamsRegionLoc; | ||||||
896 | } | ||||||
897 | /// Returns true, if current region has closely nested teams region. | ||||||
898 | bool hasInnerTeamsRegion() const { | ||||||
899 | return getInnerTeamsRegionLoc().isValid(); | ||||||
900 | } | ||||||
901 | /// Returns location of the nested teams region (if any). | ||||||
902 | SourceLocation getInnerTeamsRegionLoc() const { | ||||||
903 | const SharingMapTy *Top = getTopOfStackOrNull(); | ||||||
904 | return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); | ||||||
905 | } | ||||||
906 | |||||||
907 | Scope *getCurScope() const { | ||||||
908 | const SharingMapTy *Top = getTopOfStackOrNull(); | ||||||
909 | return Top ? Top->CurScope : nullptr; | ||||||
910 | } | ||||||
911 | SourceLocation getConstructLoc() const { | ||||||
912 | const SharingMapTy *Top = getTopOfStackOrNull(); | ||||||
913 | return Top ? Top->ConstructLoc : SourceLocation(); | ||||||
914 | } | ||||||
915 | |||||||
916 | /// Do the check specified in \a Check to all component lists and return true | ||||||
917 | /// if any issue is found. | ||||||
918 | bool checkMappableExprComponentListsForDecl( | ||||||
919 | const ValueDecl *VD, bool CurrentRegionOnly, | ||||||
920 | const llvm::function_ref< | ||||||
921 | bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, | ||||||
922 | OpenMPClauseKind)> | ||||||
923 | Check) const { | ||||||
924 | if (isStackEmpty()) | ||||||
925 | return false; | ||||||
926 | auto SI = begin(); | ||||||
927 | auto SE = end(); | ||||||
928 | |||||||
929 | if (SI == SE) | ||||||
930 | return false; | ||||||
931 | |||||||
932 | if (CurrentRegionOnly) | ||||||
933 | SE = std::next(SI); | ||||||
934 | else | ||||||
935 | std::advance(SI, 1); | ||||||
936 | |||||||
937 | for (; SI != SE; ++SI) { | ||||||
938 | auto MI = SI->MappedExprComponents.find(VD); | ||||||
939 | if (MI != SI->MappedExprComponents.end()) | ||||||
940 | for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : | ||||||
941 | MI->second.Components) | ||||||
942 | if (Check(L, MI->second.Kind)) | ||||||
943 | return true; | ||||||
944 | } | ||||||
945 | return false; | ||||||
946 | } | ||||||
947 | |||||||
948 | /// Do the check specified in \a Check to all component lists at a given level | ||||||
949 | /// and return true if any issue is found. | ||||||
950 | bool checkMappableExprComponentListsForDeclAtLevel( | ||||||
951 | const ValueDecl *VD, unsigned Level, | ||||||
952 | const llvm::function_ref< | ||||||
953 | bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, | ||||||
954 | OpenMPClauseKind)> | ||||||
955 | Check) const { | ||||||
956 | if (getStackSize() <= Level) | ||||||
957 | return false; | ||||||
958 | |||||||
959 | const SharingMapTy &StackElem = getStackElemAtLevel(Level); | ||||||
960 | auto MI = StackElem.MappedExprComponents.find(VD); | ||||||
961 | if (MI != StackElem.MappedExprComponents.end()) | ||||||
962 | for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : | ||||||
963 | MI->second.Components) | ||||||
964 | if (Check(L, MI->second.Kind)) | ||||||
965 | return true; | ||||||
966 | return false; | ||||||
967 | } | ||||||
968 | |||||||
969 | /// Create a new mappable expression component list associated with a given | ||||||
970 | /// declaration and initialize it with the provided list of components. | ||||||
971 | void addMappableExpressionComponents( | ||||||
972 | const ValueDecl *VD, | ||||||
973 | OMPClauseMappableExprCommon::MappableExprComponentListRef Components, | ||||||
974 | OpenMPClauseKind WhereFoundClauseKind) { | ||||||
975 | MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; | ||||||
976 | // Create new entry and append the new components there. | ||||||
977 | MEC.Components.resize(MEC.Components.size() + 1); | ||||||
978 | MEC.Components.back().append(Components.begin(), Components.end()); | ||||||
979 | MEC.Kind = WhereFoundClauseKind; | ||||||
980 | } | ||||||
981 | |||||||
982 | unsigned getNestingLevel() const { | ||||||
983 | assert(!isStackEmpty())((!isStackEmpty()) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty()", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 983, __PRETTY_FUNCTION__)); | ||||||
984 | return getStackSize() - 1; | ||||||
985 | } | ||||||
986 | void addDoacrossDependClause(OMPDependClause *C, | ||||||
987 | const OperatorOffsetTy &OpsOffs) { | ||||||
988 | SharingMapTy *Parent = getSecondOnStackOrNull(); | ||||||
989 | assert(Parent && isOpenMPWorksharingDirective(Parent->Directive))((Parent && isOpenMPWorksharingDirective(Parent->Directive )) ? static_cast<void> (0) : __assert_fail ("Parent && isOpenMPWorksharingDirective(Parent->Directive)" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 989, __PRETTY_FUNCTION__)); | ||||||
990 | Parent->DoacrossDepends.try_emplace(C, OpsOffs); | ||||||
991 | } | ||||||
992 | llvm::iterator_range<DoacrossDependMapTy::const_iterator> | ||||||
993 | getDoacrossDependClauses() const { | ||||||
994 | const SharingMapTy &StackElem = getTopOfStack(); | ||||||
995 | if (isOpenMPWorksharingDirective(StackElem.Directive)) { | ||||||
996 | const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; | ||||||
997 | return llvm::make_range(Ref.begin(), Ref.end()); | ||||||
998 | } | ||||||
999 | return llvm::make_range(StackElem.DoacrossDepends.end(), | ||||||
1000 | StackElem.DoacrossDepends.end()); | ||||||
1001 | } | ||||||
1002 | |||||||
1003 | // Store types of classes which have been explicitly mapped | ||||||
1004 | void addMappedClassesQualTypes(QualType QT) { | ||||||
1005 | SharingMapTy &StackElem = getTopOfStack(); | ||||||
1006 | StackElem.MappedClassesQualTypes.insert(QT); | ||||||
1007 | } | ||||||
1008 | |||||||
1009 | // Return set of mapped classes types | ||||||
1010 | bool isClassPreviouslyMapped(QualType QT) const { | ||||||
1011 | const SharingMapTy &StackElem = getTopOfStack(); | ||||||
1012 | return StackElem.MappedClassesQualTypes.count(QT) != 0; | ||||||
1013 | } | ||||||
1014 | |||||||
1015 | /// Adds global declare target to the parent target region. | ||||||
1016 | void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { | ||||||
1017 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1019, __PRETTY_FUNCTION__)) | ||||||
1018 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1019, __PRETTY_FUNCTION__)) | ||||||
1019 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1019, __PRETTY_FUNCTION__)); | ||||||
1020 | for (auto &Elem : *this) { | ||||||
1021 | if (isOpenMPTargetExecutionDirective(Elem.Directive)) { | ||||||
1022 | Elem.DeclareTargetLinkVarDecls.push_back(E); | ||||||
1023 | return; | ||||||
1024 | } | ||||||
1025 | } | ||||||
1026 | } | ||||||
1027 | |||||||
1028 | /// Returns the list of globals with declare target link if current directive | ||||||
1029 | /// is target. | ||||||
1030 | ArrayRef<DeclRefExpr *> getLinkGlobals() const { | ||||||
1031 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1032, __PRETTY_FUNCTION__)) | ||||||
1032 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1032, __PRETTY_FUNCTION__)); | ||||||
1033 | return getTopOfStack().DeclareTargetLinkVarDecls; | ||||||
1034 | } | ||||||
1035 | |||||||
1036 | /// Adds list of allocators expressions. | ||||||
1037 | void addInnerAllocatorExpr(Expr *E) { | ||||||
1038 | getTopOfStack().InnerUsedAllocators.push_back(E); | ||||||
1039 | } | ||||||
1040 | /// Return list of used allocators. | ||||||
1041 | ArrayRef<Expr *> getInnerAllocators() const { | ||||||
1042 | return getTopOfStack().InnerUsedAllocators; | ||||||
1043 | } | ||||||
1044 | /// Marks the declaration as implicitly firstprivate nin the task-based | ||||||
1045 | /// regions. | ||||||
1046 | void addImplicitTaskFirstprivate(unsigned Level, Decl *D) { | ||||||
1047 | getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D); | ||||||
1048 | } | ||||||
1049 | /// Checks if the decl is implicitly firstprivate in the task-based region. | ||||||
1050 | bool isImplicitTaskFirstprivate(Decl *D) const { | ||||||
1051 | return getTopOfStack().ImplicitTaskFirstprivates.count(D) > 0; | ||||||
1052 | } | ||||||
1053 | |||||||
1054 | /// Marks decl as used in uses_allocators clause as the allocator. | ||||||
1055 | void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) { | ||||||
1056 | getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind); | ||||||
1057 | } | ||||||
1058 | /// Checks if specified decl is used in uses allocator clause as the | ||||||
1059 | /// allocator. | ||||||
1060 | Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level, | ||||||
1061 | const Decl *D) const { | ||||||
1062 | const SharingMapTy &StackElem = getTopOfStack(); | ||||||
1063 | auto I = StackElem.UsesAllocatorsDecls.find(D); | ||||||
1064 | if (I == StackElem.UsesAllocatorsDecls.end()) | ||||||
1065 | return None; | ||||||
1066 | return I->getSecond(); | ||||||
1067 | } | ||||||
1068 | Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const { | ||||||
1069 | const SharingMapTy &StackElem = getTopOfStack(); | ||||||
1070 | auto I = StackElem.UsesAllocatorsDecls.find(D); | ||||||
1071 | if (I == StackElem.UsesAllocatorsDecls.end()) | ||||||
1072 | return None; | ||||||
1073 | return I->getSecond(); | ||||||
1074 | } | ||||||
1075 | }; | ||||||
1076 | |||||||
1077 | bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { | ||||||
1078 | return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); | ||||||
1079 | } | ||||||
1080 | |||||||
1081 | bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { | ||||||
1082 | return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || | ||||||
1083 | DKind == OMPD_unknown; | ||||||
1084 | } | ||||||
1085 | |||||||
1086 | } // namespace | ||||||
1087 | |||||||
1088 | static const Expr *getExprAsWritten(const Expr *E) { | ||||||
1089 | if (const auto *FE = dyn_cast<FullExpr>(E)) | ||||||
1090 | E = FE->getSubExpr(); | ||||||
1091 | |||||||
1092 | if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) | ||||||
1093 | E = MTE->getSubExpr(); | ||||||
1094 | |||||||
1095 | while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) | ||||||
1096 | E = Binder->getSubExpr(); | ||||||
1097 | |||||||
1098 | if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) | ||||||
1099 | E = ICE->getSubExprAsWritten(); | ||||||
1100 | return E->IgnoreParens(); | ||||||
1101 | } | ||||||
1102 | |||||||
1103 | static Expr *getExprAsWritten(Expr *E) { | ||||||
1104 | return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); | ||||||
1105 | } | ||||||
1106 | |||||||
1107 | static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { | ||||||
1108 | if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) | ||||||
1109 | if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) | ||||||
1110 | D = ME->getMemberDecl(); | ||||||
1111 | const auto *VD = dyn_cast<VarDecl>(D); | ||||||
1112 | const auto *FD = dyn_cast<FieldDecl>(D); | ||||||
1113 | if (VD != nullptr) { | ||||||
1114 | VD = VD->getCanonicalDecl(); | ||||||
1115 | D = VD; | ||||||
1116 | } else { | ||||||
1117 | assert(FD)((FD) ? static_cast<void> (0) : __assert_fail ("FD", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1117, __PRETTY_FUNCTION__)); | ||||||
1118 | FD = FD->getCanonicalDecl(); | ||||||
1119 | D = FD; | ||||||
1120 | } | ||||||
1121 | return D; | ||||||
1122 | } | ||||||
1123 | |||||||
1124 | static ValueDecl *getCanonicalDecl(ValueDecl *D) { | ||||||
1125 | return const_cast<ValueDecl *>( | ||||||
1126 | getCanonicalDecl(const_cast<const ValueDecl *>(D))); | ||||||
1127 | } | ||||||
1128 | |||||||
1129 | DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, | ||||||
1130 | ValueDecl *D) const { | ||||||
1131 | D = getCanonicalDecl(D); | ||||||
1132 | auto *VD = dyn_cast<VarDecl>(D); | ||||||
1133 | const auto *FD = dyn_cast<FieldDecl>(D); | ||||||
1134 | DSAVarData DVar; | ||||||
1135 | if (Iter == end()) { | ||||||
1136 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||
1137 | // in a region but not in construct] | ||||||
1138 | // File-scope or namespace-scope variables referenced in called routines | ||||||
1139 | // in the region are shared unless they appear in a threadprivate | ||||||
1140 | // directive. | ||||||
1141 | if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) | ||||||
1142 | DVar.CKind = OMPC_shared; | ||||||
1143 | |||||||
1144 | // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced | ||||||
1145 | // in a region but not in construct] | ||||||
1146 | // Variables with static storage duration that are declared in called | ||||||
1147 | // routines in the region are shared. | ||||||
1148 | if (VD && VD->hasGlobalStorage()) | ||||||
1149 | DVar.CKind = OMPC_shared; | ||||||
1150 | |||||||
1151 | // Non-static data members are shared by default. | ||||||
1152 | if (FD) | ||||||
1153 | DVar.CKind = OMPC_shared; | ||||||
1154 | |||||||
1155 | return DVar; | ||||||
1156 | } | ||||||
1157 | |||||||
1158 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||
1159 | // in a Construct, C/C++, predetermined, p.1] | ||||||
1160 | // Variables with automatic storage duration that are declared in a scope | ||||||
1161 | // inside the construct are private. | ||||||
1162 | if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && | ||||||
1163 | (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { | ||||||
1164 | DVar.CKind = OMPC_private; | ||||||
1165 | return DVar; | ||||||
1166 | } | ||||||
1167 | |||||||
1168 | DVar.DKind = Iter->Directive; | ||||||
1169 | // Explicitly specified attributes and local variables with predetermined | ||||||
1170 | // attributes. | ||||||
1171 | if (Iter->SharingMap.count(D)) { | ||||||
1172 | const DSAInfo &Data = Iter->SharingMap.lookup(D); | ||||||
1173 | DVar.RefExpr = Data.RefExpr.getPointer(); | ||||||
1174 | DVar.PrivateCopy = Data.PrivateCopy; | ||||||
1175 | DVar.CKind = Data.Attributes; | ||||||
1176 | DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; | ||||||
1177 | DVar.Modifier = Data.Modifier; | ||||||
1178 | return DVar; | ||||||
1179 | } | ||||||
1180 | |||||||
1181 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||
1182 | // in a Construct, C/C++, implicitly determined, p.1] | ||||||
1183 | // In a parallel or task construct, the data-sharing attributes of these | ||||||
1184 | // variables are determined by the default clause, if present. | ||||||
1185 | switch (Iter->DefaultAttr) { | ||||||
1186 | case DSA_shared: | ||||||
1187 | DVar.CKind = OMPC_shared; | ||||||
1188 | DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; | ||||||
1189 | return DVar; | ||||||
1190 | case DSA_none: | ||||||
1191 | return DVar; | ||||||
1192 | case DSA_firstprivate: | ||||||
1193 | if (VD->getStorageDuration() == SD_Static && | ||||||
1194 | VD->getDeclContext()->isFileContext()) { | ||||||
1195 | DVar.CKind = OMPC_unknown; | ||||||
1196 | } else { | ||||||
1197 | DVar.CKind = OMPC_firstprivate; | ||||||
1198 | } | ||||||
1199 | DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; | ||||||
1200 | return DVar; | ||||||
1201 | case DSA_unspecified: | ||||||
1202 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||
1203 | // in a Construct, implicitly determined, p.2] | ||||||
1204 | // In a parallel construct, if no default clause is present, these | ||||||
1205 | // variables are shared. | ||||||
1206 | DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; | ||||||
1207 | if ((isOpenMPParallelDirective(DVar.DKind) && | ||||||
1208 | !isOpenMPTaskLoopDirective(DVar.DKind)) || | ||||||
1209 | isOpenMPTeamsDirective(DVar.DKind)) { | ||||||
1210 | DVar.CKind = OMPC_shared; | ||||||
1211 | return DVar; | ||||||
1212 | } | ||||||
1213 | |||||||
1214 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||
1215 | // in a Construct, implicitly determined, p.4] | ||||||
1216 | // In a task construct, if no default clause is present, a variable that in | ||||||
1217 | // the enclosing context is determined to be shared by all implicit tasks | ||||||
1218 | // bound to the current team is shared. | ||||||
1219 | if (isOpenMPTaskingDirective(DVar.DKind)) { | ||||||
1220 | DSAVarData DVarTemp; | ||||||
1221 | const_iterator I = Iter, E = end(); | ||||||
1222 | do { | ||||||
1223 | ++I; | ||||||
1224 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables | ||||||
1225 | // Referenced in a Construct, implicitly determined, p.6] | ||||||
1226 | // In a task construct, if no default clause is present, a variable | ||||||
1227 | // whose data-sharing attribute is not determined by the rules above is | ||||||
1228 | // firstprivate. | ||||||
1229 | DVarTemp = getDSA(I, D); | ||||||
1230 | if (DVarTemp.CKind != OMPC_shared) { | ||||||
1231 | DVar.RefExpr = nullptr; | ||||||
1232 | DVar.CKind = OMPC_firstprivate; | ||||||
1233 | return DVar; | ||||||
1234 | } | ||||||
1235 | } while (I != E && !isImplicitTaskingRegion(I->Directive)); | ||||||
1236 | DVar.CKind = | ||||||
1237 | (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; | ||||||
1238 | return DVar; | ||||||
1239 | } | ||||||
1240 | } | ||||||
1241 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||
1242 | // in a Construct, implicitly determined, p.3] | ||||||
1243 | // For constructs other than task, if no default clause is present, these | ||||||
1244 | // variables inherit their data-sharing attributes from the enclosing | ||||||
1245 | // context. | ||||||
1246 | return getDSA(++Iter, D); | ||||||
1247 | } | ||||||
1248 | |||||||
1249 | const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, | ||||||
1250 | const Expr *NewDE) { | ||||||
1251 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1251, __PRETTY_FUNCTION__)); | ||||||
1252 | D = getCanonicalDecl(D); | ||||||
1253 | SharingMapTy &StackElem = getTopOfStack(); | ||||||
1254 | auto It = StackElem.AlignedMap.find(D); | ||||||
1255 | if (It == StackElem.AlignedMap.end()) { | ||||||
1256 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1256, __PRETTY_FUNCTION__)); | ||||||
1257 | StackElem.AlignedMap[D] = NewDE; | ||||||
1258 | return nullptr; | ||||||
1259 | } | ||||||
1260 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1260, __PRETTY_FUNCTION__)); | ||||||
1261 | return It->second; | ||||||
1262 | } | ||||||
1263 | |||||||
1264 | const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D, | ||||||
1265 | const Expr *NewDE) { | ||||||
1266 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1266, __PRETTY_FUNCTION__)); | ||||||
1267 | D = getCanonicalDecl(D); | ||||||
1268 | SharingMapTy &StackElem = getTopOfStack(); | ||||||
1269 | auto It = StackElem.NontemporalMap.find(D); | ||||||
1270 | if (It == StackElem.NontemporalMap.end()) { | ||||||
1271 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1271, __PRETTY_FUNCTION__)); | ||||||
1272 | StackElem.NontemporalMap[D] = NewDE; | ||||||
1273 | return nullptr; | ||||||
1274 | } | ||||||
1275 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1275, __PRETTY_FUNCTION__)); | ||||||
1276 | return It->second; | ||||||
1277 | } | ||||||
1278 | |||||||
1279 | void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { | ||||||
1280 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1280, __PRETTY_FUNCTION__)); | ||||||
1281 | D = getCanonicalDecl(D); | ||||||
1282 | SharingMapTy &StackElem = getTopOfStack(); | ||||||
1283 | StackElem.LCVMap.try_emplace( | ||||||
1284 | D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); | ||||||
1285 | } | ||||||
1286 | |||||||
1287 | const DSAStackTy::LCDeclInfo | ||||||
1288 | DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { | ||||||
1289 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1289, __PRETTY_FUNCTION__)); | ||||||
1290 | D = getCanonicalDecl(D); | ||||||
1291 | const SharingMapTy &StackElem = getTopOfStack(); | ||||||
1292 | auto It = StackElem.LCVMap.find(D); | ||||||
1293 | if (It != StackElem.LCVMap.end()) | ||||||
1294 | return It->second; | ||||||
1295 | return {0, nullptr}; | ||||||
1296 | } | ||||||
1297 | |||||||
1298 | const DSAStackTy::LCDeclInfo | ||||||
1299 | DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const { | ||||||
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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1300, __PRETTY_FUNCTION__)); | ||||||
1301 | D = getCanonicalDecl(D); | ||||||
1302 | for (unsigned I = Level + 1; I > 0; --I) { | ||||||
1303 | const SharingMapTy &StackElem = getStackElemAtLevel(I - 1); | ||||||
1304 | auto It = StackElem.LCVMap.find(D); | ||||||
1305 | if (It != StackElem.LCVMap.end()) | ||||||
1306 | return It->second; | ||||||
1307 | } | ||||||
1308 | return {0, nullptr}; | ||||||
1309 | } | ||||||
1310 | |||||||
1311 | const DSAStackTy::LCDeclInfo | ||||||
1312 | DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { | ||||||
1313 | const SharingMapTy *Parent = getSecondOnStackOrNull(); | ||||||
1314 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1314, __PRETTY_FUNCTION__)); | ||||||
1315 | D = getCanonicalDecl(D); | ||||||
1316 | auto It = Parent->LCVMap.find(D); | ||||||
1317 | if (It != Parent->LCVMap.end()) | ||||||
1318 | return It->second; | ||||||
1319 | return {0, nullptr}; | ||||||
1320 | } | ||||||
1321 | |||||||
1322 | const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { | ||||||
1323 | const SharingMapTy *Parent = getSecondOnStackOrNull(); | ||||||
1324 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1324, __PRETTY_FUNCTION__)); | ||||||
1325 | if (Parent->LCVMap.size() < I) | ||||||
1326 | return nullptr; | ||||||
1327 | for (const auto &Pair : Parent->LCVMap) | ||||||
1328 | if (Pair.second.first == I) | ||||||
1329 | return Pair.first; | ||||||
1330 | return nullptr; | ||||||
1331 | } | ||||||
1332 | |||||||
1333 | void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, | ||||||
1334 | DeclRefExpr *PrivateCopy, unsigned Modifier) { | ||||||
1335 | D = getCanonicalDecl(D); | ||||||
1336 | if (A == OMPC_threadprivate) { | ||||||
1337 | DSAInfo &Data = Threadprivates[D]; | ||||||
1338 | Data.Attributes = A; | ||||||
1339 | Data.RefExpr.setPointer(E); | ||||||
1340 | Data.PrivateCopy = nullptr; | ||||||
1341 | Data.Modifier = Modifier; | ||||||
1342 | } else { | ||||||
1343 | DSAInfo &Data = getTopOfStack().SharingMap[D]; | ||||||
1344 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1347, __PRETTY_FUNCTION__)) | ||||||
1345 | (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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1347, __PRETTY_FUNCTION__)) | ||||||
1346 | (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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1347, __PRETTY_FUNCTION__)) | ||||||
1347 | (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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1347, __PRETTY_FUNCTION__)); | ||||||
1348 | Data.Modifier = Modifier; | ||||||
1349 | if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { | ||||||
1350 | Data.RefExpr.setInt(/*IntVal=*/true); | ||||||
1351 | return; | ||||||
1352 | } | ||||||
1353 | const bool IsLastprivate = | ||||||
1354 | A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; | ||||||
1355 | Data.Attributes = A; | ||||||
1356 | Data.RefExpr.setPointerAndInt(E, IsLastprivate); | ||||||
1357 | Data.PrivateCopy = PrivateCopy; | ||||||
1358 | if (PrivateCopy) { | ||||||
1359 | DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; | ||||||
1360 | Data.Modifier = Modifier; | ||||||
1361 | Data.Attributes = A; | ||||||
1362 | Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); | ||||||
1363 | Data.PrivateCopy = nullptr; | ||||||
1364 | } | ||||||
1365 | } | ||||||
1366 | } | ||||||
1367 | |||||||
1368 | /// Build a variable declaration for OpenMP loop iteration variable. | ||||||
1369 | static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, | ||||||
1370 | StringRef Name, const AttrVec *Attrs = nullptr, | ||||||
1371 | DeclRefExpr *OrigRef = nullptr) { | ||||||
1372 | DeclContext *DC = SemaRef.CurContext; | ||||||
1373 | IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); | ||||||
1374 | TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); | ||||||
1375 | auto *Decl = | ||||||
1376 | VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); | ||||||
1377 | if (Attrs) { | ||||||
1378 | for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); | ||||||
1379 | I != E; ++I) | ||||||
1380 | Decl->addAttr(*I); | ||||||
1381 | } | ||||||
1382 | Decl->setImplicit(); | ||||||
1383 | if (OrigRef) { | ||||||
1384 | Decl->addAttr( | ||||||
1385 | OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); | ||||||
1386 | } | ||||||
1387 | return Decl; | ||||||
1388 | } | ||||||
1389 | |||||||
1390 | static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, | ||||||
1391 | SourceLocation Loc, | ||||||
1392 | bool RefersToCapture = false) { | ||||||
1393 | D->setReferenced(); | ||||||
1394 | D->markUsed(S.Context); | ||||||
1395 | return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), | ||||||
1396 | SourceLocation(), D, RefersToCapture, Loc, Ty, | ||||||
1397 | VK_LValue); | ||||||
1398 | } | ||||||
1399 | |||||||
1400 | void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, | ||||||
1401 | BinaryOperatorKind BOK) { | ||||||
1402 | D = getCanonicalDecl(D); | ||||||
1403 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1403, __PRETTY_FUNCTION__)); | ||||||
1404 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1406, __PRETTY_FUNCTION__)) | ||||||
1405 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1406, __PRETTY_FUNCTION__)) | ||||||
1406 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1406, __PRETTY_FUNCTION__)); | ||||||
1407 | ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; | ||||||
1408 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1414, __PRETTY_FUNCTION__)) | ||||||
1409 | (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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1414, __PRETTY_FUNCTION__)) | ||||||
1410 | ((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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1414, __PRETTY_FUNCTION__)) | ||||||
1411 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1414, __PRETTY_FUNCTION__)) | ||||||
1412 | !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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1414, __PRETTY_FUNCTION__)) | ||||||
1413 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1414, __PRETTY_FUNCTION__)) | ||||||
1414 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1414, __PRETTY_FUNCTION__)); | ||||||
1415 | ReductionData.set(BOK, SR); | ||||||
1416 | Expr *&TaskgroupReductionRef = | ||||||
1417 | getTopOfStack().TaskgroupReductionRef; | ||||||
1418 | if (!TaskgroupReductionRef) { | ||||||
1419 | VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), | ||||||
1420 | SemaRef.Context.VoidPtrTy, ".task_red."); | ||||||
1421 | TaskgroupReductionRef = | ||||||
1422 | buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); | ||||||
1423 | } | ||||||
1424 | } | ||||||
1425 | |||||||
1426 | void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, | ||||||
1427 | const Expr *ReductionRef) { | ||||||
1428 | D = getCanonicalDecl(D); | ||||||
1429 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1429, __PRETTY_FUNCTION__)); | ||||||
1430 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1432, __PRETTY_FUNCTION__)) | ||||||
1431 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1432, __PRETTY_FUNCTION__)) | ||||||
1432 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1432, __PRETTY_FUNCTION__)); | ||||||
1433 | ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; | ||||||
1434 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1440, __PRETTY_FUNCTION__)) | ||||||
1435 | (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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1440, __PRETTY_FUNCTION__)) | ||||||
1436 | ((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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1440, __PRETTY_FUNCTION__)) | ||||||
1437 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1440, __PRETTY_FUNCTION__)) | ||||||
1438 | !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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1440, __PRETTY_FUNCTION__)) | ||||||
1439 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1440, __PRETTY_FUNCTION__)) | ||||||
1440 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1440, __PRETTY_FUNCTION__)); | ||||||
1441 | ReductionData.set(ReductionRef, SR); | ||||||
1442 | Expr *&TaskgroupReductionRef = | ||||||
1443 | getTopOfStack().TaskgroupReductionRef; | ||||||
1444 | if (!TaskgroupReductionRef) { | ||||||
1445 | VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), | ||||||
1446 | SemaRef.Context.VoidPtrTy, ".task_red."); | ||||||
1447 | TaskgroupReductionRef = | ||||||
1448 | buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); | ||||||
1449 | } | ||||||
1450 | } | ||||||
1451 | |||||||
1452 | const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( | ||||||
1453 | const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, | ||||||
1454 | Expr *&TaskgroupDescriptor) const { | ||||||
1455 | D = getCanonicalDecl(D); | ||||||
1456 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1456, __PRETTY_FUNCTION__)); | ||||||
1457 | for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { | ||||||
1458 | const DSAInfo &Data = I->SharingMap.lookup(D); | ||||||
1459 | if (Data.Attributes != OMPC_reduction || | ||||||
1460 | Data.Modifier != OMPC_REDUCTION_task) | ||||||
1461 | continue; | ||||||
1462 | const ReductionData &ReductionData = I->ReductionMap.lookup(D); | ||||||
1463 | if (!ReductionData.ReductionOp || | ||||||
1464 | ReductionData.ReductionOp.is<const Expr *>()) | ||||||
1465 | return DSAVarData(); | ||||||
1466 | SR = ReductionData.ReductionRange; | ||||||
1467 | BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); | ||||||
1468 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1470, __PRETTY_FUNCTION__)) | ||||||
1469 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1470, __PRETTY_FUNCTION__)) | ||||||
1470 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1470, __PRETTY_FUNCTION__)); | ||||||
1471 | TaskgroupDescriptor = I->TaskgroupReductionRef; | ||||||
1472 | return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), | ||||||
1473 | Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task); | ||||||
1474 | } | ||||||
1475 | return DSAVarData(); | ||||||
1476 | } | ||||||
1477 | |||||||
1478 | const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( | ||||||
1479 | const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, | ||||||
1480 | Expr *&TaskgroupDescriptor) const { | ||||||
1481 | D = getCanonicalDecl(D); | ||||||
1482 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1482, __PRETTY_FUNCTION__)); | ||||||
1483 | for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { | ||||||
1484 | const DSAInfo &Data = I->SharingMap.lookup(D); | ||||||
1485 | if (Data.Attributes != OMPC_reduction || | ||||||
1486 | Data.Modifier != OMPC_REDUCTION_task) | ||||||
1487 | continue; | ||||||
1488 | const ReductionData &ReductionData = I->ReductionMap.lookup(D); | ||||||
1489 | if (!ReductionData.ReductionOp || | ||||||
1490 | !ReductionData.ReductionOp.is<const Expr *>()) | ||||||
1491 | return DSAVarData(); | ||||||
1492 | SR = ReductionData.ReductionRange; | ||||||
1493 | ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); | ||||||
1494 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1496, __PRETTY_FUNCTION__)) | ||||||
1495 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1496, __PRETTY_FUNCTION__)) | ||||||
1496 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1496, __PRETTY_FUNCTION__)); | ||||||
1497 | TaskgroupDescriptor = I->TaskgroupReductionRef; | ||||||
1498 | return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), | ||||||
1499 | Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task); | ||||||
1500 | } | ||||||
1501 | return DSAVarData(); | ||||||
1502 | } | ||||||
1503 | |||||||
1504 | bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { | ||||||
1505 | D = D->getCanonicalDecl(); | ||||||
1506 | for (const_iterator E = end(); I != E; ++I) { | ||||||
1507 | if (isImplicitOrExplicitTaskingRegion(I->Directive) || | ||||||
1508 | isOpenMPTargetExecutionDirective(I->Directive)) { | ||||||
1509 | Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; | ||||||
1510 | Scope *CurScope = getCurScope(); | ||||||
1511 | while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) | ||||||
1512 | CurScope = CurScope->getParent(); | ||||||
1513 | return CurScope != TopScope; | ||||||
1514 | } | ||||||
1515 | } | ||||||
1516 | return false; | ||||||
1517 | } | ||||||
1518 | |||||||
1519 | static bool isConstNotMutableType(Sema &SemaRef, QualType Type, | ||||||
1520 | bool AcceptIfMutable = true, | ||||||
1521 | bool *IsClassType = nullptr) { | ||||||
1522 | ASTContext &Context = SemaRef.getASTContext(); | ||||||
1523 | Type = Type.getNonReferenceType().getCanonicalType(); | ||||||
1524 | bool IsConstant = Type.isConstant(Context); | ||||||
1525 | Type = Context.getBaseElementType(Type); | ||||||
1526 | const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus | ||||||
1527 | ? Type->getAsCXXRecordDecl() | ||||||
1528 | : nullptr; | ||||||
1529 | if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) | ||||||
1530 | if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) | ||||||
1531 | RD = CTD->getTemplatedDecl(); | ||||||
1532 | if (IsClassType) | ||||||
1533 | *IsClassType = RD; | ||||||
1534 | return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && | ||||||
1535 | RD->hasDefinition() && RD->hasMutableFields()); | ||||||
1536 | } | ||||||
1537 | |||||||
1538 | static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, | ||||||
1539 | QualType Type, OpenMPClauseKind CKind, | ||||||
1540 | SourceLocation ELoc, | ||||||
1541 | bool AcceptIfMutable = true, | ||||||
1542 | bool ListItemNotVar = false) { | ||||||
1543 | ASTContext &Context = SemaRef.getASTContext(); | ||||||
1544 | bool IsClassType; | ||||||
1545 | if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { | ||||||
1546 | unsigned Diag = ListItemNotVar | ||||||
1547 | ? diag::err_omp_const_list_item | ||||||
1548 | : IsClassType ? diag::err_omp_const_not_mutable_variable | ||||||
1549 | : diag::err_omp_const_variable; | ||||||
1550 | SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); | ||||||
1551 | if (!ListItemNotVar && D) { | ||||||
1552 | const VarDecl *VD = dyn_cast<VarDecl>(D); | ||||||
1553 | bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == | ||||||
1554 | VarDecl::DeclarationOnly; | ||||||
1555 | SemaRef.Diag(D->getLocation(), | ||||||
1556 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||
1557 | << D; | ||||||
1558 | } | ||||||
1559 | return true; | ||||||
1560 | } | ||||||
1561 | return false; | ||||||
1562 | } | ||||||
1563 | |||||||
1564 | const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, | ||||||
1565 | bool FromParent) { | ||||||
1566 | D = getCanonicalDecl(D); | ||||||
1567 | DSAVarData DVar; | ||||||
1568 | |||||||
1569 | auto *VD = dyn_cast<VarDecl>(D); | ||||||
1570 | auto TI = Threadprivates.find(D); | ||||||
1571 | if (TI != Threadprivates.end()) { | ||||||
1572 | DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); | ||||||
1573 | DVar.CKind = OMPC_threadprivate; | ||||||
1574 | DVar.Modifier = TI->getSecond().Modifier; | ||||||
1575 | return DVar; | ||||||
1576 | } | ||||||
1577 | if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { | ||||||
1578 | DVar.RefExpr = buildDeclRefExpr( | ||||||
1579 | SemaRef, VD, D->getType().getNonReferenceType(), | ||||||
1580 | VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); | ||||||
1581 | DVar.CKind = OMPC_threadprivate; | ||||||
1582 | addDSA(D, DVar.RefExpr, OMPC_threadprivate); | ||||||
1583 | return DVar; | ||||||
1584 | } | ||||||
1585 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||
1586 | // in a Construct, C/C++, predetermined, p.1] | ||||||
1587 | // Variables appearing in threadprivate directives are threadprivate. | ||||||
1588 | if ((VD && VD->getTLSKind() != VarDecl::TLS_None && | ||||||
1589 | !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && | ||||||
1590 | SemaRef.getLangOpts().OpenMPUseTLS && | ||||||
1591 | SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || | ||||||
1592 | (VD && VD->getStorageClass() == SC_Register && | ||||||
1593 | VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { | ||||||
1594 | DVar.RefExpr = buildDeclRefExpr( | ||||||
1595 | SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); | ||||||
1596 | DVar.CKind = OMPC_threadprivate; | ||||||
1597 | addDSA(D, DVar.RefExpr, OMPC_threadprivate); | ||||||
1598 | return DVar; | ||||||
1599 | } | ||||||
1600 | if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && | ||||||
1601 | VD->isLocalVarDeclOrParm() && !isStackEmpty() && | ||||||
1602 | !isLoopControlVariable(D).first) { | ||||||
1603 | const_iterator IterTarget = | ||||||
1604 | std::find_if(begin(), end(), [](const SharingMapTy &Data) { | ||||||
1605 | return isOpenMPTargetExecutionDirective(Data.Directive); | ||||||
1606 | }); | ||||||
1607 | if (IterTarget != end()) { | ||||||
1608 | const_iterator ParentIterTarget = IterTarget + 1; | ||||||
1609 | for (const_iterator Iter = begin(); | ||||||
1610 | Iter != ParentIterTarget; ++Iter) { | ||||||
1611 | if (isOpenMPLocal(VD, Iter)) { | ||||||
1612 | DVar.RefExpr = | ||||||
1613 | buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), | ||||||
1614 | D->getLocation()); | ||||||
1615 | DVar.CKind = OMPC_threadprivate; | ||||||
1616 | return DVar; | ||||||
1617 | } | ||||||
1618 | } | ||||||
1619 | if (!isClauseParsingMode() || IterTarget != begin()) { | ||||||
1620 | auto DSAIter = IterTarget->SharingMap.find(D); | ||||||
1621 | if (DSAIter != IterTarget->SharingMap.end() && | ||||||
1622 | isOpenMPPrivate(DSAIter->getSecond().Attributes)) { | ||||||
1623 | DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); | ||||||
1624 | DVar.CKind = OMPC_threadprivate; | ||||||
1625 | return DVar; | ||||||
1626 | } | ||||||
1627 | const_iterator End = end(); | ||||||
1628 | if (!SemaRef.isOpenMPCapturedByRef( | ||||||
1629 | D, std::distance(ParentIterTarget, End), | ||||||
1630 | /*OpenMPCaptureLevel=*/0)) { | ||||||
1631 | DVar.RefExpr = | ||||||
1632 | buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), | ||||||
1633 | IterTarget->ConstructLoc); | ||||||
1634 | DVar.CKind = OMPC_threadprivate; | ||||||
1635 | return DVar; | ||||||
1636 | } | ||||||
1637 | } | ||||||
1638 | } | ||||||
1639 | } | ||||||
1640 | |||||||
1641 | if (isStackEmpty()) | ||||||
1642 | // Not in OpenMP execution region and top scope was already checked. | ||||||
1643 | return DVar; | ||||||
1644 | |||||||
1645 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||
1646 | // in a Construct, C/C++, predetermined, p.4] | ||||||
1647 | // Static data members are shared. | ||||||
1648 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||
1649 | // in a Construct, C/C++, predetermined, p.7] | ||||||
1650 | // Variables with static storage duration that are declared in a scope | ||||||
1651 | // inside the construct are shared. | ||||||
1652 | if (VD && VD->isStaticDataMember()) { | ||||||
1653 | // Check for explicitly specified attributes. | ||||||
1654 | const_iterator I = begin(); | ||||||
1655 | const_iterator EndI = end(); | ||||||
1656 | if (FromParent && I != EndI) | ||||||
1657 | ++I; | ||||||
1658 | if (I != EndI) { | ||||||
1659 | auto It = I->SharingMap.find(D); | ||||||
1660 | if (It != I->SharingMap.end()) { | ||||||
1661 | const DSAInfo &Data = It->getSecond(); | ||||||
1662 | DVar.RefExpr = Data.RefExpr.getPointer(); | ||||||
1663 | DVar.PrivateCopy = Data.PrivateCopy; | ||||||
1664 | DVar.CKind = Data.Attributes; | ||||||
1665 | DVar.ImplicitDSALoc = I->DefaultAttrLoc; | ||||||
1666 | DVar.DKind = I->Directive; | ||||||
1667 | DVar.Modifier = Data.Modifier; | ||||||
1668 | return DVar; | ||||||
1669 | } | ||||||
1670 | } | ||||||
1671 | |||||||
1672 | DVar.CKind = OMPC_shared; | ||||||
1673 | return DVar; | ||||||
1674 | } | ||||||
1675 | |||||||
1676 | auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; | ||||||
1677 | // The predetermined shared attribute for const-qualified types having no | ||||||
1678 | // mutable members was removed after OpenMP 3.1. | ||||||
1679 | if (SemaRef.LangOpts.OpenMP <= 31) { | ||||||
1680 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||
1681 | // in a Construct, C/C++, predetermined, p.6] | ||||||
1682 | // Variables with const qualified type having no mutable member are | ||||||
1683 | // shared. | ||||||
1684 | if (isConstNotMutableType(SemaRef, D->getType())) { | ||||||
1685 | // Variables with const-qualified type having no mutable member may be | ||||||
1686 | // listed in a firstprivate clause, even if they are static data members. | ||||||
1687 | DSAVarData DVarTemp = hasInnermostDSA( | ||||||
1688 | D, | ||||||
1689 | [](OpenMPClauseKind C) { | ||||||
1690 | return C == OMPC_firstprivate || C == OMPC_shared; | ||||||
1691 | }, | ||||||
1692 | MatchesAlways, FromParent); | ||||||
1693 | if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) | ||||||
1694 | return DVarTemp; | ||||||
1695 | |||||||
1696 | DVar.CKind = OMPC_shared; | ||||||
1697 | return DVar; | ||||||
1698 | } | ||||||
1699 | } | ||||||
1700 | |||||||
1701 | // Explicitly specified attributes and local variables with predetermined | ||||||
1702 | // attributes. | ||||||
1703 | const_iterator I = begin(); | ||||||
1704 | const_iterator EndI = end(); | ||||||
1705 | if (FromParent && I != EndI) | ||||||
1706 | ++I; | ||||||
1707 | if (I == EndI) | ||||||
1708 | return DVar; | ||||||
1709 | auto It = I->SharingMap.find(D); | ||||||
1710 | if (It != I->SharingMap.end()) { | ||||||
1711 | const DSAInfo &Data = It->getSecond(); | ||||||
1712 | DVar.RefExpr = Data.RefExpr.getPointer(); | ||||||
1713 | DVar.PrivateCopy = Data.PrivateCopy; | ||||||
1714 | DVar.CKind = Data.Attributes; | ||||||
1715 | DVar.ImplicitDSALoc = I->DefaultAttrLoc; | ||||||
1716 | DVar.DKind = I->Directive; | ||||||
1717 | DVar.Modifier = Data.Modifier; | ||||||
1718 | } | ||||||
1719 | |||||||
1720 | return DVar; | ||||||
1721 | } | ||||||
1722 | |||||||
1723 | const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, | ||||||
1724 | bool FromParent) const { | ||||||
1725 | if (isStackEmpty()) { | ||||||
1726 | const_iterator I; | ||||||
1727 | return getDSA(I, D); | ||||||
1728 | } | ||||||
1729 | D = getCanonicalDecl(D); | ||||||
1730 | const_iterator StartI = begin(); | ||||||
1731 | const_iterator EndI = end(); | ||||||
1732 | if (FromParent && StartI != EndI) | ||||||
1733 | ++StartI; | ||||||
1734 | return getDSA(StartI, D); | ||||||
1735 | } | ||||||
1736 | |||||||
1737 | const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, | ||||||
1738 | unsigned Level) const { | ||||||
1739 | if (getStackSize() <= Level) | ||||||
1740 | return DSAVarData(); | ||||||
1741 | D = getCanonicalDecl(D); | ||||||
1742 | const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level); | ||||||
1743 | return getDSA(StartI, D); | ||||||
1744 | } | ||||||
1745 | |||||||
1746 | const DSAStackTy::DSAVarData | ||||||
1747 | DSAStackTy::hasDSA(ValueDecl *D, | ||||||
1748 | const llvm::function_ref<bool(OpenMPClauseKind)> CPred, | ||||||
1749 | const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, | ||||||
1750 | bool FromParent) const { | ||||||
1751 | if (isStackEmpty()) | ||||||
1752 | return {}; | ||||||
1753 | D = getCanonicalDecl(D); | ||||||
1754 | const_iterator I = begin(); | ||||||
1755 | const_iterator EndI = end(); | ||||||
1756 | if (FromParent && I != EndI) | ||||||
1757 | ++I; | ||||||
1758 | for (; I != EndI; ++I) { | ||||||
1759 | if (!DPred(I->Directive) && | ||||||
1760 | !isImplicitOrExplicitTaskingRegion(I->Directive)) | ||||||
1761 | continue; | ||||||
1762 | const_iterator NewI = I; | ||||||
1763 | DSAVarData DVar = getDSA(NewI, D); | ||||||
1764 | if (I == NewI && CPred(DVar.CKind)) | ||||||
1765 | return DVar; | ||||||
1766 | } | ||||||
1767 | return {}; | ||||||
1768 | } | ||||||
1769 | |||||||
1770 | const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( | ||||||
1771 | ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, | ||||||
1772 | const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, | ||||||
1773 | bool FromParent) const { | ||||||
1774 | if (isStackEmpty()) | ||||||
1775 | return {}; | ||||||
1776 | D = getCanonicalDecl(D); | ||||||
1777 | const_iterator StartI = begin(); | ||||||
1778 | const_iterator EndI = end(); | ||||||
1779 | if (FromParent && StartI != EndI) | ||||||
1780 | ++StartI; | ||||||
1781 | if (StartI == EndI || !DPred(StartI->Directive)) | ||||||
1782 | return {}; | ||||||
1783 | const_iterator NewI = StartI; | ||||||
1784 | DSAVarData DVar = getDSA(NewI, D); | ||||||
1785 | return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); | ||||||
1786 | } | ||||||
1787 | |||||||
1788 | bool DSAStackTy::hasExplicitDSA( | ||||||
1789 | const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, | ||||||
1790 | unsigned Level, bool NotLastprivate) const { | ||||||
1791 | if (getStackSize() <= Level) | ||||||
1792 | return false; | ||||||
1793 | D = getCanonicalDecl(D); | ||||||
1794 | const SharingMapTy &StackElem = getStackElemAtLevel(Level); | ||||||
1795 | auto I = StackElem.SharingMap.find(D); | ||||||
1796 | if (I != StackElem.SharingMap.end() && | ||||||
1797 | I->getSecond().RefExpr.getPointer() && | ||||||
1798 | CPred(I->getSecond().Attributes) && | ||||||
1799 | (!NotLastprivate || !I->getSecond().RefExpr.getInt())) | ||||||
1800 | return true; | ||||||
1801 | // Check predetermined rules for the loop control variables. | ||||||
1802 | auto LI = StackElem.LCVMap.find(D); | ||||||
1803 | if (LI != StackElem.LCVMap.end()) | ||||||
1804 | return CPred(OMPC_private); | ||||||
1805 | return false; | ||||||
1806 | } | ||||||
1807 | |||||||
1808 | bool DSAStackTy::hasExplicitDirective( | ||||||
1809 | const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, | ||||||
1810 | unsigned Level) const { | ||||||
1811 | if (getStackSize() <= Level) | ||||||
1812 | return false; | ||||||
1813 | const SharingMapTy &StackElem = getStackElemAtLevel(Level); | ||||||
1814 | return DPred(StackElem.Directive); | ||||||
1815 | } | ||||||
1816 | |||||||
1817 | bool DSAStackTy::hasDirective( | ||||||
1818 | const llvm::function_ref<bool(OpenMPDirectiveKind, | ||||||
1819 | const DeclarationNameInfo &, SourceLocation)> | ||||||
1820 | DPred, | ||||||
1821 | bool FromParent) const { | ||||||
1822 | // We look only in the enclosing region. | ||||||
1823 | size_t Skip = FromParent ? 2 : 1; | ||||||
1824 | for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); | ||||||
1825 | I != E; ++I) { | ||||||
1826 | if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) | ||||||
1827 | return true; | ||||||
1828 | } | ||||||
1829 | return false; | ||||||
1830 | } | ||||||
1831 | |||||||
1832 | void Sema::InitDataSharingAttributesStack() { | ||||||
1833 | VarDataSharingAttributesStack = new DSAStackTy(*this); | ||||||
1834 | } | ||||||
1835 | |||||||
1836 | #define DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ) static_cast<DSAStackTy *>(VarDataSharingAttributesStack) | ||||||
1837 | |||||||
1838 | void Sema::pushOpenMPFunctionRegion() { | ||||||
1839 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->pushFunction(); | ||||||
1840 | } | ||||||
1841 | |||||||
1842 | void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { | ||||||
1843 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->popFunction(OldFSI); | ||||||
1844 | } | ||||||
1845 | |||||||
1846 | static bool isOpenMPDeviceDelayedContext(Sema &S) { | ||||||
1847 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1848, __PRETTY_FUNCTION__)) | ||||||
1848 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1848, __PRETTY_FUNCTION__)); | ||||||
1849 | return !S.isInOpenMPTargetExecutionDirective() && | ||||||
1850 | !S.isInOpenMPDeclareTargetContext(); | ||||||
1851 | } | ||||||
1852 | |||||||
1853 | namespace { | ||||||
1854 | /// Status of the function emission on the host/device. | ||||||
1855 | enum class FunctionEmissionStatus { | ||||||
1856 | Emitted, | ||||||
1857 | Discarded, | ||||||
1858 | Unknown, | ||||||
1859 | }; | ||||||
1860 | } // anonymous namespace | ||||||
1861 | |||||||
1862 | Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, | ||||||
1863 | unsigned DiagID) { | ||||||
1864 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1865, __PRETTY_FUNCTION__)) | ||||||
1865 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1865, __PRETTY_FUNCTION__)); | ||||||
1866 | |||||||
1867 | FunctionDecl *FD = getCurFunctionDecl(); | ||||||
1868 | DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; | ||||||
1869 | if (FD) { | ||||||
1870 | FunctionEmissionStatus FES = getEmissionStatus(FD); | ||||||
1871 | switch (FES) { | ||||||
1872 | case FunctionEmissionStatus::Emitted: | ||||||
1873 | Kind = DeviceDiagBuilder::K_Immediate; | ||||||
1874 | break; | ||||||
1875 | case FunctionEmissionStatus::Unknown: | ||||||
1876 | Kind = isOpenMPDeviceDelayedContext(*this) | ||||||
1877 | ? DeviceDiagBuilder::K_Deferred | ||||||
1878 | : DeviceDiagBuilder::K_Immediate; | ||||||
1879 | break; | ||||||
1880 | case FunctionEmissionStatus::TemplateDiscarded: | ||||||
1881 | case FunctionEmissionStatus::OMPDiscarded: | ||||||
1882 | Kind = DeviceDiagBuilder::K_Nop; | ||||||
1883 | break; | ||||||
1884 | case FunctionEmissionStatus::CUDADiscarded: | ||||||
1885 | llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation")::llvm::llvm_unreachable_internal("CUDADiscarded unexpected in OpenMP device compilation" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1885); | ||||||
1886 | break; | ||||||
1887 | } | ||||||
1888 | } | ||||||
1889 | |||||||
1890 | return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); | ||||||
1891 | } | ||||||
1892 | |||||||
1893 | Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, | ||||||
1894 | unsigned DiagID) { | ||||||
1895 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1896, __PRETTY_FUNCTION__)) | ||||||
1896 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1896, __PRETTY_FUNCTION__)); | ||||||
1897 | FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); | ||||||
1898 | DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; | ||||||
1899 | switch (FES) { | ||||||
1900 | case FunctionEmissionStatus::Emitted: | ||||||
1901 | Kind = DeviceDiagBuilder::K_Immediate; | ||||||
1902 | break; | ||||||
1903 | case FunctionEmissionStatus::Unknown: | ||||||
1904 | Kind = DeviceDiagBuilder::K_Deferred; | ||||||
1905 | break; | ||||||
1906 | case FunctionEmissionStatus::TemplateDiscarded: | ||||||
1907 | case FunctionEmissionStatus::OMPDiscarded: | ||||||
1908 | case FunctionEmissionStatus::CUDADiscarded: | ||||||
1909 | Kind = DeviceDiagBuilder::K_Nop; | ||||||
1910 | break; | ||||||
1911 | } | ||||||
1912 | |||||||
1913 | return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); | ||||||
1914 | } | ||||||
1915 | |||||||
1916 | static OpenMPDefaultmapClauseKind | ||||||
1917 | getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) { | ||||||
1918 | if (LO.OpenMP <= 45) { | ||||||
1919 | if (VD->getType().getNonReferenceType()->isScalarType()) | ||||||
1920 | return OMPC_DEFAULTMAP_scalar; | ||||||
1921 | return OMPC_DEFAULTMAP_aggregate; | ||||||
1922 | } | ||||||
1923 | if (VD->getType().getNonReferenceType()->isAnyPointerType()) | ||||||
1924 | return OMPC_DEFAULTMAP_pointer; | ||||||
1925 | if (VD->getType().getNonReferenceType()->isScalarType()) | ||||||
1926 | return OMPC_DEFAULTMAP_scalar; | ||||||
1927 | return OMPC_DEFAULTMAP_aggregate; | ||||||
1928 | } | ||||||
1929 | |||||||
1930 | bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, | ||||||
1931 | unsigned OpenMPCaptureLevel) const { | ||||||
1932 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1932, __PRETTY_FUNCTION__)); | ||||||
1933 | |||||||
1934 | ASTContext &Ctx = getASTContext(); | ||||||
1935 | bool IsByRef = true; | ||||||
1936 | |||||||
1937 | // Find the directive that is associated with the provided scope. | ||||||
1938 | D = cast<ValueDecl>(D->getCanonicalDecl()); | ||||||
1939 | QualType Ty = D->getType(); | ||||||
1940 | |||||||
1941 | bool IsVariableUsedInMapClause = false; | ||||||
1942 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { | ||||||
1943 | // This table summarizes how a given variable should be passed to the device | ||||||
1944 | // given its type and the clauses where it appears. This table is based on | ||||||
1945 | // the description in OpenMP 4.5 [2.10.4, target Construct] and | ||||||
1946 | // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. | ||||||
1947 | // | ||||||
1948 | // ========================================================================= | ||||||
1949 | // | type | defaultmap | pvt | first | is_device_ptr | map | res. | | ||||||
1950 | // | |(tofrom:scalar)| | pvt | | | | | ||||||
1951 | // ========================================================================= | ||||||
1952 | // | scl | | | | - | | bycopy| | ||||||
1953 | // | scl | | - | x | - | - | bycopy| | ||||||
1954 | // | scl | | x | - | - | - | null | | ||||||
1955 | // | scl | x | | | - | | byref | | ||||||
1956 | // | scl | x | - | x | - | - | bycopy| | ||||||
1957 | // | scl | x | x | - | - | - | null | | ||||||
1958 | // | scl | | - | - | - | x | byref | | ||||||
1959 | // | scl | x | - | - | - | x | byref | | ||||||
1960 | // | ||||||
1961 | // | agg | n.a. | | | - | | byref | | ||||||
1962 | // | agg | n.a. | - | x | - | - | byref | | ||||||
1963 | // | agg | n.a. | x | - | - | - | null | | ||||||
1964 | // | agg | n.a. | - | - | - | x | byref | | ||||||
1965 | // | agg | n.a. | - | - | - | x[] | byref | | ||||||
1966 | // | ||||||
1967 | // | ptr | n.a. | | | - | | bycopy| | ||||||
1968 | // | ptr | n.a. | - | x | - | - | bycopy| | ||||||
1969 | // | ptr | n.a. | x | - | - | - | null | | ||||||
1970 | // | ptr | n.a. | - | - | - | x | byref | | ||||||
1971 | // | ptr | n.a. | - | - | - | x[] | bycopy| | ||||||
1972 | // | ptr | n.a. | - | - | x | | bycopy| | ||||||
1973 | // | ptr | n.a. | - | - | x | x | bycopy| | ||||||
1974 | // | ptr | n.a. | - | - | x | x[] | bycopy| | ||||||
1975 | // ========================================================================= | ||||||
1976 | // Legend: | ||||||
1977 | // scl - scalar | ||||||
1978 | // ptr - pointer | ||||||
1979 | // agg - aggregate | ||||||
1980 | // x - applies | ||||||
1981 | // - - invalid in this combination | ||||||
1982 | // [] - mapped with an array section | ||||||
1983 | // byref - should be mapped by reference | ||||||
1984 | // byval - should be mapped by value | ||||||
1985 | // null - initialize a local variable to null on the device | ||||||
1986 | // | ||||||
1987 | // Observations: | ||||||
1988 | // - All scalar declarations that show up in a map clause have to be passed | ||||||
1989 | // by reference, because they may have been mapped in the enclosing data | ||||||
1990 | // environment. | ||||||
1991 | // - If the scalar value does not fit the size of uintptr, it has to be | ||||||
1992 | // passed by reference, regardless the result in the table above. | ||||||
1993 | // - For pointers mapped by value that have either an implicit map or an | ||||||
1994 | // array section, the runtime library may pass the NULL value to the | ||||||
1995 | // device instead of the value passed to it by the compiler. | ||||||
1996 | |||||||
1997 | if (Ty->isReferenceType()) | ||||||
1998 | Ty = Ty->castAs<ReferenceType>()->getPointeeType(); | ||||||
1999 | |||||||
2000 | // Locate map clauses and see if the variable being captured is referred to | ||||||
2001 | // in any of those clauses. Here we only care about variables, not fields, | ||||||
2002 | // because fields are part of aggregates. | ||||||
2003 | bool IsVariableAssociatedWithSection = false; | ||||||
2004 | |||||||
2005 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->checkMappableExprComponentListsForDeclAtLevel( | ||||||
2006 | D, Level, | ||||||
2007 | [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( | ||||||
2008 | OMPClauseMappableExprCommon::MappableExprComponentListRef | ||||||
2009 | MapExprComponents, | ||||||
2010 | OpenMPClauseKind WhereFoundClauseKind) { | ||||||
2011 | // Only the map clause information influences how a variable is | ||||||
2012 | // captured. E.g. is_device_ptr does not require changing the default | ||||||
2013 | // behavior. | ||||||
2014 | if (WhereFoundClauseKind != OMPC_map) | ||||||
2015 | return false; | ||||||
2016 | |||||||
2017 | auto EI = MapExprComponents.rbegin(); | ||||||
2018 | auto EE = MapExprComponents.rend(); | ||||||
2019 | |||||||
2020 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2020, __PRETTY_FUNCTION__)); | ||||||
2021 | |||||||
2022 | if (isa<DeclRefExpr>(EI->getAssociatedExpression())) | ||||||
2023 | IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; | ||||||
2024 | |||||||
2025 | ++EI; | ||||||
2026 | if (EI == EE) | ||||||
2027 | return false; | ||||||
2028 | |||||||
2029 | if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || | ||||||
2030 | isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || | ||||||
2031 | isa<MemberExpr>(EI->getAssociatedExpression()) || | ||||||
2032 | isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) { | ||||||
2033 | IsVariableAssociatedWithSection = true; | ||||||
2034 | // There is nothing more we need to know about this variable. | ||||||
2035 | return true; | ||||||
2036 | } | ||||||
2037 | |||||||
2038 | // Keep looking for more map info. | ||||||
2039 | return false; | ||||||
2040 | }); | ||||||
2041 | |||||||
2042 | if (IsVariableUsedInMapClause) { | ||||||
2043 | // If variable is identified in a map clause it is always captured by | ||||||
2044 | // reference except if it is a pointer that is dereferenced somehow. | ||||||
2045 | IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); | ||||||
2046 | } else { | ||||||
2047 | // By default, all the data that has a scalar type is mapped by copy | ||||||
2048 | // (except for reduction variables). | ||||||
2049 | // Defaultmap scalar is mutual exclusive to defaultmap pointer | ||||||
2050 | IsByRef = | ||||||
2051 | (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isForceCaptureByReferenceInTargetExecutable() && | ||||||
2052 | !Ty->isAnyPointerType()) || | ||||||
2053 | !Ty->isScalarType() || | ||||||
2054 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isDefaultmapCapturedByRef( | ||||||
2055 | Level, getVariableCategoryFromDecl(LangOpts, D)) || | ||||||
2056 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDSA( | ||||||
2057 | D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); | ||||||
2058 | } | ||||||
2059 | } | ||||||
2060 | |||||||
2061 | if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { | ||||||
2062 | IsByRef = | ||||||
2063 | ((IsVariableUsedInMapClause && | ||||||
2064 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCaptureRegion(Level, OpenMPCaptureLevel) == | ||||||
2065 | OMPD_target) || | ||||||
2066 | !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDSA( | ||||||
2067 | D, | ||||||
2068 | [](OpenMPClauseKind K) -> bool { | ||||||
2069 | return K == OMPC_firstprivate; | ||||||
2070 | }, | ||||||
2071 | Level, /*NotLastprivate=*/true) || | ||||||
2072 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isUsesAllocatorsDecl(Level, D))) && | ||||||
2073 | // If the variable is artificial and must be captured by value - try to | ||||||
2074 | // capture by value. | ||||||
2075 | !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && | ||||||
2076 | !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) && | ||||||
2077 | // If the variable is implicitly firstprivate and scalar - capture by | ||||||
2078 | // copy | ||||||
2079 | !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() == DSA_firstprivate && | ||||||
2080 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDSA( | ||||||
2081 | D, [](OpenMPClauseKind K) { return K != OMPC_unknown; }, Level) && | ||||||
2082 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isLoopControlVariable(D, Level).first); | ||||||
2083 | } | ||||||
2084 | |||||||
2085 | // When passing data by copy, we need to make sure it fits the uintptr size | ||||||
2086 | // and alignment, because the runtime library only deals with uintptr types. | ||||||
2087 | // If it does not fit the uintptr size, we need to pass the data by reference | ||||||
2088 | // instead. | ||||||
2089 | if (!IsByRef && | ||||||
2090 | (Ctx.getTypeSizeInChars(Ty) > | ||||||
2091 | Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || | ||||||
2092 | Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { | ||||||
2093 | IsByRef = true; | ||||||
2094 | } | ||||||
2095 | |||||||
2096 | return IsByRef; | ||||||
2097 | } | ||||||
2098 | |||||||
2099 | unsigned Sema::getOpenMPNestingLevel() const { | ||||||
2100 | assert(getLangOpts().OpenMP)((getLangOpts().OpenMP) ? static_cast<void> (0) : __assert_fail ("getLangOpts().OpenMP", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2100, __PRETTY_FUNCTION__)); | ||||||
2101 | return DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getNestingLevel(); | ||||||
2102 | } | ||||||
2103 | |||||||
2104 | bool Sema::isInOpenMPTargetExecutionDirective() const { | ||||||
2105 | return (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()) && | ||||||
2106 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isClauseParsingMode()) || | ||||||
2107 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasDirective( | ||||||
2108 | [](OpenMPDirectiveKind K, const DeclarationNameInfo &, | ||||||
2109 | SourceLocation) -> bool { | ||||||
2110 | return isOpenMPTargetExecutionDirective(K); | ||||||
2111 | }, | ||||||
2112 | false); | ||||||
2113 | } | ||||||
2114 | |||||||
2115 | VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, | ||||||
2116 | unsigned StopAt) { | ||||||
2117 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2117, __PRETTY_FUNCTION__)); | ||||||
2118 | D = getCanonicalDecl(D); | ||||||
2119 | |||||||
2120 | auto *VD = dyn_cast<VarDecl>(D); | ||||||
2121 | // Do not capture constexpr variables. | ||||||
2122 | if (VD
| ||||||
2123 | return nullptr; | ||||||
2124 | |||||||
2125 | // If we want to determine whether the variable should be captured from the | ||||||
2126 | // perspective of the current capturing scope, and we've already left all the | ||||||
2127 | // capturing scopes of the top directive on the stack, check from the | ||||||
2128 | // perspective of its parent directive (if any) instead. | ||||||
2129 | DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( | ||||||
2130 | *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), CheckScopeInfo
)->isBodyComplete()); | ||||||
2131 | |||||||
2132 | // If we are attempting to capture a global variable in a directive with | ||||||
2133 | // 'target' we return true so that this global is also mapped to the device. | ||||||
2134 | // | ||||||
2135 | if (VD
| ||||||
2136 | (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { | ||||||
2137 | if (isInOpenMPDeclareTargetContext()) { | ||||||
2138 | // Try to mark variable as declare target if it is used in capturing | ||||||
2139 | // regions. | ||||||
2140 | if (LangOpts.OpenMP <= 45 && | ||||||
2141 | !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) | ||||||
2142 | checkDeclIsAllowedInOpenMPTarget(nullptr, VD); | ||||||
2143 | return nullptr; | ||||||
2144 | } else if (isInOpenMPTargetExecutionDirective()) { | ||||||
2145 | // If the declaration is enclosed in a 'declare target' directive, | ||||||
2146 | // then it should not be captured. | ||||||
2147 | // | ||||||
2148 | if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) | ||||||
2149 | return nullptr; | ||||||
2150 | CapturedRegionScopeInfo *CSI = nullptr; | ||||||
2151 | for (FunctionScopeInfo *FSI : llvm::drop_begin( | ||||||
2152 | llvm::reverse(FunctionScopes), | ||||||
2153 | CheckScopeInfo
| ||||||
2154 | if (!isa<CapturingScopeInfo>(FSI)) | ||||||
2155 | return nullptr; | ||||||
2156 | if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) | ||||||
2157 | if (RSI->CapRegionKind == CR_OpenMP) { | ||||||
2158 | CSI = RSI; | ||||||
2159 | break; | ||||||
2160 | } | ||||||
2161 | } | ||||||
2162 | SmallVector<OpenMPDirectiveKind, 4> Regions; | ||||||
2163 | getOpenMPCaptureRegions(Regions, | ||||||
2164 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDirective(CSI->OpenMPLevel)); | ||||||
| |||||||
2165 | if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task) | ||||||
2166 | return VD; | ||||||
2167 | } | ||||||
2168 | } | ||||||
2169 | |||||||
2170 | if (CheckScopeInfo) { | ||||||
2171 | bool OpenMPFound = false; | ||||||
2172 | for (unsigned I = StopAt + 1; I > 0; --I) { | ||||||
2173 | FunctionScopeInfo *FSI = FunctionScopes[I - 1]; | ||||||
2174 | if(!isa<CapturingScopeInfo>(FSI)) | ||||||
2175 | return nullptr; | ||||||
2176 | if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) | ||||||
2177 | if (RSI->CapRegionKind == CR_OpenMP) { | ||||||
2178 | OpenMPFound = true; | ||||||
2179 | break; | ||||||
2180 | } | ||||||
2181 | } | ||||||
2182 | if (!OpenMPFound) | ||||||
2183 | return nullptr; | ||||||
2184 | } | ||||||
2185 | |||||||
2186 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() != OMPD_unknown && | ||||||
2187 | (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isClauseParsingMode() || | ||||||
2188 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentDirective() != OMPD_unknown)) { | ||||||
2189 | auto &&Info = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isLoopControlVariable(D); | ||||||
2190 | if (Info.first || | ||||||
2191 | (VD && VD->hasLocalStorage() && | ||||||
2192 | isImplicitOrExplicitTaskingRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective())) || | ||||||
2193 | (VD && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isForceVarCapturing())) | ||||||
2194 | return VD ? VD : Info.second; | ||||||
2195 | DSAStackTy::DSAVarData DVarTop = | ||||||
2196 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isClauseParsingMode()); | ||||||
2197 | if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind)) | ||||||
2198 | return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl()); | ||||||
2199 | // Threadprivate variables must not be captured. | ||||||
2200 | if (isOpenMPThreadPrivate(DVarTop.CKind)) | ||||||
2201 | return nullptr; | ||||||
2202 | // The variable is not private or it is the variable in the directive with | ||||||
2203 | // default(none) clause and not used in any clause. | ||||||
2204 | DSAStackTy::DSAVarData DVarPrivate = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasDSA( | ||||||
2205 | D, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, | ||||||
2206 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isClauseParsingMode()); | ||||||
2207 | // Global shared must not be captured. | ||||||
2208 | if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown && | ||||||
2209 | ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() != DSA_none && | ||||||
2210 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() != DSA_firstprivate) || | ||||||
2211 | DVarTop.CKind == OMPC_shared)) | ||||||
2212 | return nullptr; | ||||||
2213 | if (DVarPrivate.CKind != OMPC_unknown || | ||||||
2214 | (VD && (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() == DSA_none || | ||||||
2215 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() == DSA_firstprivate))) | ||||||
2216 | return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); | ||||||
2217 | } | ||||||
2218 | return nullptr; | ||||||
2219 | } | ||||||
2220 | |||||||
2221 | void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, | ||||||
2222 | unsigned Level) const { | ||||||
2223 | FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDirective(Level)); | ||||||
2224 | } | ||||||
2225 | |||||||
2226 | void Sema::startOpenMPLoop() { | ||||||
2227 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2227, __PRETTY_FUNCTION__)); | ||||||
2228 | if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective())) | ||||||
2229 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->loopInit(); | ||||||
2230 | } | ||||||
2231 | |||||||
2232 | void Sema::startOpenMPCXXRangeFor() { | ||||||
2233 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2233, __PRETTY_FUNCTION__)); | ||||||
2234 | if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective())) { | ||||||
2235 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->resetPossibleLoopCounter(); | ||||||
2236 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->loopStart(); | ||||||
2237 | } | ||||||
2238 | } | ||||||
2239 | |||||||
2240 | OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level, | ||||||
2241 | unsigned CapLevel) const { | ||||||
2242 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2242, __PRETTY_FUNCTION__)); | ||||||
2243 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDirective( | ||||||
2244 | [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); }, | ||||||
2245 | Level)) { | ||||||
2246 | bool IsTriviallyCopyable = | ||||||
2247 | D->getType().getNonReferenceType().isTriviallyCopyableType(Context) && | ||||||
2248 | !D->getType() | ||||||
2249 | .getNonReferenceType() | ||||||
2250 | .getCanonicalType() | ||||||
2251 | ->getAsCXXRecordDecl(); | ||||||
2252 | OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDirective(Level); | ||||||
2253 | SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; | ||||||
2254 | getOpenMPCaptureRegions(CaptureRegions, DKind); | ||||||
2255 | if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) && | ||||||
2256 | (IsTriviallyCopyable || | ||||||
2257 | !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) { | ||||||
2258 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDSA( | ||||||
2259 | D, [](OpenMPClauseKind K) { return K == OMPC_firstprivate; }, | ||||||
2260 | Level, /*NotLastprivate=*/true)) | ||||||
2261 | return OMPC_firstprivate; | ||||||
2262 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getImplicitDSA(D, Level); | ||||||
2263 | if (DVar.CKind != OMPC_shared && | ||||||
2264 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isLoopControlVariable(D, Level).first && !DVar.RefExpr) { | ||||||
2265 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addImplicitTaskFirstprivate(Level, D); | ||||||
2266 | return OMPC_firstprivate; | ||||||
2267 | } | ||||||
2268 | } | ||||||
2269 | } | ||||||
2270 | if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective())) { | ||||||
2271 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getAssociatedLoops() > 0 && | ||||||
2272 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isLoopStarted()) { | ||||||
2273 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->resetPossibleLoopCounter(D); | ||||||
2274 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->loopStart(); | ||||||
2275 | return OMPC_private; | ||||||
2276 | } | ||||||
2277 | if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getPossiblyLoopCunter() == D->getCanonicalDecl() || | ||||||
2278 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isLoopControlVariable(D).first) && | ||||||
2279 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDSA( | ||||||
2280 | D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && | ||||||
2281 | !isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective())) | ||||||
2282 | return OMPC_private; | ||||||
2283 | } | ||||||
2284 | if (const auto *VD = dyn_cast<VarDecl>(D)) { | ||||||
2285 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isThreadPrivate(const_cast<VarDecl *>(VD)) && | ||||||
2286 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isForceVarCapturing() && | ||||||
2287 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDSA( | ||||||
2288 | D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) | ||||||
2289 | return OMPC_private; | ||||||
2290 | } | ||||||
2291 | // User-defined allocators are private since they must be defined in the | ||||||
2292 | // context of target region. | ||||||
2293 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) && | ||||||
2294 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isUsesAllocatorsDecl(Level, D).getValueOr( | ||||||
2295 | DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == | ||||||
2296 | DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator) | ||||||
2297 | return OMPC_private; | ||||||
2298 | return (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDSA( | ||||||
2299 | D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || | ||||||
2300 | (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isClauseParsingMode() && | ||||||
2301 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getClauseParsingMode() == OMPC_private) || | ||||||
2302 | // Consider taskgroup reduction descriptor variable a private | ||||||
2303 | // to avoid possible capture in the region. | ||||||
2304 | (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDirective( | ||||||
2305 | [](OpenMPDirectiveKind K) { | ||||||
2306 | return K == OMPD_taskgroup || | ||||||
2307 | ((isOpenMPParallelDirective(K) || | ||||||
2308 | isOpenMPWorksharingDirective(K)) && | ||||||
2309 | !isOpenMPSimdDirective(K)); | ||||||
2310 | }, | ||||||
2311 | Level) && | ||||||
2312 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isTaskgroupReductionRef(D, Level))) | ||||||
2313 | ? OMPC_private | ||||||
2314 | : OMPC_unknown; | ||||||
2315 | } | ||||||
2316 | |||||||
2317 | void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, | ||||||
2318 | unsigned Level) { | ||||||
2319 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2319, __PRETTY_FUNCTION__)); | ||||||
2320 | D = getCanonicalDecl(D); | ||||||
2321 | OpenMPClauseKind OMPC = OMPC_unknown; | ||||||
2322 | for (unsigned I = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getNestingLevel() + 1; I > Level; --I) { | ||||||
2323 | const unsigned NewLevel = I - 1; | ||||||
2324 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDSA(D, | ||||||
2325 | [&OMPC](const OpenMPClauseKind K) { | ||||||
2326 | if (isOpenMPPrivate(K)) { | ||||||
2327 | OMPC = K; | ||||||
2328 | return true; | ||||||
2329 | } | ||||||
2330 | return false; | ||||||
2331 | }, | ||||||
2332 | NewLevel)) | ||||||
2333 | break; | ||||||
2334 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->checkMappableExprComponentListsForDeclAtLevel( | ||||||
2335 | D, NewLevel, | ||||||
2336 | [](OMPClauseMappableExprCommon::MappableExprComponentListRef, | ||||||
2337 | OpenMPClauseKind) { return true; })) { | ||||||
2338 | OMPC = OMPC_map; | ||||||
2339 | break; | ||||||
2340 | } | ||||||
2341 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDirective(isOpenMPTargetExecutionDirective, | ||||||
2342 | NewLevel)) { | ||||||
2343 | OMPC = OMPC_map; | ||||||
2344 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->mustBeFirstprivateAtLevel( | ||||||
2345 | NewLevel, getVariableCategoryFromDecl(LangOpts, D))) | ||||||
2346 | OMPC = OMPC_firstprivate; | ||||||
2347 | break; | ||||||
2348 | } | ||||||
2349 | } | ||||||
2350 | if (OMPC != OMPC_unknown) | ||||||
2351 | FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC))); | ||||||
2352 | } | ||||||
2353 | |||||||
2354 | bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, | ||||||
2355 | unsigned CaptureLevel) const { | ||||||
2356 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2356, __PRETTY_FUNCTION__)); | ||||||
2357 | // Return true if the current level is no longer enclosed in a target region. | ||||||
2358 | |||||||
2359 | SmallVector<OpenMPDirectiveKind, 4> Regions; | ||||||
2360 | getOpenMPCaptureRegions(Regions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDirective(Level)); | ||||||
2361 | const auto *VD = dyn_cast<VarDecl>(D); | ||||||
2362 | return VD && !VD->hasLocalStorage() && | ||||||
2363 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDirective(isOpenMPTargetExecutionDirective, | ||||||
2364 | Level) && | ||||||
2365 | Regions[CaptureLevel] != OMPD_task; | ||||||
2366 | } | ||||||
2367 | |||||||
2368 | bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, | ||||||
2369 | unsigned CaptureLevel) const { | ||||||
2370 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2370, __PRETTY_FUNCTION__)); | ||||||
2371 | // Return true if the current level is no longer enclosed in a target region. | ||||||
2372 | |||||||
2373 | if (const auto *VD = dyn_cast<VarDecl>(D)) { | ||||||
2374 | if (!VD->hasLocalStorage()) { | ||||||
2375 | DSAStackTy::DSAVarData TopDVar = | ||||||
2376 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); | ||||||
2377 | unsigned NumLevels = | ||||||
2378 | getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDirective(Level)); | ||||||
2379 | if (Level == 0) | ||||||
2380 | return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared; | ||||||
2381 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getImplicitDSA(D, Level - 1); | ||||||
2382 | return DVar.CKind != OMPC_shared || | ||||||
2383 | isOpenMPGlobalCapturedDecl( | ||||||
2384 | D, Level - 1, | ||||||
2385 | getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDirective(Level - 1)) - 1); | ||||||
2386 | } | ||||||
2387 | } | ||||||
2388 | return true; | ||||||
2389 | } | ||||||
2390 | |||||||
2391 | void Sema::DestroyDataSharingAttributesStack() { delete DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ); } | ||||||
2392 | |||||||
2393 | void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, | ||||||
2394 | OMPTraitInfo &TI) { | ||||||
2395 | if (!OMPDeclareVariantScopes.empty()) { | ||||||
2396 | Diag(Loc, diag::warn_nested_declare_variant); | ||||||
2397 | return; | ||||||
2398 | } | ||||||
2399 | OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI)); | ||||||
2400 | } | ||||||
2401 | |||||||
2402 | void Sema::ActOnOpenMPEndDeclareVariant() { | ||||||
2403 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2404, __PRETTY_FUNCTION__)) | ||||||
2404 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2404, __PRETTY_FUNCTION__)); | ||||||
2405 | |||||||
2406 | OMPDeclareVariantScopes.pop_back(); | ||||||
2407 | } | ||||||
2408 | |||||||
2409 | void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, | ||||||
2410 | const FunctionDecl *Callee, | ||||||
2411 | SourceLocation Loc) { | ||||||
2412 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2412, __PRETTY_FUNCTION__)); | ||||||
2413 | Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = | ||||||
2414 | OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl()); | ||||||
2415 | // Ignore host functions during device analyzis. | ||||||
2416 | if (LangOpts.OpenMPIsDevice && DevTy && | ||||||
2417 | *DevTy == OMPDeclareTargetDeclAttr::DT_Host) | ||||||
2418 | return; | ||||||
2419 | // Ignore nohost functions during host analyzis. | ||||||
2420 | if (!LangOpts.OpenMPIsDevice && DevTy && | ||||||
2421 | *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) | ||||||
2422 | return; | ||||||
2423 | const FunctionDecl *FD = Callee->getMostRecentDecl(); | ||||||
2424 | DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD); | ||||||
2425 | if (LangOpts.OpenMPIsDevice && DevTy && | ||||||
2426 | *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { | ||||||
2427 | // Diagnose host function called during device codegen. | ||||||
2428 | StringRef HostDevTy = | ||||||
2429 | getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host); | ||||||
2430 | Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; | ||||||
2431 | Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), | ||||||
2432 | diag::note_omp_marked_device_type_here) | ||||||
2433 | << HostDevTy; | ||||||
2434 | return; | ||||||
2435 | } | ||||||
2436 | if (!LangOpts.OpenMPIsDevice && DevTy && | ||||||
2437 | *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { | ||||||
2438 | // Diagnose nohost function called during host codegen. | ||||||
2439 | StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( | ||||||
2440 | OMPC_device_type, OMPC_DEVICE_TYPE_nohost); | ||||||
2441 | Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; | ||||||
2442 | Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), | ||||||
2443 | diag::note_omp_marked_device_type_here) | ||||||
2444 | << NoHostDevTy; | ||||||
2445 | } | ||||||
2446 | } | ||||||
2447 | |||||||
2448 | void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, | ||||||
2449 | const DeclarationNameInfo &DirName, | ||||||
2450 | Scope *CurScope, SourceLocation Loc) { | ||||||
2451 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->push(DKind, DirName, CurScope, Loc); | ||||||
2452 | PushExpressionEvaluationContext( | ||||||
2453 | ExpressionEvaluationContext::PotentiallyEvaluated); | ||||||
2454 | } | ||||||
2455 | |||||||
2456 | void Sema::StartOpenMPClause(OpenMPClauseKind K) { | ||||||
2457 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setClauseParsingMode(K); | ||||||
2458 | } | ||||||
2459 | |||||||
2460 | void Sema::EndOpenMPClause() { | ||||||
2461 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setClauseParsingMode(/*K=*/OMPC_unknown); | ||||||
2462 | } | ||||||
2463 | |||||||
2464 | static std::pair<ValueDecl *, bool> | ||||||
2465 | getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, | ||||||
2466 | SourceRange &ERange, bool AllowArraySection = false); | ||||||
2467 | |||||||
2468 | /// Check consistency of the reduction clauses. | ||||||
2469 | static void checkReductionClauses(Sema &S, DSAStackTy *Stack, | ||||||
2470 | ArrayRef<OMPClause *> Clauses) { | ||||||
2471 | bool InscanFound = false; | ||||||
2472 | SourceLocation InscanLoc; | ||||||
2473 | // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions. | ||||||
2474 | // A reduction clause without the inscan reduction-modifier may not appear on | ||||||
2475 | // a construct on which a reduction clause with the inscan reduction-modifier | ||||||
2476 | // appears. | ||||||
2477 | for (OMPClause *C : Clauses) { | ||||||
2478 | if (C->getClauseKind() != OMPC_reduction) | ||||||
2479 | continue; | ||||||
2480 | auto *RC = cast<OMPReductionClause>(C); | ||||||
2481 | if (RC->getModifier() == OMPC_REDUCTION_inscan) { | ||||||
2482 | InscanFound = true; | ||||||
2483 | InscanLoc = RC->getModifierLoc(); | ||||||
2484 | continue; | ||||||
2485 | } | ||||||
2486 | if (RC->getModifier() == OMPC_REDUCTION_task) { | ||||||
2487 | // OpenMP 5.0, 2.19.5.4 reduction Clause. | ||||||
2488 | // A reduction clause with the task reduction-modifier may only appear on | ||||||
2489 | // a parallel construct, a worksharing construct or a combined or | ||||||
2490 | // composite construct for which any of the aforementioned constructs is a | ||||||
2491 | // constituent construct and simd or loop are not constituent constructs. | ||||||
2492 | OpenMPDirectiveKind CurDir = Stack->getCurrentDirective(); | ||||||
2493 | if (!(isOpenMPParallelDirective(CurDir) || | ||||||
2494 | isOpenMPWorksharingDirective(CurDir)) || | ||||||
2495 | isOpenMPSimdDirective(CurDir)) | ||||||
2496 | S.Diag(RC->getModifierLoc(), | ||||||
2497 | diag::err_omp_reduction_task_not_parallel_or_worksharing); | ||||||
2498 | continue; | ||||||
2499 | } | ||||||
2500 | } | ||||||
2501 | if (InscanFound) { | ||||||
2502 | for (OMPClause *C : Clauses) { | ||||||
2503 | if (C->getClauseKind() != OMPC_reduction) | ||||||
2504 | continue; | ||||||
2505 | auto *RC = cast<OMPReductionClause>(C); | ||||||
2506 | if (RC->getModifier() != OMPC_REDUCTION_inscan) { | ||||||
2507 | S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown | ||||||
2508 | ? RC->getBeginLoc() | ||||||
2509 | : RC->getModifierLoc(), | ||||||
2510 | diag::err_omp_inscan_reduction_expected); | ||||||
2511 | S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction); | ||||||
2512 | continue; | ||||||
2513 | } | ||||||
2514 | for (Expr *Ref : RC->varlists()) { | ||||||
2515 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2515, __PRETTY_FUNCTION__)); | ||||||
2516 | SourceLocation ELoc; | ||||||
2517 | SourceRange ERange; | ||||||
2518 | Expr *SimpleRefExpr = Ref; | ||||||
2519 | auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, | ||||||
2520 | /*AllowArraySection=*/true); | ||||||
2521 | ValueDecl *D = Res.first; | ||||||
2522 | if (!D) | ||||||
2523 | continue; | ||||||
2524 | if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) { | ||||||
2525 | S.Diag(Ref->getExprLoc(), | ||||||
2526 | diag::err_omp_reduction_not_inclusive_exclusive) | ||||||
2527 | << Ref->getSourceRange(); | ||||||
2528 | } | ||||||
2529 | } | ||||||
2530 | } | ||||||
2531 | } | ||||||
2532 | } | ||||||
2533 | |||||||
2534 | static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, | ||||||
2535 | ArrayRef<OMPClause *> Clauses); | ||||||
2536 | static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, | ||||||
2537 | bool WithInit); | ||||||
2538 | |||||||
2539 | static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, | ||||||
2540 | const ValueDecl *D, | ||||||
2541 | const DSAStackTy::DSAVarData &DVar, | ||||||
2542 | bool IsLoopIterVar = false); | ||||||
2543 | |||||||
2544 | void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { | ||||||
2545 | // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] | ||||||
2546 | // A variable of class type (or array thereof) that appears in a lastprivate | ||||||
2547 | // clause requires an accessible, unambiguous default constructor for the | ||||||
2548 | // class type, unless the list item is also specified in a firstprivate | ||||||
2549 | // clause. | ||||||
2550 | if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { | ||||||
2551 | for (OMPClause *C : D->clauses()) { | ||||||
2552 | if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { | ||||||
2553 | SmallVector<Expr *, 8> PrivateCopies; | ||||||
2554 | for (Expr *DE : Clause->varlists()) { | ||||||
2555 | if (DE->isValueDependent() || DE->isTypeDependent()) { | ||||||
2556 | PrivateCopies.push_back(nullptr); | ||||||
2557 | continue; | ||||||
2558 | } | ||||||
2559 | auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); | ||||||
2560 | auto *VD = cast<VarDecl>(DRE->getDecl()); | ||||||
2561 | QualType Type = VD->getType().getNonReferenceType(); | ||||||
2562 | const DSAStackTy::DSAVarData DVar = | ||||||
2563 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(VD, /*FromParent=*/false); | ||||||
2564 | if (DVar.CKind == OMPC_lastprivate) { | ||||||
2565 | // Generate helper private variable and initialize it with the | ||||||
2566 | // default value. The address of the original variable is replaced | ||||||
2567 | // by the address of the new private variable in CodeGen. This new | ||||||
2568 | // variable is not added to IdResolver, so the code in the OpenMP | ||||||
2569 | // region uses original variable for proper diagnostics. | ||||||
2570 | VarDecl *VDPrivate = buildVarDecl( | ||||||
2571 | *this, DE->getExprLoc(), Type.getUnqualifiedType(), | ||||||
2572 | VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); | ||||||
2573 | ActOnUninitializedDecl(VDPrivate); | ||||||
2574 | if (VDPrivate->isInvalidDecl()) { | ||||||
2575 | PrivateCopies.push_back(nullptr); | ||||||
2576 | continue; | ||||||
2577 | } | ||||||
2578 | PrivateCopies.push_back(buildDeclRefExpr( | ||||||
2579 | *this, VDPrivate, DE->getType(), DE->getExprLoc())); | ||||||
2580 | } else { | ||||||
2581 | // The variable is also a firstprivate, so initialization sequence | ||||||
2582 | // for private copy is generated already. | ||||||
2583 | PrivateCopies.push_back(nullptr); | ||||||
2584 | } | ||||||
2585 | } | ||||||
2586 | Clause->setPrivateCopies(PrivateCopies); | ||||||
2587 | continue; | ||||||
2588 | } | ||||||
2589 | // Finalize nontemporal clause by handling private copies, if any. | ||||||
2590 | if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) { | ||||||
2591 | SmallVector<Expr *, 8> PrivateRefs; | ||||||
2592 | for (Expr *RefExpr : Clause->varlists()) { | ||||||
2593 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2593, __PRETTY_FUNCTION__)); | ||||||
2594 | SourceLocation ELoc; | ||||||
2595 | SourceRange ERange; | ||||||
2596 | Expr *SimpleRefExpr = RefExpr; | ||||||
2597 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||||
2598 | if (Res.second) | ||||||
2599 | // It will be analyzed later. | ||||||
2600 | PrivateRefs.push_back(RefExpr); | ||||||
2601 | ValueDecl *D = Res.first; | ||||||
2602 | if (!D) | ||||||
2603 | continue; | ||||||
2604 | |||||||
2605 | const DSAStackTy::DSAVarData DVar = | ||||||
2606 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); | ||||||
2607 | PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy | ||||||
2608 | : SimpleRefExpr); | ||||||
2609 | } | ||||||
2610 | Clause->setPrivateRefs(PrivateRefs); | ||||||
2611 | continue; | ||||||
2612 | } | ||||||
2613 | if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) { | ||||||
2614 | for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) { | ||||||
2615 | OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I); | ||||||
2616 | auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts()); | ||||||
2617 | if (!DRE) | ||||||
2618 | continue; | ||||||
2619 | ValueDecl *VD = DRE->getDecl(); | ||||||
2620 | if (!VD || !isa<VarDecl>(VD)) | ||||||
2621 | continue; | ||||||
2622 | DSAStackTy::DSAVarData DVar = | ||||||
2623 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(VD, /*FromParent=*/false); | ||||||
2624 | // OpenMP [2.12.5, target Construct] | ||||||
2625 | // Memory allocators that appear in a uses_allocators clause cannot | ||||||
2626 | // appear in other data-sharing attribute clauses or data-mapping | ||||||
2627 | // attribute clauses in the same construct. | ||||||
2628 | Expr *MapExpr = nullptr; | ||||||
2629 | if (DVar.RefExpr || | ||||||
2630 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->checkMappableExprComponentListsForDecl( | ||||||
2631 | VD, /*CurrentRegionOnly=*/true, | ||||||
2632 | [VD, &MapExpr]( | ||||||
2633 | OMPClauseMappableExprCommon::MappableExprComponentListRef | ||||||
2634 | MapExprComponents, | ||||||
2635 | OpenMPClauseKind C) { | ||||||
2636 | auto MI = MapExprComponents.rbegin(); | ||||||
2637 | auto ME = MapExprComponents.rend(); | ||||||
2638 | if (MI != ME && | ||||||
2639 | MI->getAssociatedDeclaration()->getCanonicalDecl() == | ||||||
2640 | VD->getCanonicalDecl()) { | ||||||
2641 | MapExpr = MI->getAssociatedExpression(); | ||||||
2642 | return true; | ||||||
2643 | } | ||||||
2644 | return false; | ||||||
2645 | })) { | ||||||
2646 | Diag(D.Allocator->getExprLoc(), | ||||||
2647 | diag::err_omp_allocator_used_in_clauses) | ||||||
2648 | << D.Allocator->getSourceRange(); | ||||||
2649 | if (DVar.RefExpr) | ||||||
2650 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VD, DVar); | ||||||
2651 | else | ||||||
2652 | Diag(MapExpr->getExprLoc(), diag::note_used_here) | ||||||
2653 | << MapExpr->getSourceRange(); | ||||||
2654 | } | ||||||
2655 | } | ||||||
2656 | continue; | ||||||
2657 | } | ||||||
2658 | } | ||||||
2659 | // Check allocate clauses. | ||||||
2660 | if (!CurContext->isDependentContext()) | ||||||
2661 | checkAllocateClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D->clauses()); | ||||||
2662 | checkReductionClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D->clauses()); | ||||||
2663 | } | ||||||
2664 | |||||||
2665 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->pop(); | ||||||
2666 | DiscardCleanupsInEvaluationContext(); | ||||||
2667 | PopExpressionEvaluationContext(); | ||||||
2668 | } | ||||||
2669 | |||||||
2670 | static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, | ||||||
2671 | Expr *NumIterations, Sema &SemaRef, | ||||||
2672 | Scope *S, DSAStackTy *Stack); | ||||||
2673 | |||||||
2674 | namespace { | ||||||
2675 | |||||||
2676 | class VarDeclFilterCCC final : public CorrectionCandidateCallback { | ||||||
2677 | private: | ||||||
2678 | Sema &SemaRef; | ||||||
2679 | |||||||
2680 | public: | ||||||
2681 | explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} | ||||||
2682 | bool ValidateCandidate(const TypoCorrection &Candidate) override { | ||||||
2683 | NamedDecl *ND = Candidate.getCorrectionDecl(); | ||||||
2684 | if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { | ||||||
2685 | return VD->hasGlobalStorage() && | ||||||
2686 | SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), | ||||||
2687 | SemaRef.getCurScope()); | ||||||
2688 | } | ||||||
2689 | return false; | ||||||
2690 | } | ||||||
2691 | |||||||
2692 | std::unique_ptr<CorrectionCandidateCallback> clone() override { | ||||||
2693 | return std::make_unique<VarDeclFilterCCC>(*this); | ||||||
2694 | } | ||||||
2695 | |||||||
2696 | }; | ||||||
2697 | |||||||
2698 | class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { | ||||||
2699 | private: | ||||||
2700 | Sema &SemaRef; | ||||||
2701 | |||||||
2702 | public: | ||||||
2703 | explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} | ||||||
2704 | bool ValidateCandidate(const TypoCorrection &Candidate) override { | ||||||
2705 | NamedDecl *ND = Candidate.getCorrectionDecl(); | ||||||
2706 | if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || | ||||||
2707 | isa<FunctionDecl>(ND))) { | ||||||
2708 | return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), | ||||||
2709 | SemaRef.getCurScope()); | ||||||
2710 | } | ||||||
2711 | return false; | ||||||
2712 | } | ||||||
2713 | |||||||
2714 | std::unique_ptr<CorrectionCandidateCallback> clone() override { | ||||||
2715 | return std::make_unique<VarOrFuncDeclFilterCCC>(*this); | ||||||
2716 | } | ||||||
2717 | }; | ||||||
2718 | |||||||
2719 | } // namespace | ||||||
2720 | |||||||
2721 | ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, | ||||||
2722 | CXXScopeSpec &ScopeSpec, | ||||||
2723 | const DeclarationNameInfo &Id, | ||||||
2724 | OpenMPDirectiveKind Kind) { | ||||||
2725 | LookupResult Lookup(*this, Id, LookupOrdinaryName); | ||||||
2726 | LookupParsedName(Lookup, CurScope, &ScopeSpec, true); | ||||||
2727 | |||||||
2728 | if (Lookup.isAmbiguous()) | ||||||
2729 | return ExprError(); | ||||||
2730 | |||||||
2731 | VarDecl *VD; | ||||||
2732 | if (!Lookup.isSingleResult()) { | ||||||
2733 | VarDeclFilterCCC CCC(*this); | ||||||
2734 | if (TypoCorrection Corrected = | ||||||
2735 | CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, | ||||||
2736 | CTK_ErrorRecovery)) { | ||||||
2737 | diagnoseTypo(Corrected, | ||||||
2738 | PDiag(Lookup.empty() | ||||||
2739 | ? diag::err_undeclared_var_use_suggest | ||||||
2740 | : diag::err_omp_expected_var_arg_suggest) | ||||||
2741 | << Id.getName()); | ||||||
2742 | VD = Corrected.getCorrectionDeclAs<VarDecl>(); | ||||||
2743 | } else { | ||||||
2744 | Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use | ||||||
2745 | : diag::err_omp_expected_var_arg) | ||||||
2746 | << Id.getName(); | ||||||
2747 | return ExprError(); | ||||||
2748 | } | ||||||
2749 | } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { | ||||||
2750 | Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); | ||||||
2751 | Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); | ||||||
2752 | return ExprError(); | ||||||
2753 | } | ||||||
2754 | Lookup.suppressDiagnostics(); | ||||||
2755 | |||||||
2756 | // OpenMP [2.9.2, Syntax, C/C++] | ||||||
2757 | // Variables must be file-scope, namespace-scope, or static block-scope. | ||||||
2758 | if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { | ||||||
2759 | Diag(Id.getLoc(), diag::err_omp_global_var_arg) | ||||||
2760 | << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); | ||||||
2761 | bool IsDecl = | ||||||
2762 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||||
2763 | Diag(VD->getLocation(), | ||||||
2764 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||
2765 | << VD; | ||||||
2766 | return ExprError(); | ||||||
2767 | } | ||||||
2768 | |||||||
2769 | VarDecl *CanonicalVD = VD->getCanonicalDecl(); | ||||||
2770 | NamedDecl *ND = CanonicalVD; | ||||||
2771 | // OpenMP [2.9.2, Restrictions, C/C++, p.2] | ||||||
2772 | // A threadprivate directive for file-scope variables must appear outside | ||||||
2773 | // any definition or declaration. | ||||||
2774 | if (CanonicalVD->getDeclContext()->isTranslationUnit() && | ||||||
2775 | !getCurLexicalContext()->isTranslationUnit()) { | ||||||
2776 | Diag(Id.getLoc(), diag::err_omp_var_scope) | ||||||
2777 | << getOpenMPDirectiveName(Kind) << VD; | ||||||
2778 | bool IsDecl = | ||||||
2779 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||||
2780 | Diag(VD->getLocation(), | ||||||
2781 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||
2782 | << VD; | ||||||
2783 | return ExprError(); | ||||||
2784 | } | ||||||
2785 | // OpenMP [2.9.2, Restrictions, C/C++, p.3] | ||||||
2786 | // A threadprivate directive for static class member variables must appear | ||||||
2787 | // in the class definition, in the same scope in which the member | ||||||
2788 | // variables are declared. | ||||||
2789 | if (CanonicalVD->isStaticDataMember() && | ||||||
2790 | !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { | ||||||
2791 | Diag(Id.getLoc(), diag::err_omp_var_scope) | ||||||
2792 | << getOpenMPDirectiveName(Kind) << VD; | ||||||
2793 | bool IsDecl = | ||||||
2794 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||||
2795 | Diag(VD->getLocation(), | ||||||
2796 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||
2797 | << VD; | ||||||
2798 | return ExprError(); | ||||||
2799 | } | ||||||
2800 | // OpenMP [2.9.2, Restrictions, C/C++, p.4] | ||||||
2801 | // A threadprivate directive for namespace-scope variables must appear | ||||||
2802 | // outside any definition or declaration other than the namespace | ||||||
2803 | // definition itself. | ||||||
2804 | if (CanonicalVD->getDeclContext()->isNamespace() && | ||||||
2805 | (!getCurLexicalContext()->isFileContext() || | ||||||
2806 | !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { | ||||||
2807 | Diag(Id.getLoc(), diag::err_omp_var_scope) | ||||||
2808 | << getOpenMPDirectiveName(Kind) << VD; | ||||||
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 | // OpenMP [2.9.2, Restrictions, C/C++, p.6] | ||||||
2817 | // A threadprivate directive for static block-scope variables must appear | ||||||
2818 | // in the scope of the variable and not in a nested scope. | ||||||
2819 | if (CanonicalVD->isLocalVarDecl() && CurScope && | ||||||
2820 | !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { | ||||||
2821 | Diag(Id.getLoc(), diag::err_omp_var_scope) | ||||||
2822 | << getOpenMPDirectiveName(Kind) << VD; | ||||||
2823 | bool IsDecl = | ||||||
2824 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||||
2825 | Diag(VD->getLocation(), | ||||||
2826 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||
2827 | << VD; | ||||||
2828 | return ExprError(); | ||||||
2829 | } | ||||||
2830 | |||||||
2831 | // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] | ||||||
2832 | // A threadprivate directive must lexically precede all references to any | ||||||
2833 | // of the variables in its list. | ||||||
2834 | if (Kind == OMPD_threadprivate && VD->isUsed() && | ||||||
2835 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isThreadPrivate(VD)) { | ||||||
2836 | Diag(Id.getLoc(), diag::err_omp_var_used) | ||||||
2837 | << getOpenMPDirectiveName(Kind) << VD; | ||||||
2838 | return ExprError(); | ||||||
2839 | } | ||||||
2840 | |||||||
2841 | QualType ExprType = VD->getType().getNonReferenceType(); | ||||||
2842 | return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), | ||||||
2843 | SourceLocation(), VD, | ||||||
2844 | /*RefersToEnclosingVariableOrCapture=*/false, | ||||||
2845 | Id.getLoc(), ExprType, VK_LValue); | ||||||
2846 | } | ||||||
2847 | |||||||
2848 | Sema::DeclGroupPtrTy | ||||||
2849 | Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, | ||||||
2850 | ArrayRef<Expr *> VarList) { | ||||||
2851 | if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { | ||||||
2852 | CurContext->addDecl(D); | ||||||
2853 | return DeclGroupPtrTy::make(DeclGroupRef(D)); | ||||||
2854 | } | ||||||
2855 | return nullptr; | ||||||
2856 | } | ||||||
2857 | |||||||
2858 | namespace { | ||||||
2859 | class LocalVarRefChecker final | ||||||
2860 | : public ConstStmtVisitor<LocalVarRefChecker, bool> { | ||||||
2861 | Sema &SemaRef; | ||||||
2862 | |||||||
2863 | public: | ||||||
2864 | bool VisitDeclRefExpr(const DeclRefExpr *E) { | ||||||
2865 | if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { | ||||||
2866 | if (VD->hasLocalStorage()) { | ||||||
2867 | SemaRef.Diag(E->getBeginLoc(), | ||||||
2868 | diag::err_omp_local_var_in_threadprivate_init) | ||||||
2869 | << E->getSourceRange(); | ||||||
2870 | SemaRef.Diag(VD->getLocation(), diag::note_defined_here) | ||||||
2871 | << VD << VD->getSourceRange(); | ||||||
2872 | return true; | ||||||
2873 | } | ||||||
2874 | } | ||||||
2875 | return false; | ||||||
2876 | } | ||||||
2877 | bool VisitStmt(const Stmt *S) { | ||||||
2878 | for (const Stmt *Child : S->children()) { | ||||||
2879 | if (Child && Visit(Child)) | ||||||
2880 | return true; | ||||||
2881 | } | ||||||
2882 | return false; | ||||||
2883 | } | ||||||
2884 | explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} | ||||||
2885 | }; | ||||||
2886 | } // namespace | ||||||
2887 | |||||||
2888 | OMPThreadPrivateDecl * | ||||||
2889 | Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { | ||||||
2890 | SmallVector<Expr *, 8> Vars; | ||||||
2891 | for (Expr *RefExpr : VarList) { | ||||||
2892 | auto *DE = cast<DeclRefExpr>(RefExpr); | ||||||
2893 | auto *VD = cast<VarDecl>(DE->getDecl()); | ||||||
2894 | SourceLocation ILoc = DE->getExprLoc(); | ||||||
2895 | |||||||
2896 | // Mark variable as used. | ||||||
2897 | VD->setReferenced(); | ||||||
2898 | VD->markUsed(Context); | ||||||
2899 | |||||||
2900 | QualType QType = VD->getType(); | ||||||
2901 | if (QType->isDependentType() || QType->isInstantiationDependentType()) { | ||||||
2902 | // It will be analyzed later. | ||||||
2903 | Vars.push_back(DE); | ||||||
2904 | continue; | ||||||
2905 | } | ||||||
2906 | |||||||
2907 | // OpenMP [2.9.2, Restrictions, C/C++, p.10] | ||||||
2908 | // A threadprivate variable must not have an incomplete type. | ||||||
2909 | if (RequireCompleteType(ILoc, VD->getType(), | ||||||
2910 | diag::err_omp_threadprivate_incomplete_type)) { | ||||||
2911 | continue; | ||||||
2912 | } | ||||||
2913 | |||||||
2914 | // OpenMP [2.9.2, Restrictions, C/C++, p.10] | ||||||
2915 | // A threadprivate variable must not have a reference type. | ||||||
2916 | if (VD->getType()->isReferenceType()) { | ||||||
2917 | Diag(ILoc, diag::err_omp_ref_type_arg) | ||||||
2918 | << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); | ||||||
2919 | bool IsDecl = | ||||||
2920 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||||
2921 | Diag(VD->getLocation(), | ||||||
2922 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||
2923 | << VD; | ||||||
2924 | continue; | ||||||
2925 | } | ||||||
2926 | |||||||
2927 | // Check if this is a TLS variable. If TLS is not being supported, produce | ||||||
2928 | // the corresponding diagnostic. | ||||||
2929 | if ((VD->getTLSKind() != VarDecl::TLS_None && | ||||||
2930 | !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && | ||||||
2931 | getLangOpts().OpenMPUseTLS && | ||||||
2932 | getASTContext().getTargetInfo().isTLSSupported())) || | ||||||
2933 | (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && | ||||||
2934 | !VD->isLocalVarDecl())) { | ||||||
2935 | Diag(ILoc, diag::err_omp_var_thread_local) | ||||||
2936 | << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); | ||||||
2937 | bool IsDecl = | ||||||
2938 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||||
2939 | Diag(VD->getLocation(), | ||||||
2940 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||
2941 | << VD; | ||||||
2942 | continue; | ||||||
2943 | } | ||||||
2944 | |||||||
2945 | // Check if initial value of threadprivate variable reference variable with | ||||||
2946 | // local storage (it is not supported by runtime). | ||||||
2947 | if (const Expr *Init = VD->getAnyInitializer()) { | ||||||
2948 | LocalVarRefChecker Checker(*this); | ||||||
2949 | if (Checker.Visit(Init)) | ||||||
2950 | continue; | ||||||
2951 | } | ||||||
2952 | |||||||
2953 | Vars.push_back(RefExpr); | ||||||
2954 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(VD, DE, OMPC_threadprivate); | ||||||
2955 | VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( | ||||||
2956 | Context, SourceRange(Loc, Loc))); | ||||||
2957 | if (ASTMutationListener *ML = Context.getASTMutationListener()) | ||||||
2958 | ML->DeclarationMarkedOpenMPThreadPrivate(VD); | ||||||
2959 | } | ||||||
2960 | OMPThreadPrivateDecl *D = nullptr; | ||||||
2961 | if (!Vars.empty()) { | ||||||
2962 | D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, | ||||||
2963 | Vars); | ||||||
2964 | D->setAccess(AS_public); | ||||||
2965 | } | ||||||
2966 | return D; | ||||||
2967 | } | ||||||
2968 | |||||||
2969 | static OMPAllocateDeclAttr::AllocatorTypeTy | ||||||
2970 | getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { | ||||||
2971 | if (!Allocator) | ||||||
2972 | return OMPAllocateDeclAttr::OMPNullMemAlloc; | ||||||
2973 | if (Allocator->isTypeDependent() || Allocator->isValueDependent() || | ||||||
2974 | Allocator->isInstantiationDependent() || | ||||||
2975 | Allocator->containsUnexpandedParameterPack()) | ||||||
2976 | return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; | ||||||
2977 | auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; | ||||||
2978 | const Expr *AE = Allocator->IgnoreParenImpCasts(); | ||||||
2979 | for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { | ||||||
2980 | auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); | ||||||
2981 | const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); | ||||||
2982 | llvm::FoldingSetNodeID AEId, DAEId; | ||||||
2983 | AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); | ||||||
2984 | DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); | ||||||
2985 | if (AEId == DAEId) { | ||||||
2986 | AllocatorKindRes = AllocatorKind; | ||||||
2987 | break; | ||||||
2988 | } | ||||||
2989 | } | ||||||
2990 | return AllocatorKindRes; | ||||||
2991 | } | ||||||
2992 | |||||||
2993 | static bool checkPreviousOMPAllocateAttribute( | ||||||
2994 | Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, | ||||||
2995 | OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { | ||||||
2996 | if (!VD->hasAttr<OMPAllocateDeclAttr>()) | ||||||
2997 | return false; | ||||||
2998 | const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); | ||||||
2999 | Expr *PrevAllocator = A->getAllocator(); | ||||||
3000 | OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = | ||||||
3001 | getAllocatorKind(S, Stack, PrevAllocator); | ||||||
3002 | bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; | ||||||
3003 | if (AllocatorsMatch && | ||||||
3004 | AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && | ||||||
3005 | Allocator && PrevAllocator) { | ||||||
3006 | const Expr *AE = Allocator->IgnoreParenImpCasts(); | ||||||
3007 | const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); | ||||||
3008 | llvm::FoldingSetNodeID AEId, PAEId; | ||||||
3009 | AE->Profile(AEId, S.Context, /*Canonical=*/true); | ||||||
3010 | PAE->Profile(PAEId, S.Context, /*Canonical=*/true); | ||||||
3011 | AllocatorsMatch = AEId == PAEId; | ||||||
3012 | } | ||||||
3013 | if (!AllocatorsMatch) { | ||||||
3014 | SmallString<256> AllocatorBuffer; | ||||||
3015 | llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); | ||||||
3016 | if (Allocator) | ||||||
3017 | Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); | ||||||
3018 | SmallString<256> PrevAllocatorBuffer; | ||||||
3019 | llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); | ||||||
3020 | if (PrevAllocator) | ||||||
3021 | PrevAllocator->printPretty(PrevAllocatorStream, nullptr, | ||||||
3022 | S.getPrintingPolicy()); | ||||||
3023 | |||||||
3024 | SourceLocation AllocatorLoc = | ||||||
3025 | Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); | ||||||
3026 | SourceRange AllocatorRange = | ||||||
3027 | Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); | ||||||
3028 | SourceLocation PrevAllocatorLoc = | ||||||
3029 | PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); | ||||||
3030 | SourceRange PrevAllocatorRange = | ||||||
3031 | PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); | ||||||
3032 | S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) | ||||||
3033 | << (Allocator ? 1 : 0) << AllocatorStream.str() | ||||||
3034 | << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() | ||||||
3035 | << AllocatorRange; | ||||||
3036 | S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) | ||||||
3037 | << PrevAllocatorRange; | ||||||
3038 | return true; | ||||||
3039 | } | ||||||
3040 | return false; | ||||||
3041 | } | ||||||
3042 | |||||||
3043 | static void | ||||||
3044 | applyOMPAllocateAttribute(Sema &S, VarDecl *VD, | ||||||
3045 | OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, | ||||||
3046 | Expr *Allocator, SourceRange SR) { | ||||||
3047 | if (VD->hasAttr<OMPAllocateDeclAttr>()) | ||||||
3048 | return; | ||||||
3049 | if (Allocator && | ||||||
3050 | (Allocator->isTypeDependent() || Allocator->isValueDependent() || | ||||||
3051 | Allocator->isInstantiationDependent() || | ||||||
3052 | Allocator->containsUnexpandedParameterPack())) | ||||||
3053 | return; | ||||||
3054 | auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, | ||||||
3055 | Allocator, SR); | ||||||
3056 | VD->addAttr(A); | ||||||
3057 | if (ASTMutationListener *ML = S.Context.getASTMutationListener()) | ||||||
3058 | ML->DeclarationMarkedOpenMPAllocate(VD, A); | ||||||
3059 | } | ||||||
3060 | |||||||
3061 | Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( | ||||||
3062 | SourceLocation Loc, ArrayRef<Expr *> VarList, | ||||||
3063 | ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { | ||||||
3064 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 3064, __PRETTY_FUNCTION__)); | ||||||
3065 | Expr *Allocator = nullptr; | ||||||
3066 | if (Clauses.empty()) { | ||||||
3067 | // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. | ||||||
3068 | // allocate directives that appear in a target region must specify an | ||||||
3069 | // allocator clause unless a requires directive with the dynamic_allocators | ||||||
3070 | // clause is present in the same compilation unit. | ||||||
3071 | if (LangOpts.OpenMPIsDevice && | ||||||
3072 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) | ||||||
3073 | targetDiag(Loc, diag::err_expected_allocator_clause); | ||||||
3074 | } else { | ||||||
3075 | Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); | ||||||
3076 | } | ||||||
3077 | OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = | ||||||
3078 | getAllocatorKind(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), Allocator); | ||||||
3079 | SmallVector<Expr *, 8> Vars; | ||||||
3080 | for (Expr *RefExpr : VarList) { | ||||||
3081 | auto *DE = cast<DeclRefExpr>(RefExpr); | ||||||
3082 | auto *VD = cast<VarDecl>(DE->getDecl()); | ||||||
3083 | |||||||
3084 | // Check if this is a TLS variable or global register. | ||||||
3085 | if (VD->getTLSKind() != VarDecl::TLS_None || | ||||||
3086 | VD->hasAttr<OMPThreadPrivateDeclAttr>() || | ||||||
3087 | (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && | ||||||
3088 | !VD->isLocalVarDecl())) | ||||||
3089 | continue; | ||||||
3090 | |||||||
3091 | // If the used several times in the allocate directive, the same allocator | ||||||
3092 | // must be used. | ||||||
3093 | if (checkPreviousOMPAllocateAttribute(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), RefExpr, VD, | ||||||
3094 | AllocatorKind, Allocator)) | ||||||
3095 | continue; | ||||||
3096 | |||||||
3097 | // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ | ||||||
3098 | // If a list item has a static storage type, the allocator expression in the | ||||||
3099 | // allocator clause must be a constant expression that evaluates to one of | ||||||
3100 | // the predefined memory allocator values. | ||||||
3101 | if (Allocator && VD->hasGlobalStorage()) { | ||||||
3102 | if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { | ||||||
3103 | Diag(Allocator->getExprLoc(), | ||||||
3104 | diag::err_omp_expected_predefined_allocator) | ||||||
3105 | << Allocator->getSourceRange(); | ||||||
3106 | bool IsDecl = VD->isThisDeclarationADefinition(Context) == | ||||||
3107 | VarDecl::DeclarationOnly; | ||||||
3108 | Diag(VD->getLocation(), | ||||||
3109 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||
3110 | << VD; | ||||||
3111 | continue; | ||||||
3112 | } | ||||||
3113 | } | ||||||
3114 | |||||||
3115 | Vars.push_back(RefExpr); | ||||||
3116 | applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, | ||||||
3117 | DE->getSourceRange()); | ||||||
3118 | } | ||||||
3119 | if (Vars.empty()) | ||||||
3120 | return nullptr; | ||||||
3121 | if (!Owner) | ||||||
3122 | Owner = getCurLexicalContext(); | ||||||
3123 | auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); | ||||||
3124 | D->setAccess(AS_public); | ||||||
3125 | Owner->addDecl(D); | ||||||
3126 | return DeclGroupPtrTy::make(DeclGroupRef(D)); | ||||||
3127 | } | ||||||
3128 | |||||||
3129 | Sema::DeclGroupPtrTy | ||||||
3130 | Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, | ||||||
3131 | ArrayRef<OMPClause *> ClauseList) { | ||||||
3132 | OMPRequiresDecl *D = nullptr; | ||||||
3133 | if (!CurContext->isFileContext()) { | ||||||
3134 | Diag(Loc, diag::err_omp_invalid_scope) << "requires"; | ||||||
3135 | } else { | ||||||
3136 | D = CheckOMPRequiresDecl(Loc, ClauseList); | ||||||
3137 | if (D) { | ||||||
3138 | CurContext->addDecl(D); | ||||||
3139 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addRequiresDecl(D); | ||||||
3140 | } | ||||||
3141 | } | ||||||
3142 | return DeclGroupPtrTy::make(DeclGroupRef(D)); | ||||||
3143 | } | ||||||
3144 | |||||||
3145 | OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, | ||||||
3146 | ArrayRef<OMPClause *> ClauseList) { | ||||||
3147 | /// For target specific clauses, the requires directive cannot be | ||||||
3148 | /// specified after the handling of any of the target regions in the | ||||||
3149 | /// current compilation unit. | ||||||
3150 | ArrayRef<SourceLocation> TargetLocations = | ||||||
3151 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getEncounteredTargetLocs(); | ||||||
3152 | SourceLocation AtomicLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getAtomicDirectiveLoc(); | ||||||
3153 | if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) { | ||||||
3154 | for (const OMPClause *CNew : ClauseList) { | ||||||
3155 | // Check if any of the requires clauses affect target regions. | ||||||
3156 | if (isa<OMPUnifiedSharedMemoryClause>(CNew) || | ||||||
3157 | isa<OMPUnifiedAddressClause>(CNew) || | ||||||
3158 | isa<OMPReverseOffloadClause>(CNew) || | ||||||
3159 | isa<OMPDynamicAllocatorsClause>(CNew)) { | ||||||
3160 | Diag(Loc, diag::err_omp_directive_before_requires) | ||||||
3161 | << "target" << getOpenMPClauseName(CNew->getClauseKind()); | ||||||
3162 | for (SourceLocation TargetLoc : TargetLocations) { | ||||||
3163 | Diag(TargetLoc, diag::note_omp_requires_encountered_directive) | ||||||
3164 | << "target"; | ||||||
3165 | } | ||||||
3166 | } else if (!AtomicLoc.isInvalid() && | ||||||
3167 | isa<OMPAtomicDefaultMemOrderClause>(CNew)) { | ||||||
3168 | Diag(Loc, diag::err_omp_directive_before_requires) | ||||||
3169 | << "atomic" << getOpenMPClauseName(CNew->getClauseKind()); | ||||||
3170 | Diag(AtomicLoc, diag::note_omp_requires_encountered_directive) | ||||||
3171 | << "atomic"; | ||||||
3172 | } | ||||||
3173 | } | ||||||
3174 | } | ||||||
3175 | |||||||
3176 | if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasDuplicateRequiresClause(ClauseList)) | ||||||
3177 | return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, | ||||||
3178 | ClauseList); | ||||||
3179 | return nullptr; | ||||||
3180 | } | ||||||
3181 | |||||||
3182 | static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, | ||||||
3183 | const ValueDecl *D, | ||||||
3184 | const DSAStackTy::DSAVarData &DVar, | ||||||
3185 | bool IsLoopIterVar) { | ||||||
3186 | if (DVar.RefExpr) { | ||||||
3187 | SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) | ||||||
3188 | << getOpenMPClauseName(DVar.CKind); | ||||||
3189 | return; | ||||||
3190 | } | ||||||
3191 | enum { | ||||||
3192 | PDSA_StaticMemberShared, | ||||||
3193 | PDSA_StaticLocalVarShared, | ||||||
3194 | PDSA_LoopIterVarPrivate, | ||||||
3195 | PDSA_LoopIterVarLinear, | ||||||
3196 | PDSA_LoopIterVarLastprivate, | ||||||
3197 | PDSA_ConstVarShared, | ||||||
3198 | PDSA_GlobalVarShared, | ||||||
3199 | PDSA_TaskVarFirstprivate, | ||||||
3200 | PDSA_LocalVarPrivate, | ||||||
3201 | PDSA_Implicit | ||||||
3202 | } Reason = PDSA_Implicit; | ||||||
3203 | bool ReportHint = false; | ||||||
3204 | auto ReportLoc = D->getLocation(); | ||||||
3205 | auto *VD = dyn_cast<VarDecl>(D); | ||||||
3206 | if (IsLoopIterVar) { | ||||||
3207 | if (DVar.CKind == OMPC_private) | ||||||
3208 | Reason = PDSA_LoopIterVarPrivate; | ||||||
3209 | else if (DVar.CKind == OMPC_lastprivate) | ||||||
3210 | Reason = PDSA_LoopIterVarLastprivate; | ||||||
3211 | else | ||||||
3212 | Reason = PDSA_LoopIterVarLinear; | ||||||
3213 | } else if (isOpenMPTaskingDirective(DVar.DKind) && | ||||||
3214 | DVar.CKind == OMPC_firstprivate) { | ||||||
3215 | Reason = PDSA_TaskVarFirstprivate; | ||||||
3216 | ReportLoc = DVar.ImplicitDSALoc; | ||||||
3217 | } else if (VD && VD->isStaticLocal()) | ||||||
3218 | Reason = PDSA_StaticLocalVarShared; | ||||||
3219 | else if (VD && VD->isStaticDataMember()) | ||||||
3220 | Reason = PDSA_StaticMemberShared; | ||||||
3221 | else if (VD && VD->isFileVarDecl()) | ||||||
3222 | Reason = PDSA_GlobalVarShared; | ||||||
3223 | else if (D->getType().isConstant(SemaRef.getASTContext())) | ||||||
3224 | Reason = PDSA_ConstVarShared; | ||||||
3225 | else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { | ||||||
3226 | ReportHint = true; | ||||||
3227 | Reason = PDSA_LocalVarPrivate; | ||||||
3228 | } | ||||||
3229 | if (Reason != PDSA_Implicit) { | ||||||
3230 | SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) | ||||||
3231 | << Reason << ReportHint | ||||||
3232 | << getOpenMPDirectiveName(Stack->getCurrentDirective()); | ||||||
3233 | } else if (DVar.ImplicitDSALoc.isValid()) { | ||||||
3234 | SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) | ||||||
3235 | << getOpenMPClauseName(DVar.CKind); | ||||||
3236 | } | ||||||
3237 | } | ||||||
3238 | |||||||
3239 | static OpenMPMapClauseKind | ||||||
3240 | getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, | ||||||
3241 | bool IsAggregateOrDeclareTarget) { | ||||||
3242 | OpenMPMapClauseKind Kind = OMPC_MAP_unknown; | ||||||
3243 | switch (M) { | ||||||
3244 | case OMPC_DEFAULTMAP_MODIFIER_alloc: | ||||||
3245 | Kind = OMPC_MAP_alloc; | ||||||
3246 | break; | ||||||
3247 | case OMPC_DEFAULTMAP_MODIFIER_to: | ||||||
3248 | Kind = OMPC_MAP_to; | ||||||
3249 | break; | ||||||
3250 | case OMPC_DEFAULTMAP_MODIFIER_from: | ||||||
3251 | Kind = OMPC_MAP_from; | ||||||
3252 | break; | ||||||
3253 | case OMPC_DEFAULTMAP_MODIFIER_tofrom: | ||||||
3254 | Kind = OMPC_MAP_tofrom; | ||||||
3255 | break; | ||||||
3256 | case OMPC_DEFAULTMAP_MODIFIER_firstprivate: | ||||||
3257 | case OMPC_DEFAULTMAP_MODIFIER_last: | ||||||
3258 | llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 3258); | ||||||
3259 | case OMPC_DEFAULTMAP_MODIFIER_none: | ||||||
3260 | case OMPC_DEFAULTMAP_MODIFIER_default: | ||||||
3261 | case OMPC_DEFAULTMAP_MODIFIER_unknown: | ||||||
3262 | // IsAggregateOrDeclareTarget could be true if: | ||||||
3263 | // 1. the implicit behavior for aggregate is tofrom | ||||||
3264 | // 2. it's a declare target link | ||||||
3265 | if (IsAggregateOrDeclareTarget) { | ||||||
3266 | Kind = OMPC_MAP_tofrom; | ||||||
3267 | break; | ||||||
3268 | } | ||||||
3269 | llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 3269); | ||||||
3270 | } | ||||||
3271 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 3271, __PRETTY_FUNCTION__)); | ||||||
3272 | return Kind; | ||||||
3273 | } | ||||||
3274 | |||||||
3275 | namespace { | ||||||
3276 | class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { | ||||||
3277 | DSAStackTy *Stack; | ||||||
3278 | Sema &SemaRef; | ||||||
3279 | bool ErrorFound = false; | ||||||
3280 | bool TryCaptureCXXThisMembers = false; | ||||||
3281 | CapturedStmt *CS = nullptr; | ||||||
3282 | llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; | ||||||
3283 | llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete]; | ||||||
3284 | Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; | ||||||
3285 | llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; | ||||||
3286 | |||||||
3287 | void VisitSubCaptures(OMPExecutableDirective *S) { | ||||||
3288 | // Check implicitly captured variables. | ||||||
3289 | if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) | ||||||
3290 | return; | ||||||
3291 | visitSubCaptures(S->getInnermostCapturedStmt()); | ||||||
3292 | // Try to capture inner this->member references to generate correct mappings | ||||||
3293 | // and diagnostics. | ||||||
3294 | if (TryCaptureCXXThisMembers || | ||||||
3295 | (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && | ||||||
3296 | llvm::any_of(S->getInnermostCapturedStmt()->captures(), | ||||||
3297 | [](const CapturedStmt::Capture &C) { | ||||||
3298 | return C.capturesThis(); | ||||||
3299 | }))) { | ||||||
3300 | bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; | ||||||
3301 | TryCaptureCXXThisMembers = true; | ||||||
3302 | Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); | ||||||
3303 | TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; | ||||||
3304 | } | ||||||
3305 | // In tasks firstprivates are not captured anymore, need to analyze them | ||||||
3306 | // explicitly. | ||||||
3307 | if (isOpenMPTaskingDirective(S->getDirectiveKind()) && | ||||||
3308 | !isOpenMPTaskLoopDirective(S->getDirectiveKind())) { | ||||||
3309 | for (OMPClause *C : S->clauses()) | ||||||
3310 | if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) { | ||||||
3311 | for (Expr *Ref : FC->varlists()) | ||||||
3312 | Visit(Ref); | ||||||
3313 | } | ||||||
3314 | } | ||||||
3315 | } | ||||||
3316 | |||||||
3317 | public: | ||||||
3318 | void VisitDeclRefExpr(DeclRefExpr *E) { | ||||||
3319 | if (TryCaptureCXXThisMembers || E->isTypeDependent() || | ||||||
3320 | E->isValueDependent() || E->containsUnexpandedParameterPack() || | ||||||
3321 | E->isInstantiationDependent()) | ||||||
3322 | return; | ||||||
3323 | if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { | ||||||
3324 | // Check the datasharing rules for the expressions in the clauses. | ||||||
3325 | if (!CS) { | ||||||
3326 | if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) | ||||||
3327 | if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { | ||||||
3328 | Visit(CED->getInit()); | ||||||
3329 | return; | ||||||
3330 | } | ||||||
3331 | } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) | ||||||
3332 | // Do not analyze internal variables and do not enclose them into | ||||||
3333 | // implicit clauses. | ||||||
3334 | return; | ||||||
3335 | VD = VD->getCanonicalDecl(); | ||||||
3336 | // Skip internally declared variables. | ||||||
3337 | if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) && | ||||||
3338 | !Stack->isImplicitTaskFirstprivate(VD)) | ||||||
3339 | return; | ||||||
3340 | // Skip allocators in uses_allocators clauses. | ||||||
3341 | if (Stack->isUsesAllocatorsDecl(VD).hasValue()) | ||||||
3342 | return; | ||||||
3343 | |||||||
3344 | DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); | ||||||
3345 | // Check if the variable has explicit DSA set and stop analysis if it so. | ||||||
3346 | if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) | ||||||
3347 | return; | ||||||
3348 | |||||||
3349 | // Skip internally declared static variables. | ||||||
3350 | llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = | ||||||
3351 | OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); | ||||||
3352 | if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && | ||||||
3353 | (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || | ||||||
3354 | !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) && | ||||||
3355 | !Stack->isImplicitTaskFirstprivate(VD)) | ||||||
3356 | return; | ||||||
3357 | |||||||
3358 | SourceLocation ELoc = E->getExprLoc(); | ||||||
3359 | OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); | ||||||
3360 | // The default(none) clause requires that each variable that is referenced | ||||||
3361 | // in the construct, and does not have a predetermined data-sharing | ||||||
3362 | // attribute, must have its data-sharing attribute explicitly determined | ||||||
3363 | // by being listed in a data-sharing attribute clause. | ||||||
3364 | if (DVar.CKind == OMPC_unknown && | ||||||
3365 | (Stack->getDefaultDSA() == DSA_none || | ||||||
3366 | Stack->getDefaultDSA() == DSA_firstprivate) && | ||||||
3367 | isImplicitOrExplicitTaskingRegion(DKind) && | ||||||
3368 | VarsWithInheritedDSA.count(VD) == 0) { | ||||||
3369 | bool InheritedDSA = Stack->getDefaultDSA() == DSA_none; | ||||||
3370 | if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) { | ||||||
3371 | DSAStackTy::DSAVarData DVar = | ||||||
3372 | Stack->getImplicitDSA(VD, /*FromParent=*/false); | ||||||
3373 | InheritedDSA = DVar.CKind == OMPC_unknown; | ||||||
3374 | } | ||||||
3375 | if (InheritedDSA) | ||||||
3376 | VarsWithInheritedDSA[VD] = E; | ||||||
3377 | return; | ||||||
3378 | } | ||||||
3379 | |||||||
3380 | // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] | ||||||
3381 | // If implicit-behavior is none, each variable referenced in the | ||||||
3382 | // construct that does not have a predetermined data-sharing attribute | ||||||
3383 | // and does not appear in a to or link clause on a declare target | ||||||
3384 | // directive must be listed in a data-mapping attribute clause, a | ||||||
3385 | // data-haring attribute clause (including a data-sharing attribute | ||||||
3386 | // clause on a combined construct where target. is one of the | ||||||
3387 | // constituent constructs), or an is_device_ptr clause. | ||||||
3388 | OpenMPDefaultmapClauseKind ClauseKind = | ||||||
3389 | getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); | ||||||
3390 | if (SemaRef.getLangOpts().OpenMP >= 50) { | ||||||
3391 | bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == | ||||||
3392 | OMPC_DEFAULTMAP_MODIFIER_none; | ||||||
3393 | if (DVar.CKind == OMPC_unknown && IsModifierNone && | ||||||
3394 | VarsWithInheritedDSA.count(VD) == 0 && !Res) { | ||||||
3395 | // Only check for data-mapping attribute and is_device_ptr here | ||||||
3396 | // since we have already make sure that the declaration does not | ||||||
3397 | // have a data-sharing attribute above | ||||||
3398 | if (!Stack->checkMappableExprComponentListsForDecl( | ||||||
3399 | VD, /*CurrentRegionOnly=*/true, | ||||||
3400 | [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef | ||||||
3401 | MapExprComponents, | ||||||
3402 | OpenMPClauseKind) { | ||||||
3403 | auto MI = MapExprComponents.rbegin(); | ||||||
3404 | auto ME = MapExprComponents.rend(); | ||||||
3405 | return MI != ME && MI->getAssociatedDeclaration() == VD; | ||||||
3406 | })) { | ||||||
3407 | VarsWithInheritedDSA[VD] = E; | ||||||
3408 | return; | ||||||
3409 | } | ||||||
3410 | } | ||||||
3411 | } | ||||||
3412 | |||||||
3413 | if (isOpenMPTargetExecutionDirective(DKind) && | ||||||
3414 | !Stack->isLoopControlVariable(VD).first) { | ||||||
3415 | if (!Stack->checkMappableExprComponentListsForDecl( | ||||||
3416 | VD, /*CurrentRegionOnly=*/true, | ||||||
3417 | [](OMPClauseMappableExprCommon::MappableExprComponentListRef | ||||||
3418 | StackComponents, | ||||||
3419 | OpenMPClauseKind) { | ||||||
3420 | // Variable is used if it has been marked as an array, array | ||||||
3421 | // section, array shaping or the variable iself. | ||||||
3422 | return StackComponents.size() == 1 || | ||||||
3423 | std::all_of( | ||||||
3424 | std::next(StackComponents.rbegin()), | ||||||
3425 | StackComponents.rend(), | ||||||
3426 | [](const OMPClauseMappableExprCommon:: | ||||||
3427 | MappableComponent &MC) { | ||||||
3428 | return MC.getAssociatedDeclaration() == | ||||||
3429 | nullptr && | ||||||
3430 | (isa<OMPArraySectionExpr>( | ||||||
3431 | MC.getAssociatedExpression()) || | ||||||
3432 | isa<OMPArrayShapingExpr>( | ||||||
3433 | MC.getAssociatedExpression()) || | ||||||
3434 | isa<ArraySubscriptExpr>( | ||||||
3435 | MC.getAssociatedExpression())); | ||||||
3436 | }); | ||||||
3437 | })) { | ||||||
3438 | bool IsFirstprivate = false; | ||||||
3439 | // By default lambdas are captured as firstprivates. | ||||||
3440 | if (const auto *RD = | ||||||
3441 | VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) | ||||||
3442 | IsFirstprivate = RD->isLambda(); | ||||||
3443 | IsFirstprivate = | ||||||
3444 | IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); | ||||||
3445 | if (IsFirstprivate) { | ||||||
3446 | ImplicitFirstprivate.emplace_back(E); | ||||||
3447 | } else { | ||||||
3448 | OpenMPDefaultmapClauseModifier M = | ||||||
3449 | Stack->getDefaultmapModifier(ClauseKind); | ||||||
3450 | OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( | ||||||
3451 | M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); | ||||||
3452 | ImplicitMap[Kind].emplace_back(E); | ||||||
3453 | } | ||||||
3454 | return; | ||||||
3455 | } | ||||||
3456 | } | ||||||
3457 | |||||||
3458 | // OpenMP [2.9.3.6, Restrictions, p.2] | ||||||
3459 | // A list item that appears in a reduction clause of the innermost | ||||||
3460 | // enclosing worksharing or parallel construct may not be accessed in an | ||||||
3461 | // explicit task. | ||||||
3462 | DVar = Stack->hasInnermostDSA( | ||||||
3463 | VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, | ||||||
3464 | [](OpenMPDirectiveKind K) { | ||||||
3465 | return isOpenMPParallelDirective(K) || | ||||||
3466 | isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); | ||||||
3467 | }, | ||||||
3468 | /*FromParent=*/true); | ||||||
3469 | if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { | ||||||
3470 | ErrorFound = true; | ||||||
3471 | SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); | ||||||
3472 | reportOriginalDsa(SemaRef, Stack, VD, DVar); | ||||||
3473 | return; | ||||||
3474 | } | ||||||
3475 | |||||||
3476 | // Define implicit data-sharing attributes for task. | ||||||
3477 | DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); | ||||||
3478 | if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) || | ||||||
3479 | (Stack->getDefaultDSA() == DSA_firstprivate && | ||||||
3480 | DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) && | ||||||
3481 | !Stack->isLoopControlVariable(VD).first) { | ||||||
3482 | ImplicitFirstprivate.push_back(E); | ||||||
3483 | return; | ||||||
3484 | } | ||||||
3485 | |||||||
3486 | // Store implicitly used globals with declare target link for parent | ||||||
3487 | // target. | ||||||
3488 | if (!isOpenMPTargetExecutionDirective(DKind) && Res && | ||||||
3489 | *Res == OMPDeclareTargetDeclAttr::MT_Link) { | ||||||
3490 | Stack->addToParentTargetRegionLinkGlobals(E); | ||||||
3491 | return; | ||||||
3492 | } | ||||||
3493 | } | ||||||
3494 | } | ||||||
3495 | void VisitMemberExpr(MemberExpr *E) { | ||||||
3496 | if (E->isTypeDependent() || E->isValueDependent() || | ||||||
3497 | E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) | ||||||
3498 | return; | ||||||
3499 | auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); | ||||||
3500 | OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); | ||||||
3501 | if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) { | ||||||
3502 | if (!FD) | ||||||
3503 | return; | ||||||
3504 | DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); | ||||||
3505 | // Check if the variable has explicit DSA set and stop analysis if it | ||||||
3506 | // so. | ||||||
3507 | if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) | ||||||
3508 | return; | ||||||
3509 | |||||||
3510 | if (isOpenMPTargetExecutionDirective(DKind) && | ||||||
3511 | !Stack->isLoopControlVariable(FD).first && | ||||||
3512 | !Stack->checkMappableExprComponentListsForDecl( | ||||||
3513 | FD, /*CurrentRegionOnly=*/true, | ||||||
3514 | [](OMPClauseMappableExprCommon::MappableExprComponentListRef | ||||||
3515 | StackComponents, | ||||||
3516 | OpenMPClauseKind) { | ||||||
3517 | return isa<CXXThisExpr>( | ||||||
3518 | cast<MemberExpr>( | ||||||
3519 | StackComponents.back().getAssociatedExpression()) | ||||||
3520 | ->getBase() | ||||||
3521 | ->IgnoreParens()); | ||||||
3522 | })) { | ||||||
3523 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] | ||||||
3524 | // A bit-field cannot appear in a map clause. | ||||||
3525 | // | ||||||
3526 | if (FD->isBitField()) | ||||||
3527 | return; | ||||||
3528 | |||||||
3529 | // Check to see if the member expression is referencing a class that | ||||||
3530 | // has already been explicitly mapped | ||||||
3531 | if (Stack->isClassPreviouslyMapped(TE->getType())) | ||||||
3532 | return; | ||||||
3533 | |||||||
3534 | OpenMPDefaultmapClauseModifier Modifier = | ||||||
3535 | Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); | ||||||
3536 | OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( | ||||||
3537 | Modifier, /*IsAggregateOrDeclareTarget*/ true); | ||||||
3538 | ImplicitMap[Kind].emplace_back(E); | ||||||
3539 | return; | ||||||
3540 | } | ||||||
3541 | |||||||
3542 | SourceLocation ELoc = E->getExprLoc(); | ||||||
3543 | // OpenMP [2.9.3.6, Restrictions, p.2] | ||||||
3544 | // A list item that appears in a reduction clause of the innermost | ||||||
3545 | // enclosing worksharing or parallel construct may not be accessed in | ||||||
3546 | // an explicit task. | ||||||
3547 | DVar = Stack->hasInnermostDSA( | ||||||
3548 | FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, | ||||||
3549 | [](OpenMPDirectiveKind K) { | ||||||
3550 | return isOpenMPParallelDirective(K) || | ||||||
3551 | isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); | ||||||
3552 | }, | ||||||
3553 | /*FromParent=*/true); | ||||||
3554 | if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { | ||||||
3555 | ErrorFound = true; | ||||||
3556 | SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); | ||||||
3557 | reportOriginalDsa(SemaRef, Stack, FD, DVar); | ||||||
3558 | return; | ||||||
3559 | } | ||||||
3560 | |||||||
3561 | // Define implicit data-sharing attributes for task. | ||||||
3562 | DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); | ||||||
3563 | if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && | ||||||
3564 | !Stack->isLoopControlVariable(FD).first) { | ||||||
3565 | // Check if there is a captured expression for the current field in the | ||||||
3566 | // region. Do not mark it as firstprivate unless there is no captured | ||||||
3567 | // expression. | ||||||
3568 | // TODO: try to make it firstprivate. | ||||||
3569 | if (DVar.CKind != OMPC_unknown) | ||||||
3570 | ImplicitFirstprivate.push_back(E); | ||||||
3571 | } | ||||||
3572 | return; | ||||||
3573 | } | ||||||
3574 | if (isOpenMPTargetExecutionDirective(DKind)) { | ||||||
3575 | OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; | ||||||
3576 | if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, | ||||||
3577 | /*NoDiagnose=*/true)) | ||||||
3578 | return; | ||||||
3579 | const auto *VD = cast<ValueDecl>( | ||||||
3580 | CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); | ||||||
3581 | if (!Stack->checkMappableExprComponentListsForDecl( | ||||||
3582 | VD, /*CurrentRegionOnly=*/true, | ||||||
3583 | [&CurComponents]( | ||||||
3584 | OMPClauseMappableExprCommon::MappableExprComponentListRef | ||||||
3585 | StackComponents, | ||||||
3586 | OpenMPClauseKind) { | ||||||
3587 | auto CCI = CurComponents.rbegin(); | ||||||
3588 | auto CCE = CurComponents.rend(); | ||||||
3589 | for (const auto &SC : llvm::reverse(StackComponents)) { | ||||||
3590 | // Do both expressions have the same kind? | ||||||
3591 | if (CCI->getAssociatedExpression()->getStmtClass() != | ||||||
3592 | SC.getAssociatedExpression()->getStmtClass()) | ||||||
3593 | if (!((isa<OMPArraySectionExpr>( | ||||||
3594 | SC.getAssociatedExpression()) || | ||||||
3595 | isa<OMPArrayShapingExpr>( | ||||||
3596 | SC.getAssociatedExpression())) && | ||||||
3597 | isa<ArraySubscriptExpr>( | ||||||
3598 | CCI->getAssociatedExpression()))) | ||||||
3599 | return false; | ||||||
3600 | |||||||
3601 | const Decl *CCD = CCI->getAssociatedDeclaration(); | ||||||
3602 | const Decl *SCD = SC.getAssociatedDeclaration(); | ||||||
3603 | CCD = CCD ? CCD->getCanonicalDecl() : nullptr; | ||||||
3604 | SCD = SCD ? SCD->getCanonicalDecl() : nullptr; | ||||||
3605 | if (SCD != CCD) | ||||||
3606 | return false; | ||||||
3607 | std::advance(CCI, 1); | ||||||
3608 | if (CCI == CCE) | ||||||
3609 | break; | ||||||
3610 | } | ||||||
3611 | return true; | ||||||
3612 | })) { | ||||||
3613 | Visit(E->getBase()); | ||||||
3614 | } | ||||||
3615 | } else if (!TryCaptureCXXThisMembers) { | ||||||
3616 | Visit(E->getBase()); | ||||||
3617 | } | ||||||
3618 | } | ||||||
3619 | void VisitOMPExecutableDirective(OMPExecutableDirective *S) { | ||||||
3620 | for (OMPClause *C : S->clauses()) { | ||||||
3621 | // Skip analysis of arguments of implicitly defined firstprivate clause | ||||||
3622 | // for task|target directives. | ||||||
3623 | // Skip analysis of arguments of implicitly defined map clause for target | ||||||
3624 | // directives. | ||||||
3625 | if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && | ||||||
3626 | C->isImplicit())) { | ||||||
3627 | for (Stmt *CC : C->children()) { | ||||||
3628 | if (CC) | ||||||
3629 | Visit(CC); | ||||||
3630 | } | ||||||
3631 | } | ||||||
3632 | } | ||||||
3633 | // Check implicitly captured variables. | ||||||
3634 | VisitSubCaptures(S); | ||||||
3635 | } | ||||||
3636 | void VisitStmt(Stmt *S) { | ||||||
3637 | for (Stmt *C : S->children()) { | ||||||
3638 | if (C) { | ||||||
3639 | // Check implicitly captured variables in the task-based directives to | ||||||
3640 | // check if they must be firstprivatized. | ||||||
3641 | Visit(C); | ||||||
3642 | } | ||||||
3643 | } | ||||||
3644 | } | ||||||
3645 | |||||||
3646 | void visitSubCaptures(CapturedStmt *S) { | ||||||
3647 | for (const CapturedStmt::Capture &Cap : S->captures()) { | ||||||
3648 | if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) | ||||||
3649 | continue; | ||||||
3650 | VarDecl *VD = Cap.getCapturedVar(); | ||||||
3651 | // Do not try to map the variable if it or its sub-component was mapped | ||||||
3652 | // already. | ||||||
3653 | if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && | ||||||
3654 | Stack->checkMappableExprComponentListsForDecl( | ||||||
3655 | VD, /*CurrentRegionOnly=*/true, | ||||||
3656 | [](OMPClauseMappableExprCommon::MappableExprComponentListRef, | ||||||
3657 | OpenMPClauseKind) { return true; })) | ||||||
3658 | continue; | ||||||
3659 | DeclRefExpr *DRE = buildDeclRefExpr( | ||||||
3660 | SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), | ||||||
3661 | Cap.getLocation(), /*RefersToCapture=*/true); | ||||||
3662 | Visit(DRE); | ||||||
3663 | } | ||||||
3664 | } | ||||||
3665 | bool isErrorFound() const { return ErrorFound; } | ||||||
3666 | ArrayRef<Expr *> getImplicitFirstprivate() const { | ||||||
3667 | return ImplicitFirstprivate; | ||||||
3668 | } | ||||||
3669 | ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const { | ||||||
3670 | return ImplicitMap[Kind]; | ||||||
3671 | } | ||||||
3672 | const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { | ||||||
3673 | return VarsWithInheritedDSA; | ||||||
3674 | } | ||||||
3675 | |||||||
3676 | DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) | ||||||
3677 | : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { | ||||||
3678 | // Process declare target link variables for the target directives. | ||||||
3679 | if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { | ||||||
3680 | for (DeclRefExpr *E : Stack->getLinkGlobals()) | ||||||
3681 | Visit(E); | ||||||
3682 | } | ||||||
3683 | } | ||||||
3684 | }; | ||||||
3685 | } // namespace | ||||||
3686 | |||||||
3687 | void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { | ||||||
3688 | switch (DKind) { | ||||||
3689 | case OMPD_parallel: | ||||||
3690 | case OMPD_parallel_for: | ||||||
3691 | case OMPD_parallel_for_simd: | ||||||
3692 | case OMPD_parallel_sections: | ||||||
3693 | case OMPD_parallel_master: | ||||||
3694 | case OMPD_teams: | ||||||
3695 | case OMPD_teams_distribute: | ||||||
3696 | case OMPD_teams_distribute_simd: { | ||||||
3697 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); | ||||||
3698 | QualType KmpInt32PtrTy = | ||||||
3699 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); | ||||||
3700 | Sema::CapturedParamNameType Params[] = { | ||||||
3701 | std::make_pair(".global_tid.", KmpInt32PtrTy), | ||||||
3702 | std::make_pair(".bound_tid.", KmpInt32PtrTy), | ||||||
3703 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||
3704 | }; | ||||||
3705 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||
3706 | Params); | ||||||
3707 | break; | ||||||
3708 | } | ||||||
3709 | case OMPD_target_teams: | ||||||
3710 | case OMPD_target_parallel: | ||||||
3711 | case OMPD_target_parallel_for: | ||||||
3712 | case OMPD_target_parallel_for_simd: | ||||||
3713 | case OMPD_target_teams_distribute: | ||||||
3714 | case OMPD_target_teams_distribute_simd: { | ||||||
3715 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); | ||||||
3716 | QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); | ||||||
3717 | QualType KmpInt32PtrTy = | ||||||
3718 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); | ||||||
3719 | QualType Args[] = {VoidPtrTy}; | ||||||
3720 | FunctionProtoType::ExtProtoInfo EPI; | ||||||
3721 | EPI.Variadic = true; | ||||||
3722 | QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); | ||||||
3723 | Sema::CapturedParamNameType Params[] = { | ||||||
3724 | std::make_pair(".global_tid.", KmpInt32Ty), | ||||||
3725 | std::make_pair(".part_id.", KmpInt32PtrTy), | ||||||
3726 | std::make_pair(".privates.", VoidPtrTy), | ||||||
3727 | std::make_pair( | ||||||
3728 | ".copy_fn.", | ||||||
3729 | Context.getPointerType(CopyFnType).withConst().withRestrict()), | ||||||
3730 | std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), | ||||||
3731 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||
3732 | }; | ||||||
3733 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||
3734 | Params, /*OpenMPCaptureLevel=*/0); | ||||||
3735 | // Mark this captured region as inlined, because we don't use outlined | ||||||
3736 | // function directly. | ||||||
3737 | getCurCapturedRegion()->TheCapturedDecl->addAttr( | ||||||
3738 | AlwaysInlineAttr::CreateImplicit( | ||||||
3739 | Context, {}, AttributeCommonInfo::AS_Keyword, | ||||||
3740 | AlwaysInlineAttr::Keyword_forceinline)); | ||||||
3741 | Sema::CapturedParamNameType ParamsTarget[] = { | ||||||
3742 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||
3743 | }; | ||||||
3744 | // Start a captured region for 'target' with no implicit parameters. | ||||||
3745 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||
3746 | ParamsTarget, /*OpenMPCaptureLevel=*/1); | ||||||
3747 | Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { | ||||||
3748 | std::make_pair(".global_tid.", KmpInt32PtrTy), | ||||||
3749 | std::make_pair(".bound_tid.", KmpInt32PtrTy), | ||||||
3750 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||
3751 | }; | ||||||
3752 | // Start a captured region for 'teams' or 'parallel'. Both regions have | ||||||
3753 | // the same implicit parameters. | ||||||
3754 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||
3755 | ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); | ||||||
3756 | break; | ||||||
3757 | } | ||||||
3758 | case OMPD_target: | ||||||
3759 | case OMPD_target_simd: { | ||||||
3760 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); | ||||||
3761 | QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); | ||||||
3762 | QualType KmpInt32PtrTy = | ||||||
3763 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); | ||||||
3764 | QualType Args[] = {VoidPtrTy}; | ||||||
3765 | FunctionProtoType::ExtProtoInfo EPI; | ||||||
3766 | EPI.Variadic = true; | ||||||
3767 | QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); | ||||||
3768 | Sema::CapturedParamNameType Params[] = { | ||||||
3769 | std::make_pair(".global_tid.", KmpInt32Ty), | ||||||
3770 | std::make_pair(".part_id.", KmpInt32PtrTy), | ||||||
3771 | std::make_pair(".privates.", VoidPtrTy), | ||||||
3772 | std::make_pair( | ||||||
3773 | ".copy_fn.", | ||||||
3774 | Context.getPointerType(CopyFnType).withConst().withRestrict()), | ||||||
3775 | std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), | ||||||
3776 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||
3777 | }; | ||||||
3778 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||
3779 | Params, /*OpenMPCaptureLevel=*/0); | ||||||
3780 | // Mark this captured region as inlined, because we don't use outlined | ||||||
3781 | // function directly. | ||||||
3782 | getCurCapturedRegion()->TheCapturedDecl->addAttr( | ||||||
3783 | AlwaysInlineAttr::CreateImplicit( | ||||||
3784 | Context, {}, AttributeCommonInfo::AS_Keyword, | ||||||
3785 | AlwaysInlineAttr::Keyword_forceinline)); | ||||||
3786 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||
3787 | std::make_pair(StringRef(), QualType()), | ||||||
3788 | /*OpenMPCaptureLevel=*/1); | ||||||
3789 | break; | ||||||
3790 | } | ||||||
3791 | case OMPD_simd: | ||||||
3792 | case OMPD_for: | ||||||
3793 | case OMPD_for_simd: | ||||||
3794 | case OMPD_sections: | ||||||
3795 | case OMPD_section: | ||||||
3796 | case OMPD_single: | ||||||
3797 | case OMPD_master: | ||||||
3798 | case OMPD_critical: | ||||||
3799 | case OMPD_taskgroup: | ||||||
3800 | case OMPD_distribute: | ||||||
3801 | case OMPD_distribute_simd: | ||||||
3802 | case OMPD_ordered: | ||||||
3803 | case OMPD_atomic: | ||||||
3804 | case OMPD_target_data: { | ||||||
3805 | Sema::CapturedParamNameType Params[] = { | ||||||
3806 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||
3807 | }; | ||||||
3808 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||
3809 | Params); | ||||||
3810 | break; | ||||||
3811 | } | ||||||
3812 | case OMPD_task: { | ||||||
3813 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); | ||||||
3814 | QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); | ||||||
3815 | QualType KmpInt32PtrTy = | ||||||
3816 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); | ||||||
3817 | QualType Args[] = {VoidPtrTy}; | ||||||
3818 | FunctionProtoType::ExtProtoInfo EPI; | ||||||
3819 | EPI.Variadic = true; | ||||||
3820 | QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); | ||||||
3821 | Sema::CapturedParamNameType Params[] = { | ||||||
3822 | std::make_pair(".global_tid.", KmpInt32Ty), | ||||||
3823 | std::make_pair(".part_id.", KmpInt32PtrTy), | ||||||
3824 | std::make_pair(".privates.", VoidPtrTy), | ||||||
3825 | std::make_pair( | ||||||
3826 | ".copy_fn.", | ||||||
3827 | Context.getPointerType(CopyFnType).withConst().withRestrict()), | ||||||
3828 | std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), | ||||||
3829 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||
3830 | }; | ||||||
3831 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||
3832 | Params); | ||||||
3833 | // Mark this captured region as inlined, because we don't use outlined | ||||||
3834 | // function directly. | ||||||
3835 | getCurCapturedRegion()->TheCapturedDecl->addAttr( | ||||||
3836 | AlwaysInlineAttr::CreateImplicit( | ||||||
3837 | Context, {}, AttributeCommonInfo::AS_Keyword, | ||||||
3838 | AlwaysInlineAttr::Keyword_forceinline)); | ||||||
3839 | break; | ||||||
3840 | } | ||||||
3841 | case OMPD_taskloop: | ||||||
3842 | case OMPD_taskloop_simd: | ||||||
3843 | case OMPD_master_taskloop: | ||||||
3844 | case OMPD_master_taskloop_simd: { | ||||||
3845 | QualType KmpInt32Ty = | ||||||
3846 | Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) | ||||||
3847 | .withConst(); | ||||||
3848 | QualType KmpUInt64Ty = | ||||||
3849 | Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) | ||||||
3850 | .withConst(); | ||||||
3851 | QualType KmpInt64Ty = | ||||||
3852 | Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) | ||||||
3853 | .withConst(); | ||||||
3854 | QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); | ||||||
3855 | QualType KmpInt32PtrTy = | ||||||
3856 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); | ||||||
3857 | QualType Args[] = {VoidPtrTy}; | ||||||
3858 | FunctionProtoType::ExtProtoInfo EPI; | ||||||
3859 | EPI.Variadic = true; | ||||||
3860 | QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); | ||||||
3861 | Sema::CapturedParamNameType Params[] = { | ||||||
3862 | std::make_pair(".global_tid.", KmpInt32Ty), | ||||||
3863 | std::make_pair(".part_id.", KmpInt32PtrTy), | ||||||
3864 | std::make_pair(".privates.", VoidPtrTy), | ||||||
3865 | std::make_pair( | ||||||
3866 | ".copy_fn.", | ||||||
3867 | Context.getPointerType(CopyFnType).withConst().withRestrict()), | ||||||
3868 | std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), | ||||||
3869 | std::make_pair(".lb.", KmpUInt64Ty), | ||||||
3870 | std::make_pair(".ub.", KmpUInt64Ty), | ||||||
3871 | std::make_pair(".st.", KmpInt64Ty), | ||||||
3872 | std::make_pair(".liter.", KmpInt32Ty), | ||||||
3873 | std::make_pair(".reductions.", VoidPtrTy), | ||||||
3874 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||
3875 | }; | ||||||
3876 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||
3877 | Params); | ||||||
3878 | // Mark this captured region as inlined, because we don't use outlined | ||||||
3879 | // function directly. | ||||||
3880 | getCurCapturedRegion()->TheCapturedDecl->addAttr( | ||||||
3881 | AlwaysInlineAttr::CreateImplicit( | ||||||
3882 | Context, {}, AttributeCommonInfo::AS_Keyword, | ||||||
3883 | AlwaysInlineAttr::Keyword_forceinline)); | ||||||
3884 | break; | ||||||
3885 | } | ||||||
3886 | case OMPD_parallel_master_taskloop: | ||||||
3887 | case OMPD_parallel_master_taskloop_simd: { | ||||||
3888 | QualType KmpInt32Ty = | ||||||
3889 | Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) | ||||||
3890 | .withConst(); | ||||||
3891 | QualType KmpUInt64Ty = | ||||||
3892 | Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) | ||||||
3893 | .withConst(); | ||||||
3894 | QualType KmpInt64Ty = | ||||||
3895 | Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) | ||||||
3896 | .withConst(); | ||||||
3897 | QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); | ||||||
3898 | QualType KmpInt32PtrTy = | ||||||
3899 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); | ||||||
3900 | Sema::CapturedParamNameType ParamsParallel[] = { | ||||||
3901 | std::make_pair(".global_tid.", KmpInt32PtrTy), | ||||||
3902 | std::make_pair(".bound_tid.", KmpInt32PtrTy), | ||||||
3903 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||
3904 | }; | ||||||
3905 | // Start a captured region for 'parallel'. | ||||||
3906 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||
3907 | ParamsParallel, /*OpenMPCaptureLevel=*/0); | ||||||
3908 | QualType Args[] = {VoidPtrTy}; | ||||||
3909 | FunctionProtoType::ExtProtoInfo EPI; | ||||||
3910 | EPI.Variadic = true; | ||||||
3911 | QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); | ||||||
3912 | Sema::CapturedParamNameType Params[] = { | ||||||
3913 | std::make_pair(".global_tid.", KmpInt32Ty), | ||||||
3914 | std::make_pair(".part_id.", KmpInt32PtrTy), | ||||||
3915 | std::make_pair(".privates.", VoidPtrTy), | ||||||
3916 | std::make_pair( | ||||||
3917 | ".copy_fn.", | ||||||
3918 | Context.getPointerType(CopyFnType).withConst().withRestrict()), | ||||||
3919 | std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), | ||||||
3920 | std::make_pair(".lb.", KmpUInt64Ty), | ||||||
3921 | std::make_pair(".ub.", KmpUInt64Ty), | ||||||
3922 | std::make_pair(".st.", KmpInt64Ty), | ||||||
3923 | std::make_pair(".liter.", KmpInt32Ty), | ||||||
3924 | std::make_pair(".reductions.", VoidPtrTy), | ||||||
3925 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||
3926 | }; | ||||||
3927 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||
3928 | Params, /*OpenMPCaptureLevel=*/1); | ||||||
3929 | // Mark this captured region as inlined, because we don't use outlined | ||||||
3930 | // function directly. | ||||||
3931 | getCurCapturedRegion()->TheCapturedDecl->addAttr( | ||||||
3932 | AlwaysInlineAttr::CreateImplicit( | ||||||
3933 | Context, {}, AttributeCommonInfo::AS_Keyword, | ||||||
3934 | AlwaysInlineAttr::Keyword_forceinline)); | ||||||
3935 | break; | ||||||
3936 | } | ||||||
3937 | case OMPD_distribute_parallel_for_simd: | ||||||
3938 | case OMPD_distribute_parallel_for: { | ||||||
3939 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); | ||||||
3940 | QualType KmpInt32PtrTy = | ||||||
3941 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); | ||||||
3942 | Sema::CapturedParamNameType Params[] = { | ||||||
3943 | std::make_pair(".global_tid.", KmpInt32PtrTy), | ||||||
3944 | std::make_pair(".bound_tid.", KmpInt32PtrTy), | ||||||
3945 | std::make_pair(".previous.lb.", Context.getSizeType().withConst()), | ||||||
3946 | std::make_pair(".previous.ub.", Context.getSizeType().withConst()), | ||||||
3947 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||
3948 | }; | ||||||
3949 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||
3950 | Params); | ||||||
3951 | break; | ||||||
3952 | } | ||||||
3953 | case OMPD_target_teams_distribute_parallel_for: | ||||||
3954 | case OMPD_target_teams_distribute_parallel_for_simd: { | ||||||
3955 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); | ||||||
3956 | QualType KmpInt32PtrTy = | ||||||
3957 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); | ||||||
3958 | QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); | ||||||
3959 | |||||||
3960 | QualType Args[] = {VoidPtrTy}; | ||||||
3961 | FunctionProtoType::ExtProtoInfo EPI; | ||||||
3962 | EPI.Variadic = true; | ||||||
3963 | QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); | ||||||
3964 | Sema::CapturedParamNameType Params[] = { | ||||||
3965 | std::make_pair(".global_tid.", KmpInt32Ty), | ||||||
3966 | std::make_pair(".part_id.", KmpInt32PtrTy), | ||||||
3967 | std::make_pair(".privates.", VoidPtrTy), | ||||||
3968 | std::make_pair( | ||||||
3969 | ".copy_fn.", | ||||||
3970 | Context.getPointerType(CopyFnType).withConst().withRestrict()), | ||||||
3971 | std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), | ||||||
3972 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||
3973 | }; | ||||||
3974 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||
3975 | Params, /*OpenMPCaptureLevel=*/0); | ||||||
3976 | // Mark this captured region as inlined, because we don't use outlined | ||||||
3977 | // function directly. | ||||||
3978 | getCurCapturedRegion()->TheCapturedDecl->addAttr( | ||||||
3979 | AlwaysInlineAttr::CreateImplicit( | ||||||
3980 | Context, {}, AttributeCommonInfo::AS_Keyword, | ||||||
3981 | AlwaysInlineAttr::Keyword_forceinline)); | ||||||
3982 | Sema::CapturedParamNameType ParamsTarget[] = { | ||||||
3983 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||
3984 | }; | ||||||
3985 | // Start a captured region for 'target' with no implicit parameters. | ||||||
3986 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||
3987 | ParamsTarget, /*OpenMPCaptureLevel=*/1); | ||||||
3988 | |||||||
3989 | Sema::CapturedParamNameType ParamsTeams[] = { | ||||||
3990 | std::make_pair(".global_tid.", KmpInt32PtrTy), | ||||||
3991 | std::make_pair(".bound_tid.", KmpInt32PtrTy), | ||||||
3992 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||
3993 | }; | ||||||
3994 | // Start a captured region for 'target' with no implicit parameters. | ||||||
3995 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||
3996 | ParamsTeams, /*OpenMPCaptureLevel=*/2); | ||||||
3997 | |||||||
3998 | Sema::CapturedParamNameType ParamsParallel[] = { | ||||||
3999 | std::make_pair(".global_tid.", KmpInt32PtrTy), | ||||||
4000 | std::make_pair(".bound_tid.", KmpInt32PtrTy), | ||||||
4001 | std::make_pair(".previous.lb.", Context.getSizeType().withConst()), | ||||||
4002 | std::make_pair(".previous.ub.", Context.getSizeType().withConst()), | ||||||
4003 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||
4004 | }; | ||||||
4005 | // Start a captured region for 'teams' or 'parallel'. Both regions have | ||||||
4006 | // the same implicit parameters. | ||||||
4007 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||
4008 | ParamsParallel, /*OpenMPCaptureLevel=*/3); | ||||||
4009 | break; | ||||||
4010 | } | ||||||
4011 | |||||||
4012 | case OMPD_teams_distribute_parallel_for: | ||||||
4013 | case OMPD_teams_distribute_parallel_for_simd: { | ||||||
4014 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); | ||||||
4015 | QualType KmpInt32PtrTy = | ||||||
4016 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); | ||||||
4017 | |||||||
4018 | Sema::CapturedParamNameType ParamsTeams[] = { | ||||||
4019 | std::make_pair(".global_tid.", KmpInt32PtrTy), | ||||||
4020 | std::make_pair(".bound_tid.", KmpInt32PtrTy), | ||||||
4021 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||
4022 | }; | ||||||
4023 | // Start a captured region for 'target' with no implicit parameters. | ||||||
4024 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||
4025 | ParamsTeams, /*OpenMPCaptureLevel=*/0); | ||||||
4026 | |||||||
4027 | Sema::CapturedParamNameType ParamsParallel[] = { | ||||||
4028 | std::make_pair(".global_tid.", KmpInt32PtrTy), | ||||||
4029 | std::make_pair(".bound_tid.", KmpInt32PtrTy), | ||||||
4030 | std::make_pair(".previous.lb.", Context.getSizeType().withConst()), | ||||||
4031 | std::make_pair(".previous.ub.", Context.getSizeType().withConst()), | ||||||
4032 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||
4033 | }; | ||||||
4034 | // Start a captured region for 'teams' or 'parallel'. Both regions have | ||||||
4035 | // the same implicit parameters. | ||||||
4036 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||
4037 | ParamsParallel, /*OpenMPCaptureLevel=*/1); | ||||||
4038 | break; | ||||||
4039 | } | ||||||
4040 | case OMPD_target_update: | ||||||
4041 | case OMPD_target_enter_data: | ||||||
4042 | case OMPD_target_exit_data: { | ||||||
4043 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); | ||||||
4044 | QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); | ||||||
4045 | QualType KmpInt32PtrTy = | ||||||
4046 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); | ||||||
4047 | QualType Args[] = {VoidPtrTy}; | ||||||
4048 | FunctionProtoType::ExtProtoInfo EPI; | ||||||
4049 | EPI.Variadic = true; | ||||||
4050 | QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); | ||||||
4051 | Sema::CapturedParamNameType Params[] = { | ||||||
4052 | std::make_pair(".global_tid.", KmpInt32Ty), | ||||||
4053 | std::make_pair(".part_id.", KmpInt32PtrTy), | ||||||
4054 | std::make_pair(".privates.", VoidPtrTy), | ||||||
4055 | std::make_pair( | ||||||
4056 | ".copy_fn.", | ||||||
4057 | Context.getPointerType(CopyFnType).withConst().withRestrict()), | ||||||
4058 | std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), | ||||||
4059 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||||
4060 | }; | ||||||
4061 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | ||||||
4062 | Params); | ||||||
4063 | // Mark this captured region as inlined, because we don't use outlined | ||||||
4064 | // function directly. | ||||||
4065 | getCurCapturedRegion()->TheCapturedDecl->addAttr( | ||||||
4066 | AlwaysInlineAttr::CreateImplicit( | ||||||
4067 | Context, {}, AttributeCommonInfo::AS_Keyword, | ||||||
4068 | AlwaysInlineAttr::Keyword_forceinline)); | ||||||
4069 | break; | ||||||
4070 | } | ||||||
4071 | case OMPD_threadprivate: | ||||||
4072 | case OMPD_allocate: | ||||||
4073 | case OMPD_taskyield: | ||||||
4074 | case OMPD_barrier: | ||||||
4075 | case OMPD_taskwait: | ||||||
4076 | case OMPD_cancellation_point: | ||||||
4077 | case OMPD_cancel: | ||||||
4078 | case OMPD_flush: | ||||||
4079 | case OMPD_depobj: | ||||||
4080 | case OMPD_scan: | ||||||
4081 | case OMPD_declare_reduction: | ||||||
4082 | case OMPD_declare_mapper: | ||||||
4083 | case OMPD_declare_simd: | ||||||
4084 | case OMPD_declare_target: | ||||||
4085 | case OMPD_end_declare_target: | ||||||
4086 | case OMPD_requires: | ||||||
4087 | case OMPD_declare_variant: | ||||||
4088 | case OMPD_begin_declare_variant: | ||||||
4089 | case OMPD_end_declare_variant: | ||||||
4090 | llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 4090); | ||||||
4091 | case OMPD_unknown: | ||||||
4092 | default: | ||||||
4093 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 4093); | ||||||
4094 | } | ||||||
4095 | } | ||||||
4096 | |||||||
4097 | int Sema::getNumberOfConstructScopes(unsigned Level) const { | ||||||
4098 | return getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDirective(Level)); | ||||||
4099 | } | ||||||
4100 | |||||||
4101 | int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { | ||||||
4102 | SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; | ||||||
4103 | getOpenMPCaptureRegions(CaptureRegions, DKind); | ||||||
4104 | return CaptureRegions.size(); | ||||||
4105 | } | ||||||
4106 | |||||||
4107 | static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, | ||||||
4108 | Expr *CaptureExpr, bool WithInit, | ||||||
4109 | bool AsExpression) { | ||||||
4110 | assert(CaptureExpr)((CaptureExpr) ? static_cast<void> (0) : __assert_fail ( "CaptureExpr", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 4110, __PRETTY_FUNCTION__)); | ||||||
4111 | ASTContext &C = S.getASTContext(); | ||||||
4112 | Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); | ||||||
4113 | QualType Ty = Init->getType(); | ||||||
4114 | if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { | ||||||
4115 | if (S.getLangOpts().CPlusPlus) { | ||||||
4116 | Ty = C.getLValueReferenceType(Ty); | ||||||
4117 | } else { | ||||||
4118 | Ty = C.getPointerType(Ty); | ||||||
4119 | ExprResult Res = | ||||||
4120 | S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); | ||||||
4121 | if (!Res.isUsable()) | ||||||
4122 | return nullptr; | ||||||
4123 | Init = Res.get(); | ||||||
4124 | } | ||||||
4125 | WithInit = true; | ||||||
4126 | } | ||||||
4127 | auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, | ||||||
4128 | CaptureExpr->getBeginLoc()); | ||||||
4129 | if (!WithInit) | ||||||
4130 | CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); | ||||||
4131 | S.CurContext->addHiddenDecl(CED); | ||||||
4132 | S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); | ||||||
4133 | return CED; | ||||||
4134 | } | ||||||
4135 | |||||||
4136 | static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, | ||||||
4137 | bool WithInit) { | ||||||
4138 | OMPCapturedExprDecl *CD; | ||||||
4139 | if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) | ||||||
4140 | CD = cast<OMPCapturedExprDecl>(VD); | ||||||
4141 | else | ||||||
4142 | CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, | ||||||
4143 | /*AsExpression=*/false); | ||||||
4144 | return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), | ||||||
4145 | CaptureExpr->getExprLoc()); | ||||||
4146 | } | ||||||
4147 | |||||||
4148 | static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { | ||||||
4149 | CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); | ||||||
4150 | if (!Ref) { | ||||||
4151 | OMPCapturedExprDecl *CD = buildCaptureDecl( | ||||||
4152 | S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, | ||||||
4153 | /*WithInit=*/true, /*AsExpression=*/true); | ||||||
4154 | Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), | ||||||
4155 | CaptureExpr->getExprLoc()); | ||||||
4156 | } | ||||||
4157 | ExprResult Res = Ref; | ||||||
4158 | if (!S.getLangOpts().CPlusPlus && | ||||||
4159 | CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && | ||||||
4160 | Ref->getType()->isPointerType()) { | ||||||
4161 | Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); | ||||||
4162 | if (!Res.isUsable()) | ||||||
4163 | return ExprError(); | ||||||
4164 | } | ||||||
4165 | return S.DefaultLvalueConversion(Res.get()); | ||||||
4166 | } | ||||||
4167 | |||||||
4168 | namespace { | ||||||
4169 | // OpenMP directives parsed in this section are represented as a | ||||||
4170 | // CapturedStatement with an associated statement. If a syntax error | ||||||
4171 | // is detected during the parsing of the associated statement, the | ||||||
4172 | // compiler must abort processing and close the CapturedStatement. | ||||||
4173 | // | ||||||
4174 | // Combined directives such as 'target parallel' have more than one | ||||||
4175 | // nested CapturedStatements. This RAII ensures that we unwind out | ||||||
4176 | // of all the nested CapturedStatements when an error is found. | ||||||
4177 | class CaptureRegionUnwinderRAII { | ||||||
4178 | private: | ||||||
4179 | Sema &S; | ||||||
4180 | bool &ErrorFound; | ||||||
4181 | OpenMPDirectiveKind DKind = OMPD_unknown; | ||||||
4182 | |||||||
4183 | public: | ||||||
4184 | CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, | ||||||
4185 | OpenMPDirectiveKind DKind) | ||||||
4186 | : S(S), ErrorFound(ErrorFound), DKind(DKind) {} | ||||||
4187 | ~CaptureRegionUnwinderRAII() { | ||||||
4188 | if (ErrorFound) { | ||||||
4189 | int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); | ||||||
4190 | while (--ThisCaptureLevel >= 0) | ||||||
4191 | S.ActOnCapturedRegionError(); | ||||||
4192 | } | ||||||
4193 | } | ||||||
4194 | }; | ||||||
4195 | } // namespace | ||||||
4196 | |||||||
4197 | void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { | ||||||
4198 | // Capture variables captured by reference in lambdas for target-based | ||||||
4199 | // directives. | ||||||
4200 | if (!CurContext->isDependentContext() && | ||||||
4201 | (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()) || | ||||||
4202 | isOpenMPTargetDataManagementDirective( | ||||||
4203 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()))) { | ||||||
4204 | QualType Type = V->getType(); | ||||||
4205 | if (const auto *RD = Type.getCanonicalType() | ||||||
4206 | .getNonReferenceType() | ||||||
4207 | ->getAsCXXRecordDecl()) { | ||||||
4208 | bool SavedForceCaptureByReferenceInTargetExecutable = | ||||||
4209 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isForceCaptureByReferenceInTargetExecutable(); | ||||||
4210 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setForceCaptureByReferenceInTargetExecutable( | ||||||
4211 | /*V=*/true); | ||||||
4212 | if (RD->isLambda()) { | ||||||
4213 | llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; | ||||||
4214 | FieldDecl *ThisCapture; | ||||||
4215 | RD->getCaptureFields(Captures, ThisCapture); | ||||||
4216 | for (const LambdaCapture &LC : RD->captures()) { | ||||||
4217 | if (LC.getCaptureKind() == LCK_ByRef) { | ||||||
4218 | VarDecl *VD = LC.getCapturedVar(); | ||||||
4219 | DeclContext *VDC = VD->getDeclContext(); | ||||||
4220 | if (!VDC->Encloses(CurContext)) | ||||||
4221 | continue; | ||||||
4222 | MarkVariableReferenced(LC.getLocation(), VD); | ||||||
4223 | } else if (LC.getCaptureKind() == LCK_This) { | ||||||
4224 | QualType ThisTy = getCurrentThisType(); | ||||||
4225 | if (!ThisTy.isNull() && | ||||||
4226 | Context.typesAreCompatible(ThisTy, ThisCapture->getType())) | ||||||
4227 | CheckCXXThisCapture(LC.getLocation()); | ||||||
4228 | } | ||||||
4229 | } | ||||||
4230 | } | ||||||
4231 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setForceCaptureByReferenceInTargetExecutable( | ||||||
4232 | SavedForceCaptureByReferenceInTargetExecutable); | ||||||
4233 | } | ||||||
4234 | } | ||||||
4235 | } | ||||||
4236 | |||||||
4237 | static bool checkOrderedOrderSpecified(Sema &S, | ||||||
4238 | const ArrayRef<OMPClause *> Clauses) { | ||||||
4239 | const OMPOrderedClause *Ordered = nullptr; | ||||||
4240 | const OMPOrderClause *Order = nullptr; | ||||||
4241 | |||||||
4242 | for (const OMPClause *Clause : Clauses) { | ||||||
4243 | if (Clause->getClauseKind() == OMPC_ordered) | ||||||
4244 | Ordered = cast<OMPOrderedClause>(Clause); | ||||||
4245 | else if (Clause->getClauseKind() == OMPC_order) { | ||||||
4246 | Order = cast<OMPOrderClause>(Clause); | ||||||
4247 | if (Order->getKind() != OMPC_ORDER_concurrent) | ||||||
4248 | Order = nullptr; | ||||||
4249 | } | ||||||
4250 | if (Ordered && Order) | ||||||
4251 | break; | ||||||
4252 | } | ||||||
4253 | |||||||
4254 | if (Ordered && Order) { | ||||||
4255 | S.Diag(Order->getKindKwLoc(), | ||||||
4256 | diag::err_omp_simple_clause_incompatible_with_ordered) | ||||||
4257 | << getOpenMPClauseName(OMPC_order) | ||||||
4258 | << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) | ||||||
4259 | << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); | ||||||
4260 | S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) | ||||||
4261 | << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); | ||||||
4262 | return true; | ||||||
4263 | } | ||||||
4264 | return false; | ||||||
4265 | } | ||||||
4266 | |||||||
4267 | StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, | ||||||
4268 | ArrayRef<OMPClause *> Clauses) { | ||||||
4269 | bool ErrorFound = false; | ||||||
4270 | CaptureRegionUnwinderRAII CaptureRegionUnwinder( | ||||||
4271 | *this, ErrorFound, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()); | ||||||
4272 | if (!S.isUsable()) { | ||||||
4273 | ErrorFound = true; | ||||||
4274 | return StmtError(); | ||||||
4275 | } | ||||||
4276 | |||||||
4277 | SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; | ||||||
4278 | getOpenMPCaptureRegions(CaptureRegions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()); | ||||||
4279 | OMPOrderedClause *OC = nullptr; | ||||||
4280 | OMPScheduleClause *SC = nullptr; | ||||||
4281 | SmallVector<const OMPLinearClause *, 4> LCs; | ||||||
4282 | SmallVector<const OMPClauseWithPreInit *, 4> PICs; | ||||||
4283 | // This is required for proper codegen. | ||||||
4284 | for (OMPClause *Clause : Clauses) { | ||||||
4285 | if (!LangOpts.OpenMPSimd && | ||||||
4286 | isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()) && | ||||||
4287 | Clause->getClauseKind() == OMPC_in_reduction) { | ||||||
4288 | // Capture taskgroup task_reduction descriptors inside the tasking regions | ||||||
4289 | // with the corresponding in_reduction items. | ||||||
4290 | auto *IRC = cast<OMPInReductionClause>(Clause); | ||||||
4291 | for (Expr *E : IRC->taskgroup_descriptors()) | ||||||
4292 | if (E) | ||||||
4293 | MarkDeclarationsReferencedInExpr(E); | ||||||
4294 | } | ||||||
4295 | if (isOpenMPPrivate(Clause->getClauseKind()) || | ||||||
4296 | Clause->getClauseKind() == OMPC_copyprivate || | ||||||
4297 | (getLangOpts().OpenMPUseTLS && | ||||||
4298 | getASTContext().getTargetInfo().isTLSSupported() && | ||||||
4299 | Clause->getClauseKind() == OMPC_copyin)) { | ||||||
4300 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); | ||||||
4301 | // Mark all variables in private list clauses as used in inner region. | ||||||
4302 | for (Stmt *VarRef : Clause->children()) { | ||||||
4303 | if (auto *E = cast_or_null<Expr>(VarRef)) { | ||||||
4304 | MarkDeclarationsReferencedInExpr(E); | ||||||
4305 | } | ||||||
4306 | } | ||||||
4307 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setForceVarCapturing(/*V=*/false); | ||||||
4308 | } else if (CaptureRegions.size() > 1 || | ||||||
4309 | CaptureRegions.back() != OMPD_unknown) { | ||||||
4310 | if (auto *C = OMPClauseWithPreInit::get(Clause)) | ||||||
4311 | PICs.push_back(C); | ||||||
4312 | if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { | ||||||
4313 | if (Expr *E = C->getPostUpdateExpr()) | ||||||
4314 | MarkDeclarationsReferencedInExpr(E); | ||||||
4315 | } | ||||||
4316 | } | ||||||
4317 | if (Clause->getClauseKind() == OMPC_schedule) | ||||||
4318 | SC = cast<OMPScheduleClause>(Clause); | ||||||
4319 | else if (Clause->getClauseKind() == OMPC_ordered) | ||||||
4320 | OC = cast<OMPOrderedClause>(Clause); | ||||||
4321 | else if (Clause->getClauseKind() == OMPC_linear) | ||||||
4322 | LCs.push_back(cast<OMPLinearClause>(Clause)); | ||||||
4323 | } | ||||||
4324 | // Capture allocator expressions if used. | ||||||
4325 | for (Expr *E : DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getInnerAllocators()) | ||||||
4326 | MarkDeclarationsReferencedInExpr(E); | ||||||
4327 | // OpenMP, 2.7.1 Loop Construct, Restrictions | ||||||
4328 | // The nonmonotonic modifier cannot be specified if an ordered clause is | ||||||
4329 | // specified. | ||||||
4330 | if (SC && | ||||||
4331 | (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || | ||||||
4332 | SC->getSecondScheduleModifier() == | ||||||
4333 | OMPC_SCHEDULE_MODIFIER_nonmonotonic) && | ||||||
4334 | OC) { | ||||||
4335 | Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic | ||||||
4336 | ? SC->getFirstScheduleModifierLoc() | ||||||
4337 | : SC->getSecondScheduleModifierLoc(), | ||||||
4338 | diag::err_omp_simple_clause_incompatible_with_ordered) | ||||||
4339 | << getOpenMPClauseName(OMPC_schedule) | ||||||
4340 | << getOpenMPSimpleClauseTypeName(OMPC_schedule, | ||||||
4341 | OMPC_SCHEDULE_MODIFIER_nonmonotonic) | ||||||
4342 | << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); | ||||||
4343 | ErrorFound = true; | ||||||
4344 | } | ||||||
4345 | // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. | ||||||
4346 | // If an order(concurrent) clause is present, an ordered clause may not appear | ||||||
4347 | // on the same directive. | ||||||
4348 | if (checkOrderedOrderSpecified(*this, Clauses)) | ||||||
4349 | ErrorFound = true; | ||||||
4350 | if (!LCs.empty() && OC && OC->getNumForLoops()) { | ||||||
4351 | for (const OMPLinearClause *C : LCs) { | ||||||
4352 | Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) | ||||||
4353 | << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); | ||||||
4354 | } | ||||||
4355 | ErrorFound = true; | ||||||
4356 | } | ||||||
4357 | if (isOpenMPWorksharingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()) && | ||||||
4358 | isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()) && OC && | ||||||
4359 | OC->getNumForLoops()) { | ||||||
4360 | Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) | ||||||
4361 | << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()); | ||||||
4362 | ErrorFound = true; | ||||||
4363 | } | ||||||
4364 | if (ErrorFound) { | ||||||
4365 | return StmtError(); | ||||||
4366 | } | ||||||
4367 | StmtResult SR = S; | ||||||
4368 | unsigned CompletedRegions = 0; | ||||||
4369 | for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { | ||||||
4370 | // Mark all variables in private list clauses as used in inner region. | ||||||
4371 | // Required for proper codegen of combined directives. | ||||||
4372 | // TODO: add processing for other clauses. | ||||||
4373 | if (ThisCaptureRegion != OMPD_unknown) { | ||||||
4374 | for (const clang::OMPClauseWithPreInit *C : PICs) { | ||||||
4375 | OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); | ||||||
4376 | // Find the particular capture region for the clause if the | ||||||
4377 | // directive is a combined one with multiple capture regions. | ||||||
4378 | // If the directive is not a combined one, the capture region | ||||||
4379 | // associated with the clause is OMPD_unknown and is generated | ||||||
4380 | // only once. | ||||||
4381 | if (CaptureRegion == ThisCaptureRegion || | ||||||
4382 | CaptureRegion == OMPD_unknown) { | ||||||
4383 | if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { | ||||||
4384 | for (Decl *D : DS->decls()) | ||||||
4385 | MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); | ||||||
4386 | } | ||||||
4387 | } | ||||||
4388 | } | ||||||
4389 | } | ||||||
4390 | if (ThisCaptureRegion == OMPD_target) { | ||||||
4391 | // Capture allocator traits in the target region. They are used implicitly | ||||||
4392 | // and, thus, are not captured by default. | ||||||
4393 | for (OMPClause *C : Clauses) { | ||||||
4394 | if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) { | ||||||
4395 | for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End; | ||||||
4396 | ++I) { | ||||||
4397 | OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I); | ||||||
4398 | if (Expr *E = D.AllocatorTraits) | ||||||
4399 | MarkDeclarationsReferencedInExpr(E); | ||||||
4400 | } | ||||||
4401 | continue; | ||||||
4402 | } | ||||||
4403 | } | ||||||
4404 | } | ||||||
4405 | if (++CompletedRegions == CaptureRegions.size()) | ||||||
4406 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setBodyComplete(); | ||||||
4407 | SR = ActOnCapturedRegionEnd(SR.get()); | ||||||
4408 | } | ||||||
4409 | return SR; | ||||||
4410 | } | ||||||
4411 | |||||||
4412 | static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, | ||||||
4413 | OpenMPDirectiveKind CancelRegion, | ||||||
4414 | SourceLocation StartLoc) { | ||||||
4415 | // CancelRegion is only needed for cancel and cancellation_point. | ||||||
4416 | if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) | ||||||
4417 | return false; | ||||||
4418 | |||||||
4419 | if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || | ||||||
4420 | CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) | ||||||
4421 | return false; | ||||||
4422 | |||||||
4423 | SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) | ||||||
4424 | << getOpenMPDirectiveName(CancelRegion); | ||||||
4425 | return true; | ||||||
4426 | } | ||||||
4427 | |||||||
4428 | static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, | ||||||
4429 | OpenMPDirectiveKind CurrentRegion, | ||||||
4430 | const DeclarationNameInfo &CurrentName, | ||||||
4431 | OpenMPDirectiveKind CancelRegion, | ||||||
4432 | SourceLocation StartLoc) { | ||||||
4433 | if (Stack->getCurScope()) { | ||||||
4434 | OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); | ||||||
4435 | OpenMPDirectiveKind OffendingRegion = ParentRegion; | ||||||
4436 | bool NestingProhibited = false; | ||||||
4437 | bool CloseNesting = true; | ||||||
4438 | bool OrphanSeen = false; | ||||||
4439 | enum { | ||||||
4440 | NoRecommend, | ||||||
4441 | ShouldBeInParallelRegion, | ||||||
4442 | ShouldBeInOrderedRegion, | ||||||
4443 | ShouldBeInTargetRegion, | ||||||
4444 | ShouldBeInTeamsRegion, | ||||||
4445 | ShouldBeInLoopSimdRegion, | ||||||
4446 | } Recommend = NoRecommend; | ||||||
4447 | if (isOpenMPSimdDirective(ParentRegion) && | ||||||
4448 | ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || | ||||||
4449 | (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && | ||||||
4450 | CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic && | ||||||
4451 | CurrentRegion != OMPD_scan))) { | ||||||
4452 | // OpenMP [2.16, Nesting of Regions] | ||||||
4453 | // OpenMP constructs may not be nested inside a simd region. | ||||||
4454 | // OpenMP [2.8.1,simd Construct, Restrictions] | ||||||
4455 | // An ordered construct with the simd clause is the only OpenMP | ||||||
4456 | // construct that can appear in the simd region. | ||||||
4457 | // Allowing a SIMD construct nested in another SIMD construct is an | ||||||
4458 | // extension. The OpenMP 4.5 spec does not allow it. Issue a warning | ||||||
4459 | // message. | ||||||
4460 | // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] | ||||||
4461 | // The only OpenMP constructs that can be encountered during execution of | ||||||
4462 | // a simd region are the atomic construct, the loop construct, the simd | ||||||
4463 | // construct and the ordered construct with the simd clause. | ||||||
4464 | SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) | ||||||
4465 | ? diag::err_omp_prohibited_region_simd | ||||||
4466 | : diag::warn_omp_nesting_simd) | ||||||
4467 | << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); | ||||||
4468 | return CurrentRegion != OMPD_simd; | ||||||
4469 | } | ||||||
4470 | if (ParentRegion == OMPD_atomic) { | ||||||
4471 | // OpenMP [2.16, Nesting of Regions] | ||||||
4472 | // OpenMP constructs may not be nested inside an atomic region. | ||||||
4473 | SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); | ||||||
4474 | return true; | ||||||
4475 | } | ||||||
4476 | if (CurrentRegion == OMPD_section) { | ||||||
4477 | // OpenMP [2.7.2, sections Construct, Restrictions] | ||||||
4478 | // Orphaned section directives are prohibited. That is, the section | ||||||
4479 | // directives must appear within the sections construct and must not be | ||||||
4480 | // encountered elsewhere in the sections region. | ||||||
4481 | if (ParentRegion != OMPD_sections && | ||||||
4482 | ParentRegion != OMPD_parallel_sections) { | ||||||
4483 | SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) | ||||||
4484 | << (ParentRegion != OMPD_unknown) | ||||||
4485 | << getOpenMPDirectiveName(ParentRegion); | ||||||
4486 | return true; | ||||||
4487 | } | ||||||
4488 | return false; | ||||||
4489 | } | ||||||
4490 | // Allow some constructs (except teams and cancellation constructs) to be | ||||||
4491 | // orphaned (they could be used in functions, called from OpenMP regions | ||||||
4492 | // with the required preconditions). | ||||||
4493 | if (ParentRegion == OMPD_unknown && | ||||||
4494 | !isOpenMPNestingTeamsDirective(CurrentRegion) && | ||||||
4495 | CurrentRegion != OMPD_cancellation_point && | ||||||
4496 | CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan) | ||||||
4497 | return false; | ||||||
4498 | if (CurrentRegion == OMPD_cancellation_point || | ||||||
4499 | CurrentRegion == OMPD_cancel) { | ||||||
4500 | // OpenMP [2.16, Nesting of Regions] | ||||||
4501 | // A cancellation point construct for which construct-type-clause is | ||||||
4502 | // taskgroup must be nested inside a task construct. A cancellation | ||||||
4503 | // point construct for which construct-type-clause is not taskgroup must | ||||||
4504 | // be closely nested inside an OpenMP construct that matches the type | ||||||
4505 | // specified in construct-type-clause. | ||||||
4506 | // A cancel construct for which construct-type-clause is taskgroup must be | ||||||
4507 | // nested inside a task construct. A cancel construct for which | ||||||
4508 | // construct-type-clause is not taskgroup must be closely nested inside an | ||||||
4509 | // OpenMP construct that matches the type specified in | ||||||
4510 | // construct-type-clause. | ||||||
4511 | NestingProhibited = | ||||||
4512 | !((CancelRegion == OMPD_parallel && | ||||||
4513 | (ParentRegion == OMPD_parallel || | ||||||
4514 | ParentRegion == OMPD_target_parallel)) || | ||||||
4515 | (CancelRegion == OMPD_for && | ||||||
4516 | (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || | ||||||
4517 | ParentRegion == OMPD_target_parallel_for || | ||||||
4518 | ParentRegion == OMPD_distribute_parallel_for || | ||||||
4519 | ParentRegion == OMPD_teams_distribute_parallel_for || | ||||||
4520 | ParentRegion == OMPD_target_teams_distribute_parallel_for)) || | ||||||
4521 | (CancelRegion == OMPD_taskgroup && | ||||||
4522 | (ParentRegion == OMPD_task || | ||||||
4523 | (SemaRef.getLangOpts().OpenMP >= 50 && | ||||||
4524 | (ParentRegion == OMPD_taskloop || | ||||||
4525 | ParentRegion == OMPD_master_taskloop || | ||||||
4526 | ParentRegion == OMPD_parallel_master_taskloop)))) || | ||||||
4527 | (CancelRegion == OMPD_sections && | ||||||
4528 | (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || | ||||||
4529 | ParentRegion == OMPD_parallel_sections))); | ||||||
4530 | OrphanSeen = ParentRegion == OMPD_unknown; | ||||||
4531 | } else if (CurrentRegion == OMPD_master) { | ||||||
4532 | // OpenMP [2.16, Nesting of Regions] | ||||||
4533 | // A master region may not be closely nested inside a worksharing, | ||||||
4534 | // atomic, or explicit task region. | ||||||
4535 | NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || | ||||||
4536 | isOpenMPTaskingDirective(ParentRegion); | ||||||
4537 | } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { | ||||||
4538 | // OpenMP [2.16, Nesting of Regions] | ||||||
4539 | // A critical region may not be nested (closely or otherwise) inside a | ||||||
4540 | // critical region with the same name. Note that this restriction is not | ||||||
4541 | // sufficient to prevent deadlock. | ||||||
4542 | SourceLocation PreviousCriticalLoc; | ||||||
4543 | bool DeadLock = Stack->hasDirective( | ||||||
4544 | [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, | ||||||
4545 | const DeclarationNameInfo &DNI, | ||||||
4546 | SourceLocation Loc) { | ||||||
4547 | if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { | ||||||
4548 | PreviousCriticalLoc = Loc; | ||||||
4549 | return true; | ||||||
4550 | } | ||||||
4551 | return false; | ||||||
4552 | }, | ||||||
4553 | false /* skip top directive */); | ||||||
4554 | if (DeadLock) { | ||||||
4555 | SemaRef.Diag(StartLoc, | ||||||
4556 | diag::err_omp_prohibited_region_critical_same_name) | ||||||
4557 | << CurrentName.getName(); | ||||||
4558 | if (PreviousCriticalLoc.isValid()) | ||||||
4559 | SemaRef.Diag(PreviousCriticalLoc, | ||||||
4560 | diag::note_omp_previous_critical_region); | ||||||
4561 | return true; | ||||||
4562 | } | ||||||
4563 | } else if (CurrentRegion == OMPD_barrier) { | ||||||
4564 | // OpenMP [2.16, Nesting of Regions] | ||||||
4565 | // A barrier region may not be closely nested inside a worksharing, | ||||||
4566 | // explicit task, critical, ordered, atomic, or master region. | ||||||
4567 | NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || | ||||||
4568 | isOpenMPTaskingDirective(ParentRegion) || | ||||||
4569 | ParentRegion == OMPD_master || | ||||||
4570 | ParentRegion == OMPD_parallel_master || | ||||||
4571 | ParentRegion == OMPD_critical || | ||||||
4572 | ParentRegion == OMPD_ordered; | ||||||
4573 | } else if (isOpenMPWorksharingDirective(CurrentRegion) && | ||||||
4574 | !isOpenMPParallelDirective(CurrentRegion) && | ||||||
4575 | !isOpenMPTeamsDirective(CurrentRegion)) { | ||||||
4576 | // OpenMP [2.16, Nesting of Regions] | ||||||
4577 | // A worksharing region may not be closely nested inside a worksharing, | ||||||
4578 | // explicit task, critical, ordered, atomic, or master region. | ||||||
4579 | NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || | ||||||
4580 | isOpenMPTaskingDirective(ParentRegion) || | ||||||
4581 | ParentRegion == OMPD_master || | ||||||
4582 | ParentRegion == OMPD_parallel_master || | ||||||
4583 | ParentRegion == OMPD_critical || | ||||||
4584 | ParentRegion == OMPD_ordered; | ||||||
4585 | Recommend = ShouldBeInParallelRegion; | ||||||
4586 | } else if (CurrentRegion == OMPD_ordered) { | ||||||
4587 | // OpenMP [2.16, Nesting of Regions] | ||||||
4588 | // An ordered region may not be closely nested inside a critical, | ||||||
4589 | // atomic, or explicit task region. | ||||||
4590 | // An ordered region must be closely nested inside a loop region (or | ||||||
4591 | // parallel loop region) with an ordered clause. | ||||||
4592 | // OpenMP [2.8.1,simd Construct, Restrictions] | ||||||
4593 | // An ordered construct with the simd clause is the only OpenMP construct | ||||||
4594 | // that can appear in the simd region. | ||||||
4595 | NestingProhibited = ParentRegion == OMPD_critical || | ||||||
4596 | isOpenMPTaskingDirective(ParentRegion) || | ||||||
4597 | !(isOpenMPSimdDirective(ParentRegion) || | ||||||
4598 | Stack->isParentOrderedRegion()); | ||||||
4599 | Recommend = ShouldBeInOrderedRegion; | ||||||
4600 | } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { | ||||||
4601 | // OpenMP [2.16, Nesting of Regions] | ||||||
4602 | // If specified, a teams construct must be contained within a target | ||||||
4603 | // construct. | ||||||
4604 | NestingProhibited = | ||||||
4605 | (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || | ||||||
4606 | (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && | ||||||
4607 | ParentRegion != OMPD_target); | ||||||
4608 | OrphanSeen = ParentRegion == OMPD_unknown; | ||||||
4609 | Recommend = ShouldBeInTargetRegion; | ||||||
4610 | } else if (CurrentRegion == OMPD_scan) { | ||||||
4611 | // OpenMP [2.16, Nesting of Regions] | ||||||
4612 | // If specified, a teams construct must be contained within a target | ||||||
4613 | // construct. | ||||||
4614 | NestingProhibited = | ||||||
4615 | SemaRef.LangOpts.OpenMP < 50 || | ||||||
4616 | (ParentRegion != OMPD_simd && ParentRegion != OMPD_for && | ||||||
4617 | ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for && | ||||||
4618 | ParentRegion != OMPD_parallel_for_simd); | ||||||
4619 | OrphanSeen = ParentRegion == OMPD_unknown; | ||||||
4620 | Recommend = ShouldBeInLoopSimdRegion; | ||||||
4621 | } | ||||||
4622 | if (!NestingProhibited && | ||||||
4623 | !isOpenMPTargetExecutionDirective(CurrentRegion) && | ||||||
4624 | !isOpenMPTargetDataManagementDirective(CurrentRegion) && | ||||||
4625 | (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { | ||||||
4626 | // OpenMP [2.16, Nesting of Regions] | ||||||
4627 | // distribute, parallel, parallel sections, parallel workshare, and the | ||||||
4628 | // parallel loop and parallel loop SIMD constructs are the only OpenMP | ||||||
4629 | // constructs that can be closely nested in the teams region. | ||||||
4630 | NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && | ||||||
4631 | !isOpenMPDistributeDirective(CurrentRegion); | ||||||
4632 | Recommend = ShouldBeInParallelRegion; | ||||||
4633 | } | ||||||
4634 | if (!NestingProhibited && | ||||||
4635 | isOpenMPNestingDistributeDirective(CurrentRegion)) { | ||||||
4636 | // OpenMP 4.5 [2.17 Nesting of Regions] | ||||||
4637 | // The region associated with the distribute construct must be strictly | ||||||
4638 | // nested inside a teams region | ||||||
4639 | NestingProhibited = | ||||||
4640 | (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); | ||||||
4641 | Recommend = ShouldBeInTeamsRegion; | ||||||
4642 | } | ||||||
4643 | if (!NestingProhibited && | ||||||
4644 | (isOpenMPTargetExecutionDirective(CurrentRegion) || | ||||||
4645 | isOpenMPTargetDataManagementDirective(CurrentRegion))) { | ||||||
4646 | // OpenMP 4.5 [2.17 Nesting of Regions] | ||||||
4647 | // If a target, target update, target data, target enter data, or | ||||||
4648 | // target exit data construct is encountered during execution of a | ||||||
4649 | // target region, the behavior is unspecified. | ||||||
4650 | NestingProhibited = Stack->hasDirective( | ||||||
4651 | [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, | ||||||
4652 | SourceLocation) { | ||||||
4653 | if (isOpenMPTargetExecutionDirective(K)) { | ||||||
4654 | OffendingRegion = K; | ||||||
4655 | return true; | ||||||
4656 | } | ||||||
4657 | return false; | ||||||
4658 | }, | ||||||
4659 | false /* don't skip top directive */); | ||||||
4660 | CloseNesting = false; | ||||||
4661 | } | ||||||
4662 | if (NestingProhibited) { | ||||||
4663 | if (OrphanSeen) { | ||||||
4664 | SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) | ||||||
4665 | << getOpenMPDirectiveName(CurrentRegion) << Recommend; | ||||||
4666 | } else { | ||||||
4667 | SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) | ||||||
4668 | << CloseNesting << getOpenMPDirectiveName(OffendingRegion) | ||||||
4669 | << Recommend << getOpenMPDirectiveName(CurrentRegion); | ||||||
4670 | } | ||||||
4671 | return true; | ||||||
4672 | } | ||||||
4673 | } | ||||||
4674 | return false; | ||||||
4675 | } | ||||||
4676 | |||||||
4677 | struct Kind2Unsigned { | ||||||
4678 | using argument_type = OpenMPDirectiveKind; | ||||||
4679 | unsigned operator()(argument_type DK) { return unsigned(DK); } | ||||||
4680 | }; | ||||||
4681 | static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, | ||||||
4682 | ArrayRef<OMPClause *> Clauses, | ||||||
4683 | ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { | ||||||
4684 | bool ErrorFound = false; | ||||||
4685 | unsigned NamedModifiersNumber = 0; | ||||||
4686 | llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; | ||||||
4687 | FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1); | ||||||
4688 | SmallVector<SourceLocation, 4> NameModifierLoc; | ||||||
4689 | for (const OMPClause *C : Clauses) { | ||||||
4690 | if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { | ||||||
4691 | // At most one if clause without a directive-name-modifier can appear on | ||||||
4692 | // the directive. | ||||||
4693 | OpenMPDirectiveKind CurNM = IC->getNameModifier(); | ||||||
4694 | if (FoundNameModifiers[CurNM]) { | ||||||
4695 | S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) | ||||||
4696 | << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) | ||||||
4697 | << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); | ||||||
4698 | ErrorFound = true; | ||||||
4699 | } else if (CurNM != OMPD_unknown) { | ||||||
4700 | NameModifierLoc.push_back(IC->getNameModifierLoc()); | ||||||
4701 | ++NamedModifiersNumber; | ||||||
4702 | } | ||||||
4703 | FoundNameModifiers[CurNM] = IC; | ||||||
4704 | if (CurNM == OMPD_unknown) | ||||||
4705 | continue; | ||||||
4706 | // Check if the specified name modifier is allowed for the current | ||||||
4707 | // directive. | ||||||
4708 | // At most one if clause with the particular directive-name-modifier can | ||||||
4709 | // appear on the directive. | ||||||
4710 | bool MatchFound = false; | ||||||
4711 | for (auto NM : AllowedNameModifiers) { | ||||||
4712 | if (CurNM == NM) { | ||||||
4713 | MatchFound = true; | ||||||
4714 | break; | ||||||
4715 | } | ||||||
4716 | } | ||||||
4717 | if (!MatchFound) { | ||||||
4718 | S.Diag(IC->getNameModifierLoc(), | ||||||
4719 | diag::err_omp_wrong_if_directive_name_modifier) | ||||||
4720 | << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); | ||||||
4721 | ErrorFound = true; | ||||||
4722 | } | ||||||
4723 | } | ||||||
4724 | } | ||||||
4725 | // If any if clause on the directive includes a directive-name-modifier then | ||||||
4726 | // all if clauses on the directive must include a directive-name-modifier. | ||||||
4727 | if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { | ||||||
4728 | if (NamedModifiersNumber == AllowedNameModifiers.size()) { | ||||||
4729 | S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), | ||||||
4730 | diag::err_omp_no_more_if_clause); | ||||||
4731 | } else { | ||||||
4732 | std::string Values; | ||||||
4733 | std::string Sep(", "); | ||||||
4734 | unsigned AllowedCnt = 0; | ||||||
4735 | unsigned TotalAllowedNum = | ||||||
4736 | AllowedNameModifiers.size() - NamedModifiersNumber; | ||||||
4737 | for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; | ||||||
4738 | ++Cnt) { | ||||||
4739 | OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; | ||||||
4740 | if (!FoundNameModifiers[NM]) { | ||||||
4741 | Values += "'"; | ||||||
4742 | Values += getOpenMPDirectiveName(NM); | ||||||
4743 | Values += "'"; | ||||||
4744 | if (AllowedCnt + 2 == TotalAllowedNum) | ||||||
4745 | Values += " or "; | ||||||
4746 | else if (AllowedCnt + 1 != TotalAllowedNum) | ||||||
4747 | Values += Sep; | ||||||
4748 | ++AllowedCnt; | ||||||
4749 | } | ||||||
4750 | } | ||||||
4751 | S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), | ||||||
4752 | diag::err_omp_unnamed_if_clause) | ||||||
4753 | << (TotalAllowedNum > 1) << Values; | ||||||
4754 | } | ||||||
4755 | for (SourceLocation Loc : NameModifierLoc) { | ||||||
4756 | S.Diag(Loc, diag::note_omp_previous_named_if_clause); | ||||||
4757 | } | ||||||
4758 | ErrorFound = true; | ||||||
4759 | } | ||||||
4760 | return ErrorFound; | ||||||
4761 | } | ||||||
4762 | |||||||
4763 | static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, | ||||||
4764 | SourceLocation &ELoc, | ||||||
4765 | SourceRange &ERange, | ||||||
4766 | bool AllowArraySection) { | ||||||
4767 | if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || | ||||||
4768 | RefExpr->containsUnexpandedParameterPack()) | ||||||
4769 | return std::make_pair(nullptr, true); | ||||||
4770 | |||||||
4771 | // OpenMP [3.1, C/C++] | ||||||
4772 | // A list item is a variable name. | ||||||
4773 | // OpenMP [2.9.3.3, Restrictions, p.1] | ||||||
4774 | // A variable that is part of another variable (as an array or | ||||||
4775 | // structure element) cannot appear in a private clause. | ||||||
4776 | RefExpr = RefExpr->IgnoreParens(); | ||||||
4777 | enum { | ||||||
4778 | NoArrayExpr = -1, | ||||||
4779 | ArraySubscript = 0, | ||||||
4780 | OMPArraySection = 1 | ||||||
4781 | } IsArrayExpr = NoArrayExpr; | ||||||
4782 | if (AllowArraySection) { | ||||||
4783 | if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { | ||||||
4784 | Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); | ||||||
4785 | while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) | ||||||
4786 | Base = TempASE->getBase()->IgnoreParenImpCasts(); | ||||||
4787 | RefExpr = Base; | ||||||
4788 | IsArrayExpr = ArraySubscript; | ||||||
4789 | } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { | ||||||
4790 | Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); | ||||||
4791 | while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) | ||||||
4792 | Base = TempOASE->getBase()->IgnoreParenImpCasts(); | ||||||
4793 | while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) | ||||||
4794 | Base = TempASE->getBase()->IgnoreParenImpCasts(); | ||||||
4795 | RefExpr = Base; | ||||||
4796 | IsArrayExpr = OMPArraySection; | ||||||
4797 | } | ||||||
4798 | } | ||||||
4799 | ELoc = RefExpr->getExprLoc(); | ||||||
4800 | ERange = RefExpr->getSourceRange(); | ||||||
4801 | RefExpr = RefExpr->IgnoreParenImpCasts(); | ||||||
4802 | auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); | ||||||
4803 | auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); | ||||||
4804 | if ((!DE || !isa<VarDecl>(DE->getDecl())) && | ||||||
4805 | (S.getCurrentThisType().isNull() || !ME || | ||||||
4806 | !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || | ||||||
4807 | !isa<FieldDecl>(ME->getMemberDecl()))) { | ||||||
4808 | if (IsArrayExpr != NoArrayExpr) { | ||||||
4809 | S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr | ||||||
4810 | << ERange; | ||||||
4811 | } else { | ||||||
4812 | S.Diag(ELoc, | ||||||
4813 | AllowArraySection | ||||||
4814 | ? diag::err_omp_expected_var_name_member_expr_or_array_item | ||||||
4815 | : diag::err_omp_expected_var_name_member_expr) | ||||||
4816 | << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; | ||||||
4817 | } | ||||||
4818 | return std::make_pair(nullptr, false); | ||||||
4819 | } | ||||||
4820 | return std::make_pair( | ||||||
4821 | getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); | ||||||
4822 | } | ||||||
4823 | |||||||
4824 | namespace { | ||||||
4825 | /// Checks if the allocator is used in uses_allocators clause to be allowed in | ||||||
4826 | /// target regions. | ||||||
4827 | class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> { | ||||||
4828 | DSAStackTy *S = nullptr; | ||||||
4829 | |||||||
4830 | public: | ||||||
4831 | bool VisitDeclRefExpr(const DeclRefExpr *E) { | ||||||
4832 | return S->isUsesAllocatorsDecl(E->getDecl()) | ||||||
4833 | .getValueOr( | ||||||
4834 | DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == | ||||||
4835 | DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait; | ||||||
4836 | } | ||||||
4837 | bool VisitStmt(const Stmt *S) { | ||||||
4838 | for (const Stmt *Child : S->children()) { | ||||||
4839 | if (Child && Visit(Child)) | ||||||
4840 | return true; | ||||||
4841 | } | ||||||
4842 | return false; | ||||||
4843 | } | ||||||
4844 | explicit AllocatorChecker(DSAStackTy *S) : S(S) {} | ||||||
4845 | }; | ||||||
4846 | } // namespace | ||||||
4847 | |||||||
4848 | static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, | ||||||
4849 | ArrayRef<OMPClause *> Clauses) { | ||||||
4850 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 4851, __PRETTY_FUNCTION__)) | ||||||
4851 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 4851, __PRETTY_FUNCTION__)); | ||||||
4852 | auto AllocateRange = | ||||||
4853 | llvm::make_filter_range(Clauses, OMPAllocateClause::classof); | ||||||
4854 | llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> | ||||||
4855 | DeclToCopy; | ||||||
4856 | auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { | ||||||
4857 | return isOpenMPPrivate(C->getClauseKind()); | ||||||
4858 | }); | ||||||
4859 | for (OMPClause *Cl : PrivateRange) { | ||||||
4860 | MutableArrayRef<Expr *>::iterator I, It, Et; | ||||||
4861 | if (Cl->getClauseKind() == OMPC_private) { | ||||||
4862 | auto *PC = cast<OMPPrivateClause>(Cl); | ||||||
4863 | I = PC->private_copies().begin(); | ||||||
4864 | It = PC->varlist_begin(); | ||||||
4865 | Et = PC->varlist_end(); | ||||||
4866 | } else if (Cl->getClauseKind() == OMPC_firstprivate) { | ||||||
4867 | auto *PC = cast<OMPFirstprivateClause>(Cl); | ||||||
4868 | I = PC->private_copies().begin(); | ||||||
4869 | It = PC->varlist_begin(); | ||||||
4870 | Et = PC->varlist_end(); | ||||||
4871 | } else if (Cl->getClauseKind() == OMPC_lastprivate) { | ||||||
4872 | auto *PC = cast<OMPLastprivateClause>(Cl); | ||||||
4873 | I = PC->private_copies().begin(); | ||||||
4874 | It = PC->varlist_begin(); | ||||||
4875 | Et = PC->varlist_end(); | ||||||
4876 | } else if (Cl->getClauseKind() == OMPC_linear) { | ||||||
4877 | auto *PC = cast<OMPLinearClause>(Cl); | ||||||
4878 | I = PC->privates().begin(); | ||||||
4879 | It = PC->varlist_begin(); | ||||||
4880 | Et = PC->varlist_end(); | ||||||
4881 | } else if (Cl->getClauseKind() == OMPC_reduction) { | ||||||
4882 | auto *PC = cast<OMPReductionClause>(Cl); | ||||||
4883 | I = PC->privates().begin(); | ||||||
4884 | It = PC->varlist_begin(); | ||||||
4885 | Et = PC->varlist_end(); | ||||||
4886 | } else if (Cl->getClauseKind() == OMPC_task_reduction) { | ||||||
4887 | auto *PC = cast<OMPTaskReductionClause>(Cl); | ||||||
4888 | I = PC->privates().begin(); | ||||||
4889 | It = PC->varlist_begin(); | ||||||
4890 | Et = PC->varlist_end(); | ||||||
4891 | } else if (Cl->getClauseKind() == OMPC_in_reduction) { | ||||||
4892 | auto *PC = cast<OMPInReductionClause>(Cl); | ||||||
4893 | I = PC->privates().begin(); | ||||||
4894 | It = PC->varlist_begin(); | ||||||
4895 | Et = PC->varlist_end(); | ||||||
4896 | } else { | ||||||
4897 | llvm_unreachable("Expected private clause.")::llvm::llvm_unreachable_internal("Expected private clause.", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 4897); | ||||||
4898 | } | ||||||
4899 | for (Expr *E : llvm::make_range(It, Et)) { | ||||||
4900 | if (!*I) { | ||||||
4901 | ++I; | ||||||
4902 | continue; | ||||||
4903 | } | ||||||
4904 | SourceLocation ELoc; | ||||||
4905 | SourceRange ERange; | ||||||
4906 | Expr *SimpleRefExpr = E; | ||||||
4907 | auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, | ||||||
4908 | /*AllowArraySection=*/true); | ||||||
4909 | DeclToCopy.try_emplace(Res.first, | ||||||
4910 | cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); | ||||||
4911 | ++I; | ||||||
4912 | } | ||||||
4913 | } | ||||||
4914 | for (OMPClause *C : AllocateRange) { | ||||||
4915 | auto *AC = cast<OMPAllocateClause>(C); | ||||||
4916 | if (S.getLangOpts().OpenMP >= 50 && | ||||||
4917 | !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() && | ||||||
4918 | isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && | ||||||
4919 | AC->getAllocator()) { | ||||||
4920 | Expr *Allocator = AC->getAllocator(); | ||||||
4921 | // OpenMP, 2.12.5 target Construct | ||||||
4922 | // Memory allocators that do not appear in a uses_allocators clause cannot | ||||||
4923 | // appear as an allocator in an allocate clause or be used in the target | ||||||
4924 | // region unless a requires directive with the dynamic_allocators clause | ||||||
4925 | // is present in the same compilation unit. | ||||||
4926 | AllocatorChecker Checker(Stack); | ||||||
4927 | if (Checker.Visit(Allocator)) | ||||||
4928 | S.Diag(Allocator->getExprLoc(), | ||||||
4929 | diag::err_omp_allocator_not_in_uses_allocators) | ||||||
4930 | << Allocator->getSourceRange(); | ||||||
4931 | } | ||||||
4932 | OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = | ||||||
4933 | getAllocatorKind(S, Stack, AC->getAllocator()); | ||||||
4934 | // OpenMP, 2.11.4 allocate Clause, Restrictions. | ||||||
4935 | // For task, taskloop or target directives, allocation requests to memory | ||||||
4936 | // allocators with the trait access set to thread result in unspecified | ||||||
4937 | // behavior. | ||||||
4938 | if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && | ||||||
4939 | (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || | ||||||
4940 | isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { | ||||||
4941 | S.Diag(AC->getAllocator()->getExprLoc(), | ||||||
4942 | diag::warn_omp_allocate_thread_on_task_target_directive) | ||||||
4943 | << getOpenMPDirectiveName(Stack->getCurrentDirective()); | ||||||
4944 | } | ||||||
4945 | for (Expr *E : AC->varlists()) { | ||||||
4946 | SourceLocation ELoc; | ||||||
4947 | SourceRange ERange; | ||||||
4948 | Expr *SimpleRefExpr = E; | ||||||
4949 | auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); | ||||||
4950 | ValueDecl *VD = Res.first; | ||||||
4951 | DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); | ||||||
4952 | if (!isOpenMPPrivate(Data.CKind)) { | ||||||
4953 | S.Diag(E->getExprLoc(), | ||||||
4954 | diag::err_omp_expected_private_copy_for_allocate); | ||||||
4955 | continue; | ||||||
4956 | } | ||||||
4957 | VarDecl *PrivateVD = DeclToCopy[VD]; | ||||||
4958 | if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, | ||||||
4959 | AllocatorKind, AC->getAllocator())) | ||||||
4960 | continue; | ||||||
4961 | applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), | ||||||
4962 | E->getSourceRange()); | ||||||
4963 | } | ||||||
4964 | } | ||||||
4965 | } | ||||||
4966 | |||||||
4967 | StmtResult Sema::ActOnOpenMPExecutableDirective( | ||||||
4968 | OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, | ||||||
4969 | OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, | ||||||
4970 | Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { | ||||||
4971 | StmtResult Res = StmtError(); | ||||||
4972 | // First check CancelRegion which is then used in checkNestingOfRegions. | ||||||
4973 | if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || | ||||||
4974 | checkNestingOfRegions(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), Kind, DirName, CancelRegion, | ||||||
4975 | StartLoc)) | ||||||
4976 | return StmtError(); | ||||||
4977 | |||||||
4978 | llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; | ||||||
4979 | VarsWithInheritedDSAType VarsWithInheritedDSA; | ||||||
4980 | bool ErrorFound = false; | ||||||
4981 | ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); | ||||||
4982 | if (AStmt && !CurContext->isDependentContext()) { | ||||||
4983 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 4983, __PRETTY_FUNCTION__)); | ||||||
4984 | |||||||
4985 | // Check default data sharing attributes for referenced variables. | ||||||
4986 | DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), *this, cast<CapturedStmt>(AStmt)); | ||||||
4987 | int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); | ||||||
4988 | Stmt *S = AStmt; | ||||||
4989 | while (--ThisCaptureLevel >= 0) | ||||||
4990 | S = cast<CapturedStmt>(S)->getCapturedStmt(); | ||||||
4991 | DSAChecker.Visit(S); | ||||||
4992 | if (!isOpenMPTargetDataManagementDirective(Kind) && | ||||||
4993 | !isOpenMPTaskingDirective(Kind)) { | ||||||
4994 | // Visit subcaptures to generate implicit clauses for captured vars. | ||||||
4995 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
4996 | SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; | ||||||
4997 | getOpenMPCaptureRegions(CaptureRegions, Kind); | ||||||
4998 | // Ignore outer tasking regions for target directives. | ||||||
4999 | if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) | ||||||
5000 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||
5001 | DSAChecker.visitSubCaptures(CS); | ||||||
5002 | } | ||||||
5003 | if (DSAChecker.isErrorFound()) | ||||||
5004 | return StmtError(); | ||||||
5005 | // Generate list of implicitly defined firstprivate variables. | ||||||
5006 | VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); | ||||||
5007 | |||||||
5008 | SmallVector<Expr *, 4> ImplicitFirstprivates( | ||||||
5009 | DSAChecker.getImplicitFirstprivate().begin(), | ||||||
5010 | DSAChecker.getImplicitFirstprivate().end()); | ||||||
5011 | SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete]; | ||||||
5012 | for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { | ||||||
5013 | ArrayRef<Expr *> ImplicitMap = | ||||||
5014 | DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I)); | ||||||
5015 | ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end()); | ||||||
5016 | } | ||||||
5017 | // Mark taskgroup task_reduction descriptors as implicitly firstprivate. | ||||||
5018 | for (OMPClause *C : Clauses) { | ||||||
5019 | if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { | ||||||
5020 | for (Expr *E : IRC->taskgroup_descriptors()) | ||||||
5021 | if (E) | ||||||
5022 | ImplicitFirstprivates.emplace_back(E); | ||||||
5023 | } | ||||||
5024 | // OpenMP 5.0, 2.10.1 task Construct | ||||||
5025 | // [detach clause]... The event-handle will be considered as if it was | ||||||
5026 | // specified on a firstprivate clause. | ||||||
5027 | if (auto *DC = dyn_cast<OMPDetachClause>(C)) | ||||||
5028 | ImplicitFirstprivates.push_back(DC->getEventHandler()); | ||||||
5029 | } | ||||||
5030 | if (!ImplicitFirstprivates.empty()) { | ||||||
5031 | if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( | ||||||
5032 | ImplicitFirstprivates, SourceLocation(), SourceLocation(), | ||||||
5033 | SourceLocation())) { | ||||||
5034 | ClausesWithImplicit.push_back(Implicit); | ||||||
5035 | ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != | ||||||
5036 | ImplicitFirstprivates.size(); | ||||||
5037 | } else { | ||||||
5038 | ErrorFound = true; | ||||||
5039 | } | ||||||
5040 | } | ||||||
5041 | int ClauseKindCnt = -1; | ||||||
5042 | for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) { | ||||||
5043 | ++ClauseKindCnt; | ||||||
5044 | if (ImplicitMap.empty()) | ||||||
5045 | continue; | ||||||
5046 | CXXScopeSpec MapperIdScopeSpec; | ||||||
5047 | DeclarationNameInfo MapperId; | ||||||
5048 | auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); | ||||||
5049 | if (OMPClause *Implicit = ActOnOpenMPMapClause( | ||||||
5050 | llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind, | ||||||
5051 | /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), | ||||||
5052 | ImplicitMap, OMPVarListLocTy())) { | ||||||
5053 | ClausesWithImplicit.emplace_back(Implicit); | ||||||
5054 | ErrorFound |= | ||||||
5055 | cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size(); | ||||||
5056 | } else { | ||||||
5057 | ErrorFound = true; | ||||||
5058 | } | ||||||
5059 | } | ||||||
5060 | } | ||||||
5061 | |||||||
5062 | llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; | ||||||
5063 | switch (Kind) { | ||||||
5064 | case OMPD_parallel: | ||||||
5065 | Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||
5066 | EndLoc); | ||||||
5067 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||
5068 | break; | ||||||
5069 | case OMPD_simd: | ||||||
5070 | Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, | ||||||
5071 | VarsWithInheritedDSA); | ||||||
5072 | if (LangOpts.OpenMP >= 50) | ||||||
5073 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||
5074 | break; | ||||||
5075 | case OMPD_for: | ||||||
5076 | Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, | ||||||
5077 | VarsWithInheritedDSA); | ||||||
5078 | break; | ||||||
5079 | case OMPD_for_simd: | ||||||
5080 | Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||
5081 | EndLoc, VarsWithInheritedDSA); | ||||||
5082 | if (LangOpts.OpenMP >= 50) | ||||||
5083 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||
5084 | break; | ||||||
5085 | case OMPD_sections: | ||||||
5086 | Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||
5087 | EndLoc); | ||||||
5088 | break; | ||||||
5089 | case OMPD_section: | ||||||
5090 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5091, __PRETTY_FUNCTION__)) | ||||||
5091 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5091, __PRETTY_FUNCTION__)); | ||||||
5092 | Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); | ||||||
5093 | break; | ||||||
5094 | case OMPD_single: | ||||||
5095 | Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||
5096 | EndLoc); | ||||||
5097 | break; | ||||||
5098 | case OMPD_master: | ||||||
5099 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5100, __PRETTY_FUNCTION__)) | ||||||
5100 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5100, __PRETTY_FUNCTION__)); | ||||||
5101 | Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); | ||||||
5102 | break; | ||||||
5103 | case OMPD_critical: | ||||||
5104 | Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, | ||||||
5105 | StartLoc, EndLoc); | ||||||
5106 | break; | ||||||
5107 | case OMPD_parallel_for: | ||||||
5108 | Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||
5109 | EndLoc, VarsWithInheritedDSA); | ||||||
5110 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||
5111 | break; | ||||||
5112 | case OMPD_parallel_for_simd: | ||||||
5113 | Res = ActOnOpenMPParallelForSimdDirective( | ||||||
5114 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||
5115 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||
5116 | if (LangOpts.OpenMP >= 50) | ||||||
5117 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||
5118 | break; | ||||||
5119 | case OMPD_parallel_master: | ||||||
5120 | Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, | ||||||
5121 | StartLoc, EndLoc); | ||||||
5122 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||
5123 | break; | ||||||
5124 | case OMPD_parallel_sections: | ||||||
5125 | Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, | ||||||
5126 | StartLoc, EndLoc); | ||||||
5127 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||
5128 | break; | ||||||
5129 | case OMPD_task: | ||||||
5130 | Res = | ||||||
5131 | ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); | ||||||
5132 | AllowedNameModifiers.push_back(OMPD_task); | ||||||
5133 | break; | ||||||
5134 | case OMPD_taskyield: | ||||||
5135 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5136, __PRETTY_FUNCTION__)) | ||||||
5136 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5136, __PRETTY_FUNCTION__)); | ||||||
5137 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5138, __PRETTY_FUNCTION__)) | ||||||
5138 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5138, __PRETTY_FUNCTION__)); | ||||||
5139 | Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); | ||||||
5140 | break; | ||||||
5141 | case OMPD_barrier: | ||||||
5142 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5143, __PRETTY_FUNCTION__)) | ||||||
5143 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5143, __PRETTY_FUNCTION__)); | ||||||
5144 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5145, __PRETTY_FUNCTION__)) | ||||||
5145 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5145, __PRETTY_FUNCTION__)); | ||||||
5146 | Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); | ||||||
5147 | break; | ||||||
5148 | case OMPD_taskwait: | ||||||
5149 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5150, __PRETTY_FUNCTION__)) | ||||||
5150 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5150, __PRETTY_FUNCTION__)); | ||||||
5151 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5152, __PRETTY_FUNCTION__)) | ||||||
5152 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5152, __PRETTY_FUNCTION__)); | ||||||
5153 | Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); | ||||||
5154 | break; | ||||||
5155 | case OMPD_taskgroup: | ||||||
5156 | Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||
5157 | EndLoc); | ||||||
5158 | break; | ||||||
5159 | case OMPD_flush: | ||||||
5160 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5161, __PRETTY_FUNCTION__)) | ||||||
5161 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5161, __PRETTY_FUNCTION__)); | ||||||
5162 | Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); | ||||||
5163 | break; | ||||||
5164 | case OMPD_depobj: | ||||||
5165 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5166, __PRETTY_FUNCTION__)) | ||||||
5166 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5166, __PRETTY_FUNCTION__)); | ||||||
5167 | Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc); | ||||||
5168 | break; | ||||||
5169 | case OMPD_scan: | ||||||
5170 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5171, __PRETTY_FUNCTION__)) | ||||||
5171 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5171, __PRETTY_FUNCTION__)); | ||||||
5172 | Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc); | ||||||
5173 | break; | ||||||
5174 | case OMPD_ordered: | ||||||
5175 | Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||
5176 | EndLoc); | ||||||
5177 | break; | ||||||
5178 | case OMPD_atomic: | ||||||
5179 | Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||
5180 | EndLoc); | ||||||
5181 | break; | ||||||
5182 | case OMPD_teams: | ||||||
5183 | Res = | ||||||
5184 | ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); | ||||||
5185 | break; | ||||||
5186 | case OMPD_target: | ||||||
5187 | Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||
5188 | EndLoc); | ||||||
5189 | AllowedNameModifiers.push_back(OMPD_target); | ||||||
5190 | break; | ||||||
5191 | case OMPD_target_parallel: | ||||||
5192 | Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, | ||||||
5193 | StartLoc, EndLoc); | ||||||
5194 | AllowedNameModifiers.push_back(OMPD_target); | ||||||
5195 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||
5196 | break; | ||||||
5197 | case OMPD_target_parallel_for: | ||||||
5198 | Res = ActOnOpenMPTargetParallelForDirective( | ||||||
5199 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||
5200 | AllowedNameModifiers.push_back(OMPD_target); | ||||||
5201 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||
5202 | break; | ||||||
5203 | case OMPD_cancellation_point: | ||||||
5204 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5205, __PRETTY_FUNCTION__)) | ||||||
5205 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5205, __PRETTY_FUNCTION__)); | ||||||
5206 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5207, __PRETTY_FUNCTION__)) | ||||||
5207 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5207, __PRETTY_FUNCTION__)); | ||||||
5208 | Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); | ||||||
5209 | break; | ||||||
5210 | case OMPD_cancel: | ||||||
5211 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5212, __PRETTY_FUNCTION__)) | ||||||
5212 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5212, __PRETTY_FUNCTION__)); | ||||||
5213 | Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, | ||||||
5214 | CancelRegion); | ||||||
5215 | AllowedNameModifiers.push_back(OMPD_cancel); | ||||||
5216 | break; | ||||||
5217 | case OMPD_target_data: | ||||||
5218 | Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||
5219 | EndLoc); | ||||||
5220 | AllowedNameModifiers.push_back(OMPD_target_data); | ||||||
5221 | break; | ||||||
5222 | case OMPD_target_enter_data: | ||||||
5223 | Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, | ||||||
5224 | EndLoc, AStmt); | ||||||
5225 | AllowedNameModifiers.push_back(OMPD_target_enter_data); | ||||||
5226 | break; | ||||||
5227 | case OMPD_target_exit_data: | ||||||
5228 | Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, | ||||||
5229 | EndLoc, AStmt); | ||||||
5230 | AllowedNameModifiers.push_back(OMPD_target_exit_data); | ||||||
5231 | break; | ||||||
5232 | case OMPD_taskloop: | ||||||
5233 | Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||
5234 | EndLoc, VarsWithInheritedDSA); | ||||||
5235 | AllowedNameModifiers.push_back(OMPD_taskloop); | ||||||
5236 | break; | ||||||
5237 | case OMPD_taskloop_simd: | ||||||
5238 | Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||
5239 | EndLoc, VarsWithInheritedDSA); | ||||||
5240 | AllowedNameModifiers.push_back(OMPD_taskloop); | ||||||
5241 | if (LangOpts.OpenMP >= 50) | ||||||
5242 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||
5243 | break; | ||||||
5244 | case OMPD_master_taskloop: | ||||||
5245 | Res = ActOnOpenMPMasterTaskLoopDirective( | ||||||
5246 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||
5247 | AllowedNameModifiers.push_back(OMPD_taskloop); | ||||||
5248 | break; | ||||||
5249 | case OMPD_master_taskloop_simd: | ||||||
5250 | Res = ActOnOpenMPMasterTaskLoopSimdDirective( | ||||||
5251 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||
5252 | AllowedNameModifiers.push_back(OMPD_taskloop); | ||||||
5253 | if (LangOpts.OpenMP >= 50) | ||||||
5254 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||
5255 | break; | ||||||
5256 | case OMPD_parallel_master_taskloop: | ||||||
5257 | Res = ActOnOpenMPParallelMasterTaskLoopDirective( | ||||||
5258 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||
5259 | AllowedNameModifiers.push_back(OMPD_taskloop); | ||||||
5260 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||
5261 | break; | ||||||
5262 | case OMPD_parallel_master_taskloop_simd: | ||||||
5263 | Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( | ||||||
5264 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||
5265 | AllowedNameModifiers.push_back(OMPD_taskloop); | ||||||
5266 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||
5267 | if (LangOpts.OpenMP >= 50) | ||||||
5268 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||
5269 | break; | ||||||
5270 | case OMPD_distribute: | ||||||
5271 | Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||
5272 | EndLoc, VarsWithInheritedDSA); | ||||||
5273 | break; | ||||||
5274 | case OMPD_target_update: | ||||||
5275 | Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, | ||||||
5276 | EndLoc, AStmt); | ||||||
5277 | AllowedNameModifiers.push_back(OMPD_target_update); | ||||||
5278 | break; | ||||||
5279 | case OMPD_distribute_parallel_for: | ||||||
5280 | Res = ActOnOpenMPDistributeParallelForDirective( | ||||||
5281 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||
5282 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||
5283 | break; | ||||||
5284 | case OMPD_distribute_parallel_for_simd: | ||||||
5285 | Res = ActOnOpenMPDistributeParallelForSimdDirective( | ||||||
5286 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||
5287 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||
5288 | if (LangOpts.OpenMP >= 50) | ||||||
5289 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||
5290 | break; | ||||||
5291 | case OMPD_distribute_simd: | ||||||
5292 | Res = ActOnOpenMPDistributeSimdDirective( | ||||||
5293 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||
5294 | if (LangOpts.OpenMP >= 50) | ||||||
5295 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||
5296 | break; | ||||||
5297 | case OMPD_target_parallel_for_simd: | ||||||
5298 | Res = ActOnOpenMPTargetParallelForSimdDirective( | ||||||
5299 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||
5300 | AllowedNameModifiers.push_back(OMPD_target); | ||||||
5301 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||
5302 | if (LangOpts.OpenMP >= 50) | ||||||
5303 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||
5304 | break; | ||||||
5305 | case OMPD_target_simd: | ||||||
5306 | Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||
5307 | EndLoc, VarsWithInheritedDSA); | ||||||
5308 | AllowedNameModifiers.push_back(OMPD_target); | ||||||
5309 | if (LangOpts.OpenMP >= 50) | ||||||
5310 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||
5311 | break; | ||||||
5312 | case OMPD_teams_distribute: | ||||||
5313 | Res = ActOnOpenMPTeamsDistributeDirective( | ||||||
5314 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||
5315 | break; | ||||||
5316 | case OMPD_teams_distribute_simd: | ||||||
5317 | Res = ActOnOpenMPTeamsDistributeSimdDirective( | ||||||
5318 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||
5319 | if (LangOpts.OpenMP >= 50) | ||||||
5320 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||
5321 | break; | ||||||
5322 | case OMPD_teams_distribute_parallel_for_simd: | ||||||
5323 | Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( | ||||||
5324 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||
5325 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||
5326 | if (LangOpts.OpenMP >= 50) | ||||||
5327 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||
5328 | break; | ||||||
5329 | case OMPD_teams_distribute_parallel_for: | ||||||
5330 | Res = ActOnOpenMPTeamsDistributeParallelForDirective( | ||||||
5331 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||
5332 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||
5333 | break; | ||||||
5334 | case OMPD_target_teams: | ||||||
5335 | Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||||
5336 | EndLoc); | ||||||
5337 | AllowedNameModifiers.push_back(OMPD_target); | ||||||
5338 | break; | ||||||
5339 | case OMPD_target_teams_distribute: | ||||||
5340 | Res = ActOnOpenMPTargetTeamsDistributeDirective( | ||||||
5341 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||
5342 | AllowedNameModifiers.push_back(OMPD_target); | ||||||
5343 | break; | ||||||
5344 | case OMPD_target_teams_distribute_parallel_for: | ||||||
5345 | Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( | ||||||
5346 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||
5347 | AllowedNameModifiers.push_back(OMPD_target); | ||||||
5348 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||
5349 | break; | ||||||
5350 | case OMPD_target_teams_distribute_parallel_for_simd: | ||||||
5351 | Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( | ||||||
5352 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||
5353 | AllowedNameModifiers.push_back(OMPD_target); | ||||||
5354 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||||
5355 | if (LangOpts.OpenMP >= 50) | ||||||
5356 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||
5357 | break; | ||||||
5358 | case OMPD_target_teams_distribute_simd: | ||||||
5359 | Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( | ||||||
5360 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||||
5361 | AllowedNameModifiers.push_back(OMPD_target); | ||||||
5362 | if (LangOpts.OpenMP >= 50) | ||||||
5363 | AllowedNameModifiers.push_back(OMPD_simd); | ||||||
5364 | break; | ||||||
5365 | case OMPD_declare_target: | ||||||
5366 | case OMPD_end_declare_target: | ||||||
5367 | case OMPD_threadprivate: | ||||||
5368 | case OMPD_allocate: | ||||||
5369 | case OMPD_declare_reduction: | ||||||
5370 | case OMPD_declare_mapper: | ||||||
5371 | case OMPD_declare_simd: | ||||||
5372 | case OMPD_requires: | ||||||
5373 | case OMPD_declare_variant: | ||||||
5374 | case OMPD_begin_declare_variant: | ||||||
5375 | case OMPD_end_declare_variant: | ||||||
5376 | llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5376); | ||||||
5377 | case OMPD_unknown: | ||||||
5378 | default: | ||||||
5379 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5379); | ||||||
5380 | } | ||||||
5381 | |||||||
5382 | ErrorFound = Res.isInvalid() || ErrorFound; | ||||||
5383 | |||||||
5384 | // Check variables in the clauses if default(none) or | ||||||
5385 | // default(firstprivate) was specified. | ||||||
5386 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() == DSA_none || | ||||||
5387 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() == DSA_firstprivate) { | ||||||
5388 | DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), *this, nullptr); | ||||||
5389 | for (OMPClause *C : Clauses) { | ||||||
5390 | switch (C->getClauseKind()) { | ||||||
5391 | case OMPC_num_threads: | ||||||
5392 | case OMPC_dist_schedule: | ||||||
5393 | // Do not analyse if no parent teams directive. | ||||||
5394 | if (isOpenMPTeamsDirective(Kind)) | ||||||
5395 | break; | ||||||
5396 | continue; | ||||||
5397 | case OMPC_if: | ||||||
5398 | if (isOpenMPTeamsDirective(Kind) && | ||||||
5399 | cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) | ||||||
5400 | break; | ||||||
5401 | if (isOpenMPParallelDirective(Kind) && | ||||||
5402 | isOpenMPTaskLoopDirective(Kind) && | ||||||
5403 | cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) | ||||||
5404 | break; | ||||||
5405 | continue; | ||||||
5406 | case OMPC_schedule: | ||||||
5407 | case OMPC_detach: | ||||||
5408 | break; | ||||||
5409 | case OMPC_grainsize: | ||||||
5410 | case OMPC_num_tasks: | ||||||
5411 | case OMPC_final: | ||||||
5412 | case OMPC_priority: | ||||||
5413 | // Do not analyze if no parent parallel directive. | ||||||
5414 | if (isOpenMPParallelDirective(Kind)) | ||||||
5415 | break; | ||||||
5416 | continue; | ||||||
5417 | case OMPC_ordered: | ||||||
5418 | case OMPC_device: | ||||||
5419 | case OMPC_num_teams: | ||||||
5420 | case OMPC_thread_limit: | ||||||
5421 | case OMPC_hint: | ||||||
5422 | case OMPC_collapse: | ||||||
5423 | case OMPC_safelen: | ||||||
5424 | case OMPC_simdlen: | ||||||
5425 | case OMPC_default: | ||||||
5426 | case OMPC_proc_bind: | ||||||
5427 | case OMPC_private: | ||||||
5428 | case OMPC_firstprivate: | ||||||
5429 | case OMPC_lastprivate: | ||||||
5430 | case OMPC_shared: | ||||||
5431 | case OMPC_reduction: | ||||||
5432 | case OMPC_task_reduction: | ||||||
5433 | case OMPC_in_reduction: | ||||||
5434 | case OMPC_linear: | ||||||
5435 | case OMPC_aligned: | ||||||
5436 | case OMPC_copyin: | ||||||
5437 | case OMPC_copyprivate: | ||||||
5438 | case OMPC_nowait: | ||||||
5439 | case OMPC_untied: | ||||||
5440 | case OMPC_mergeable: | ||||||
5441 | case OMPC_allocate: | ||||||
5442 | case OMPC_read: | ||||||
5443 | case OMPC_write: | ||||||
5444 | case OMPC_update: | ||||||
5445 | case OMPC_capture: | ||||||
5446 | case OMPC_seq_cst: | ||||||
5447 | case OMPC_acq_rel: | ||||||
5448 | case OMPC_acquire: | ||||||
5449 | case OMPC_release: | ||||||
5450 | case OMPC_relaxed: | ||||||
5451 | case OMPC_depend: | ||||||
5452 | case OMPC_threads: | ||||||
5453 | case OMPC_simd: | ||||||
5454 | case OMPC_map: | ||||||
5455 | case OMPC_nogroup: | ||||||
5456 | case OMPC_defaultmap: | ||||||
5457 | case OMPC_to: | ||||||
5458 | case OMPC_from: | ||||||
5459 | case OMPC_use_device_ptr: | ||||||
5460 | case OMPC_use_device_addr: | ||||||
5461 | case OMPC_is_device_ptr: | ||||||
5462 | case OMPC_nontemporal: | ||||||
5463 | case OMPC_order: | ||||||
5464 | case OMPC_destroy: | ||||||
5465 | case OMPC_inclusive: | ||||||
5466 | case OMPC_exclusive: | ||||||
5467 | case OMPC_uses_allocators: | ||||||
5468 | case OMPC_affinity: | ||||||
5469 | continue; | ||||||
5470 | case OMPC_allocator: | ||||||
5471 | case OMPC_flush: | ||||||
5472 | case OMPC_depobj: | ||||||
5473 | case OMPC_threadprivate: | ||||||
5474 | case OMPC_uniform: | ||||||
5475 | case OMPC_unknown: | ||||||
5476 | case OMPC_unified_address: | ||||||
5477 | case OMPC_unified_shared_memory: | ||||||
5478 | case OMPC_reverse_offload: | ||||||
5479 | case OMPC_dynamic_allocators: | ||||||
5480 | case OMPC_atomic_default_mem_order: | ||||||
5481 | case OMPC_device_type: | ||||||
5482 | case OMPC_match: | ||||||
5483 | default: | ||||||
5484 | llvm_unreachable("Unexpected clause")::llvm::llvm_unreachable_internal("Unexpected clause", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5484); | ||||||
5485 | } | ||||||
5486 | for (Stmt *CC : C->children()) { | ||||||
5487 | if (CC) | ||||||
5488 | DSAChecker.Visit(CC); | ||||||
5489 | } | ||||||
5490 | } | ||||||
5491 | for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) | ||||||
5492 | VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); | ||||||
5493 | } | ||||||
5494 | for (const auto &P : VarsWithInheritedDSA) { | ||||||
5495 | if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) | ||||||
5496 | continue; | ||||||
5497 | ErrorFound = true; | ||||||
5498 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() == DSA_none || | ||||||
5499 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() == DSA_firstprivate) { | ||||||
5500 | Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) | ||||||
5501 | << P.first << P.second->getSourceRange(); | ||||||
5502 | Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSALocation(), diag::note_omp_default_dsa_none); | ||||||
5503 | } else if (getLangOpts().OpenMP >= 50) { | ||||||
5504 | Diag(P.second->getExprLoc(), | ||||||
5505 | diag::err_omp_defaultmap_no_attr_for_variable) | ||||||
5506 | << P.first << P.second->getSourceRange(); | ||||||
5507 | Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSALocation(), | ||||||
5508 | diag::note_omp_defaultmap_attr_none); | ||||||
5509 | } | ||||||
5510 | } | ||||||
5511 | |||||||
5512 | if (!AllowedNameModifiers.empty()) | ||||||
5513 | ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || | ||||||
5514 | ErrorFound; | ||||||
5515 | |||||||
5516 | if (ErrorFound) | ||||||
5517 | return StmtError(); | ||||||
5518 | |||||||
5519 | if (!CurContext->isDependentContext() && | ||||||
5520 | isOpenMPTargetExecutionDirective(Kind) && | ||||||
5521 | !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || | ||||||
5522 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || | ||||||
5523 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || | ||||||
5524 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { | ||||||
5525 | // Register target to DSA Stack. | ||||||
5526 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addTargetDirLocation(StartLoc); | ||||||
5527 | } | ||||||
5528 | |||||||
5529 | return Res; | ||||||
5530 | } | ||||||
5531 | |||||||
5532 | Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( | ||||||
5533 | DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, | ||||||
5534 | ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, | ||||||
5535 | ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, | ||||||
5536 | ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { | ||||||
5537 | assert(Aligneds.size() == Alignments.size())((Aligneds.size() == Alignments.size()) ? static_cast<void > (0) : __assert_fail ("Aligneds.size() == Alignments.size()" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5537, __PRETTY_FUNCTION__)); | ||||||
5538 | assert(Linears.size() == LinModifiers.size())((Linears.size() == LinModifiers.size()) ? static_cast<void > (0) : __assert_fail ("Linears.size() == LinModifiers.size()" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5538, __PRETTY_FUNCTION__)); | ||||||
5539 | assert(Linears.size() == Steps.size())((Linears.size() == Steps.size()) ? static_cast<void> ( 0) : __assert_fail ("Linears.size() == Steps.size()", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5539, __PRETTY_FUNCTION__)); | ||||||
5540 | if (!DG || DG.get().isNull()) | ||||||
5541 | return DeclGroupPtrTy(); | ||||||
5542 | |||||||
5543 | const int SimdId = 0; | ||||||
5544 | if (!DG.get().isSingleDecl()) { | ||||||
5545 | Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) | ||||||
5546 | << SimdId; | ||||||
5547 | return DG; | ||||||
5548 | } | ||||||
5549 | Decl *ADecl = DG.get().getSingleDecl(); | ||||||
5550 | if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) | ||||||
5551 | ADecl = FTD->getTemplatedDecl(); | ||||||
5552 | |||||||
5553 | auto *FD = dyn_cast<FunctionDecl>(ADecl); | ||||||
5554 | if (!FD) { | ||||||
5555 | Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; | ||||||
5556 | return DeclGroupPtrTy(); | ||||||
5557 | } | ||||||
5558 | |||||||
5559 | // OpenMP [2.8.2, declare simd construct, Description] | ||||||
5560 | // The parameter of the simdlen clause must be a constant positive integer | ||||||
5561 | // expression. | ||||||
5562 | ExprResult SL; | ||||||
5563 | if (Simdlen) | ||||||
5564 | SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); | ||||||
5565 | // OpenMP [2.8.2, declare simd construct, Description] | ||||||
5566 | // The special this pointer can be used as if was one of the arguments to the | ||||||
5567 | // function in any of the linear, aligned, or uniform clauses. | ||||||
5568 | // The uniform clause declares one or more arguments to have an invariant | ||||||
5569 | // value for all concurrent invocations of the function in the execution of a | ||||||
5570 | // single SIMD loop. | ||||||
5571 | llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; | ||||||
5572 | const Expr *UniformedLinearThis = nullptr; | ||||||
5573 | for (const Expr *E : Uniforms) { | ||||||
5574 | E = E->IgnoreParenImpCasts(); | ||||||
5575 | if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) | ||||||
5576 | if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) | ||||||
5577 | if (FD->getNumParams() > PVD->getFunctionScopeIndex() && | ||||||
5578 | FD->getParamDecl(PVD->getFunctionScopeIndex()) | ||||||
5579 | ->getCanonicalDecl() == PVD->getCanonicalDecl()) { | ||||||
5580 | UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); | ||||||
5581 | continue; | ||||||
5582 | } | ||||||
5583 | if (isa<CXXThisExpr>(E)) { | ||||||
5584 | UniformedLinearThis = E; | ||||||
5585 | continue; | ||||||
5586 | } | ||||||
5587 | Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) | ||||||
5588 | << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); | ||||||
5589 | } | ||||||
5590 | // OpenMP [2.8.2, declare simd construct, Description] | ||||||
5591 | // The aligned clause declares that the object to which each list item points | ||||||
5592 | // is aligned to the number of bytes expressed in the optional parameter of | ||||||
5593 | // the aligned clause. | ||||||
5594 | // The special this pointer can be used as if was one of the arguments to the | ||||||
5595 | // function in any of the linear, aligned, or uniform clauses. | ||||||
5596 | // The type of list items appearing in the aligned clause must be array, | ||||||
5597 | // pointer, reference to array, or reference to pointer. | ||||||
5598 | llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; | ||||||
5599 | const Expr *AlignedThis = nullptr; | ||||||
5600 | for (const Expr *E : Aligneds) { | ||||||
5601 | E = E->IgnoreParenImpCasts(); | ||||||
5602 | if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) | ||||||
5603 | if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { | ||||||
5604 | const VarDecl *CanonPVD = PVD->getCanonicalDecl(); | ||||||
5605 | if (FD->getNumParams() > PVD->getFunctionScopeIndex() && | ||||||
5606 | FD->getParamDecl(PVD->getFunctionScopeIndex()) | ||||||
5607 | ->getCanonicalDecl() == CanonPVD) { | ||||||
5608 | // OpenMP [2.8.1, simd construct, Restrictions] | ||||||
5609 | // A list-item cannot appear in more than one aligned clause. | ||||||
5610 | if (AlignedArgs.count(CanonPVD) > 0) { | ||||||
5611 | Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) | ||||||
5612 | << 1 << getOpenMPClauseName(OMPC_aligned) | ||||||
5613 | << E->getSourceRange(); | ||||||
5614 | Diag(AlignedArgs[CanonPVD]->getExprLoc(), | ||||||
5615 | diag::note_omp_explicit_dsa) | ||||||
5616 | << getOpenMPClauseName(OMPC_aligned); | ||||||
5617 | continue; | ||||||
5618 | } | ||||||
5619 | AlignedArgs[CanonPVD] = E; | ||||||
5620 | QualType QTy = PVD->getType() | ||||||
5621 | .getNonReferenceType() | ||||||
5622 | .getUnqualifiedType() | ||||||
5623 | .getCanonicalType(); | ||||||
5624 | const Type *Ty = QTy.getTypePtrOrNull(); | ||||||
5625 | if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { | ||||||
5626 | Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) | ||||||
5627 | << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); | ||||||
5628 | Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; | ||||||
5629 | } | ||||||
5630 | continue; | ||||||
5631 | } | ||||||
5632 | } | ||||||
5633 | if (isa<CXXThisExpr>(E)) { | ||||||
5634 | if (AlignedThis) { | ||||||
5635 | Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) | ||||||
5636 | << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); | ||||||
5637 | Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) | ||||||
5638 | << getOpenMPClauseName(OMPC_aligned); | ||||||
5639 | } | ||||||
5640 | AlignedThis = E; | ||||||
5641 | continue; | ||||||
5642 | } | ||||||
5643 | Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) | ||||||
5644 | << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); | ||||||
5645 | } | ||||||
5646 | // The optional parameter of the aligned clause, alignment, must be a constant | ||||||
5647 | // positive integer expression. If no optional parameter is specified, | ||||||
5648 | // implementation-defined default alignments for SIMD instructions on the | ||||||
5649 | // target platforms are assumed. | ||||||
5650 | SmallVector<const Expr *, 4> NewAligns; | ||||||
5651 | for (Expr *E : Alignments) { | ||||||
5652 | ExprResult Align; | ||||||
5653 | if (E) | ||||||
5654 | Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); | ||||||
5655 | NewAligns.push_back(Align.get()); | ||||||
5656 | } | ||||||
5657 | // OpenMP [2.8.2, declare simd construct, Description] | ||||||
5658 | // The linear clause declares one or more list items to be private to a SIMD | ||||||
5659 | // lane and to have a linear relationship with respect to the iteration space | ||||||
5660 | // of a loop. | ||||||
5661 | // The special this pointer can be used as if was one of the arguments to the | ||||||
5662 | // function in any of the linear, aligned, or uniform clauses. | ||||||
5663 | // When a linear-step expression is specified in a linear clause it must be | ||||||
5664 | // either a constant integer expression or an integer-typed parameter that is | ||||||
5665 | // specified in a uniform clause on the directive. | ||||||
5666 | llvm::DenseMap<const Decl *, const Expr *> LinearArgs; | ||||||
5667 | const bool IsUniformedThis = UniformedLinearThis != nullptr; | ||||||
5668 | auto MI = LinModifiers.begin(); | ||||||
5669 | for (const Expr *E : Linears) { | ||||||
5670 | auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); | ||||||
5671 | ++MI; | ||||||
5672 | E = E->IgnoreParenImpCasts(); | ||||||
5673 | if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) | ||||||
5674 | if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { | ||||||
5675 | const VarDecl *CanonPVD = PVD->getCanonicalDecl(); | ||||||
5676 | if (FD->getNumParams() > PVD->getFunctionScopeIndex() && | ||||||
5677 | FD->getParamDecl(PVD->getFunctionScopeIndex()) | ||||||
5678 | ->getCanonicalDecl() == CanonPVD) { | ||||||
5679 | // OpenMP [2.15.3.7, linear Clause, Restrictions] | ||||||
5680 | // A list-item cannot appear in more than one linear clause. | ||||||
5681 | if (LinearArgs.count(CanonPVD) > 0) { | ||||||
5682 | Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) | ||||||
5683 | << getOpenMPClauseName(OMPC_linear) | ||||||
5684 | << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); | ||||||
5685 | Diag(LinearArgs[CanonPVD]->getExprLoc(), | ||||||
5686 | diag::note_omp_explicit_dsa) | ||||||
5687 | << getOpenMPClauseName(OMPC_linear); | ||||||
5688 | continue; | ||||||
5689 | } | ||||||
5690 | // Each argument can appear in at most one uniform or linear clause. | ||||||
5691 | if (UniformedArgs.count(CanonPVD) > 0) { | ||||||
5692 | Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) | ||||||
5693 | << getOpenMPClauseName(OMPC_linear) | ||||||
5694 | << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); | ||||||
5695 | Diag(UniformedArgs[CanonPVD]->getExprLoc(), | ||||||
5696 | diag::note_omp_explicit_dsa) | ||||||
5697 | << getOpenMPClauseName(OMPC_uniform); | ||||||
5698 | continue; | ||||||
5699 | } | ||||||
5700 | LinearArgs[CanonPVD] = E; | ||||||
5701 | if (E->isValueDependent() || E->isTypeDependent() || | ||||||
5702 | E->isInstantiationDependent() || | ||||||
5703 | E->containsUnexpandedParameterPack()) | ||||||
5704 | continue; | ||||||
5705 | (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, | ||||||
5706 | PVD->getOriginalType(), | ||||||
5707 | /*IsDeclareSimd=*/true); | ||||||
5708 | continue; | ||||||
5709 | } | ||||||
5710 | } | ||||||
5711 | if (isa<CXXThisExpr>(E)) { | ||||||
5712 | if (UniformedLinearThis) { | ||||||
5713 | Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) | ||||||
5714 | << getOpenMPClauseName(OMPC_linear) | ||||||
5715 | << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) | ||||||
5716 | << E->getSourceRange(); | ||||||
5717 | Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) | ||||||
5718 | << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform | ||||||
5719 | : OMPC_linear); | ||||||
5720 | continue; | ||||||
5721 | } | ||||||
5722 | UniformedLinearThis = E; | ||||||
5723 | if (E->isValueDependent() || E->isTypeDependent() || | ||||||
5724 | E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) | ||||||
5725 | continue; | ||||||
5726 | (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, | ||||||
5727 | E->getType(), /*IsDeclareSimd=*/true); | ||||||
5728 | continue; | ||||||
5729 | } | ||||||
5730 | Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) | ||||||
5731 | << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); | ||||||
5732 | } | ||||||
5733 | Expr *Step = nullptr; | ||||||
5734 | Expr *NewStep = nullptr; | ||||||
5735 | SmallVector<Expr *, 4> NewSteps; | ||||||
5736 | for (Expr *E : Steps) { | ||||||
5737 | // Skip the same step expression, it was checked already. | ||||||
5738 | if (Step == E || !E) { | ||||||
5739 | NewSteps.push_back(E ? NewStep : nullptr); | ||||||
5740 | continue; | ||||||
5741 | } | ||||||
5742 | Step = E; | ||||||
5743 | if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) | ||||||
5744 | if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { | ||||||
5745 | const VarDecl *CanonPVD = PVD->getCanonicalDecl(); | ||||||
5746 | if (UniformedArgs.count(CanonPVD) == 0) { | ||||||
5747 | Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) | ||||||
5748 | << Step->getSourceRange(); | ||||||
5749 | } else if (E->isValueDependent() || E->isTypeDependent() || | ||||||
5750 | E->isInstantiationDependent() || | ||||||
5751 | E->containsUnexpandedParameterPack() || | ||||||
5752 | CanonPVD->getType()->hasIntegerRepresentation()) { | ||||||
5753 | NewSteps.push_back(Step); | ||||||
5754 | } else { | ||||||
5755 | Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) | ||||||
5756 | << Step->getSourceRange(); | ||||||
5757 | } | ||||||
5758 | continue; | ||||||
5759 | } | ||||||
5760 | NewStep = Step; | ||||||
5761 | if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && | ||||||
5762 | !Step->isInstantiationDependent() && | ||||||
5763 | !Step->containsUnexpandedParameterPack()) { | ||||||
5764 | NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) | ||||||
5765 | .get(); | ||||||
5766 | if (NewStep) | ||||||
5767 | NewStep = VerifyIntegerConstantExpression(NewStep).get(); | ||||||
5768 | } | ||||||
5769 | NewSteps.push_back(NewStep); | ||||||
5770 | } | ||||||
5771 | auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( | ||||||
5772 | Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), | ||||||
5773 | Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), | ||||||
5774 | const_cast<Expr **>(NewAligns.data()), NewAligns.size(), | ||||||
5775 | const_cast<Expr **>(Linears.data()), Linears.size(), | ||||||
5776 | const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), | ||||||
5777 | NewSteps.data(), NewSteps.size(), SR); | ||||||
5778 | ADecl->addAttr(NewAttr); | ||||||
5779 | return DG; | ||||||
5780 | } | ||||||
5781 | |||||||
5782 | static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, | ||||||
5783 | QualType NewType) { | ||||||
5784 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5785, __PRETTY_FUNCTION__)) | ||||||
5785 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5785, __PRETTY_FUNCTION__)); | ||||||
5786 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5787, __PRETTY_FUNCTION__)) | ||||||
5787 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5787, __PRETTY_FUNCTION__)); | ||||||
5788 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5789, __PRETTY_FUNCTION__)) | ||||||
5789 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5789, __PRETTY_FUNCTION__)); | ||||||
5790 | // Synthesize parameters with the same types. | ||||||
5791 | FD->setType(NewType); | ||||||
5792 | SmallVector<ParmVarDecl *, 16> Params; | ||||||
5793 | for (const ParmVarDecl *P : FDWithProto->parameters()) { | ||||||
5794 | auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), | ||||||
5795 | SourceLocation(), nullptr, P->getType(), | ||||||
5796 | /*TInfo=*/nullptr, SC_None, nullptr); | ||||||
5797 | Param->setScopeInfo(0, Params.size()); | ||||||
5798 | Param->setImplicit(); | ||||||
5799 | Params.push_back(Param); | ||||||
5800 | } | ||||||
5801 | |||||||
5802 | FD->setParams(Params); | ||||||
5803 | } | ||||||
5804 | |||||||
5805 | Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI) | ||||||
5806 | : TI(&TI), NameSuffix(TI.getMangledName()) {} | ||||||
5807 | |||||||
5808 | FunctionDecl * | ||||||
5809 | Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S, | ||||||
5810 | Declarator &D) { | ||||||
5811 | IdentifierInfo *BaseII = D.getIdentifier(); | ||||||
5812 | LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(), | ||||||
5813 | LookupOrdinaryName); | ||||||
5814 | LookupParsedName(Lookup, S, &D.getCXXScopeSpec()); | ||||||
5815 | |||||||
5816 | TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); | ||||||
5817 | QualType FType = TInfo->getType(); | ||||||
5818 | |||||||
5819 | bool IsConstexpr = D.getDeclSpec().getConstexprSpecifier() == CSK_constexpr; | ||||||
5820 | bool IsConsteval = D.getDeclSpec().getConstexprSpecifier() == CSK_consteval; | ||||||
5821 | |||||||
5822 | FunctionDecl *BaseFD = nullptr; | ||||||
5823 | for (auto *Candidate : Lookup) { | ||||||
5824 | auto *UDecl = dyn_cast<FunctionDecl>(Candidate->getUnderlyingDecl()); | ||||||
5825 | if (!UDecl) | ||||||
5826 | continue; | ||||||
5827 | |||||||
5828 | // Don't specialize constexpr/consteval functions with | ||||||
5829 | // non-constexpr/consteval functions. | ||||||
5830 | if (UDecl->isConstexpr() && !IsConstexpr) | ||||||
5831 | continue; | ||||||
5832 | if (UDecl->isConsteval() && !IsConsteval) | ||||||
5833 | continue; | ||||||
5834 | |||||||
5835 | QualType NewType = Context.mergeFunctionTypes( | ||||||
5836 | FType, UDecl->getType(), /* OfBlockPointer */ false, | ||||||
5837 | /* Unqualified */ false, /* AllowCXX */ true); | ||||||
5838 | if (NewType.isNull()) | ||||||
5839 | continue; | ||||||
5840 | |||||||
5841 | // Found a base! | ||||||
5842 | BaseFD = UDecl; | ||||||
5843 | break; | ||||||
5844 | } | ||||||
5845 | if (!BaseFD) { | ||||||
5846 | BaseFD = cast<FunctionDecl>(ActOnDeclarator(S, D)); | ||||||
5847 | BaseFD->setImplicit(true); | ||||||
5848 | } | ||||||
5849 | |||||||
5850 | OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); | ||||||
5851 | std::string MangledName; | ||||||
5852 | MangledName += D.getIdentifier()->getName(); | ||||||
5853 | MangledName += getOpenMPVariantManglingSeparatorStr(); | ||||||
5854 | MangledName += DVScope.NameSuffix; | ||||||
5855 | IdentifierInfo &VariantII = Context.Idents.get(MangledName); | ||||||
5856 | |||||||
5857 | VariantII.setMangledOpenMPVariantName(true); | ||||||
5858 | D.SetIdentifier(&VariantII, D.getBeginLoc()); | ||||||
5859 | return BaseFD; | ||||||
5860 | } | ||||||
5861 | |||||||
5862 | void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( | ||||||
5863 | FunctionDecl *FD, FunctionDecl *BaseFD) { | ||||||
5864 | // Do not mark function as is used to prevent its emission if this is the | ||||||
5865 | // only place where it is used. | ||||||
5866 | EnterExpressionEvaluationContext Unevaluated( | ||||||
5867 | *this, Sema::ExpressionEvaluationContext::Unevaluated); | ||||||
5868 | |||||||
5869 | Expr *VariantFuncRef = DeclRefExpr::Create( | ||||||
5870 | Context, NestedNameSpecifierLoc(), SourceLocation(), FD, | ||||||
5871 | /* RefersToEnclosingVariableOrCapture */ false, | ||||||
5872 | /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue); | ||||||
5873 | |||||||
5874 | OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); | ||||||
5875 | auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit( | ||||||
5876 | Context, VariantFuncRef, DVScope.TI); | ||||||
5877 | BaseFD->addAttr(OMPDeclareVariantA); | ||||||
5878 | } | ||||||
5879 | |||||||
5880 | ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope, | ||||||
5881 | SourceLocation LParenLoc, | ||||||
5882 | MultiExprArg ArgExprs, | ||||||
5883 | SourceLocation RParenLoc, Expr *ExecConfig) { | ||||||
5884 | // The common case is a regular call we do not want to specialize at all. Try | ||||||
5885 | // to make that case fast by bailing early. | ||||||
5886 | CallExpr *CE = dyn_cast<CallExpr>(Call.get()); | ||||||
5887 | if (!CE) | ||||||
5888 | return Call; | ||||||
5889 | |||||||
5890 | FunctionDecl *CalleeFnDecl = CE->getDirectCallee(); | ||||||
5891 | if (!CalleeFnDecl) | ||||||
5892 | return Call; | ||||||
5893 | |||||||
5894 | if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>()) | ||||||
5895 | return Call; | ||||||
5896 | |||||||
5897 | ASTContext &Context = getASTContext(); | ||||||
5898 | std::function<void(StringRef)> DiagUnknownTrait = [this, | ||||||
5899 | CE](StringRef ISATrait) { | ||||||
5900 | // TODO Track the selector locations in a way that is accessible here to | ||||||
5901 | // improve the diagnostic location. | ||||||
5902 | Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait) | ||||||
5903 | << ISATrait; | ||||||
5904 | }; | ||||||
5905 | TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait), | ||||||
5906 | getCurFunctionDecl()); | ||||||
5907 | |||||||
5908 | SmallVector<Expr *, 4> Exprs; | ||||||
5909 | SmallVector<VariantMatchInfo, 4> VMIs; | ||||||
5910 | while (CalleeFnDecl) { | ||||||
5911 | for (OMPDeclareVariantAttr *A : | ||||||
5912 | CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) { | ||||||
5913 | Expr *VariantRef = A->getVariantFuncRef(); | ||||||
5914 | |||||||
5915 | VariantMatchInfo VMI; | ||||||
5916 | OMPTraitInfo &TI = A->getTraitInfo(); | ||||||
5917 | TI.getAsVariantMatchInfo(Context, VMI); | ||||||
5918 | if (!isVariantApplicableInContext(VMI, OMPCtx, | ||||||
5919 | /* DeviceSetOnly */ false)) | ||||||
5920 | continue; | ||||||
5921 | |||||||
5922 | VMIs.push_back(VMI); | ||||||
5923 | Exprs.push_back(VariantRef); | ||||||
5924 | } | ||||||
5925 | |||||||
5926 | CalleeFnDecl = CalleeFnDecl->getPreviousDecl(); | ||||||
5927 | } | ||||||
5928 | |||||||
5929 | ExprResult NewCall; | ||||||
5930 | do { | ||||||
5931 | int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx); | ||||||
5932 | if (BestIdx < 0) | ||||||
5933 | return Call; | ||||||
5934 | Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]); | ||||||
5935 | Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl(); | ||||||
5936 | |||||||
5937 | { | ||||||
5938 | // Try to build a (member) call expression for the current best applicable | ||||||
5939 | // variant expression. We allow this to fail in which case we continue | ||||||
5940 | // with the next best variant expression. The fail case is part of the | ||||||
5941 | // implementation defined behavior in the OpenMP standard when it talks | ||||||
5942 | // about what differences in the function prototypes: "Any differences | ||||||
5943 | // that the specific OpenMP context requires in the prototype of the | ||||||
5944 | // variant from the base function prototype are implementation defined." | ||||||
5945 | // This wording is there to allow the specialized variant to have a | ||||||
5946 | // different type than the base function. This is intended and OK but if | ||||||
5947 | // we cannot create a call the difference is not in the "implementation | ||||||
5948 | // defined range" we allow. | ||||||
5949 | Sema::TentativeAnalysisScope Trap(*this); | ||||||
5950 | |||||||
5951 | if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) { | ||||||
5952 | auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE); | ||||||
5953 | BestExpr = MemberExpr::CreateImplicit( | ||||||
5954 | Context, MemberCall->getImplicitObjectArgument(), | ||||||
5955 | /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy, | ||||||
5956 | MemberCall->getValueKind(), MemberCall->getObjectKind()); | ||||||
5957 | } | ||||||
5958 | NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, | ||||||
5959 | ExecConfig); | ||||||
5960 | if (NewCall.isUsable()) | ||||||
5961 | break; | ||||||
5962 | } | ||||||
5963 | |||||||
5964 | VMIs.erase(VMIs.begin() + BestIdx); | ||||||
5965 | Exprs.erase(Exprs.begin() + BestIdx); | ||||||
5966 | } while (!VMIs.empty()); | ||||||
5967 | |||||||
5968 | if (!NewCall.isUsable()) | ||||||
5969 | return Call; | ||||||
5970 | return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0); | ||||||
5971 | } | ||||||
5972 | |||||||
5973 | Optional<std::pair<FunctionDecl *, Expr *>> | ||||||
5974 | Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, | ||||||
5975 | Expr *VariantRef, OMPTraitInfo &TI, | ||||||
5976 | SourceRange SR) { | ||||||
5977 | if (!DG || DG.get().isNull()) | ||||||
5978 | return None; | ||||||
5979 | |||||||
5980 | const int VariantId = 1; | ||||||
5981 | // Must be applied only to single decl. | ||||||
5982 | if (!DG.get().isSingleDecl()) { | ||||||
5983 | Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) | ||||||
5984 | << VariantId << SR; | ||||||
5985 | return None; | ||||||
5986 | } | ||||||
5987 | Decl *ADecl = DG.get().getSingleDecl(); | ||||||
5988 | if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) | ||||||
5989 | ADecl = FTD->getTemplatedDecl(); | ||||||
5990 | |||||||
5991 | // Decl must be a function. | ||||||
5992 | auto *FD = dyn_cast<FunctionDecl>(ADecl); | ||||||
5993 | if (!FD) { | ||||||
5994 | Diag(ADecl->getLocation(), diag::err_omp_function_expected) | ||||||
5995 | << VariantId << SR; | ||||||
5996 | return None; | ||||||
5997 | } | ||||||
5998 | |||||||
5999 | auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { | ||||||
6000 | return FD->hasAttrs() && | ||||||
6001 | (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || | ||||||
6002 | FD->hasAttr<TargetAttr>()); | ||||||
6003 | }; | ||||||
6004 | // OpenMP is not compatible with CPU-specific attributes. | ||||||
6005 | if (HasMultiVersionAttributes(FD)) { | ||||||
6006 | Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) | ||||||
6007 | << SR; | ||||||
6008 | return None; | ||||||
6009 | } | ||||||
6010 | |||||||
6011 | // Allow #pragma omp declare variant only if the function is not used. | ||||||
6012 | if (FD->isUsed(false)) | ||||||
6013 | Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) | ||||||
6014 | << FD->getLocation(); | ||||||
6015 | |||||||
6016 | // Check if the function was emitted already. | ||||||
6017 | const FunctionDecl *Definition; | ||||||
6018 | if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && | ||||||
6019 | (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) | ||||||
6020 | Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) | ||||||
6021 | << FD->getLocation(); | ||||||
6022 | |||||||
6023 | // The VariantRef must point to function. | ||||||
6024 | if (!VariantRef) { | ||||||
6025 | Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; | ||||||
6026 | return None; | ||||||
6027 | } | ||||||
6028 | |||||||
6029 | auto ShouldDelayChecks = [](Expr *&E, bool) { | ||||||
6030 | return E && (E->isTypeDependent() || E->isValueDependent() || | ||||||
6031 | E->containsUnexpandedParameterPack() || | ||||||
6032 | E->isInstantiationDependent()); | ||||||
6033 | }; | ||||||
6034 | // Do not check templates, wait until instantiation. | ||||||
6035 | if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) || | ||||||
6036 | TI.anyScoreOrCondition(ShouldDelayChecks)) | ||||||
6037 | return std::make_pair(FD, VariantRef); | ||||||
6038 | |||||||
6039 | // Deal with non-constant score and user condition expressions. | ||||||
6040 | auto HandleNonConstantScoresAndConditions = [this](Expr *&E, | ||||||
6041 | bool IsScore) -> bool { | ||||||
6042 | if (!E || E->isIntegerConstantExpr(Context)) | ||||||
6043 | return false; | ||||||
6044 | |||||||
6045 | if (IsScore) { | ||||||
6046 | // We warn on non-constant scores and pretend they were not present. | ||||||
6047 | Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant) | ||||||
6048 | << E; | ||||||
6049 | E = nullptr; | ||||||
6050 | } else { | ||||||
6051 | // We could replace a non-constant user condition with "false" but we | ||||||
6052 | // will soon need to handle these anyway for the dynamic version of | ||||||
6053 | // OpenMP context selectors. | ||||||
6054 | Diag(E->getExprLoc(), | ||||||
6055 | diag::err_omp_declare_variant_user_condition_not_constant) | ||||||
6056 | << E; | ||||||
6057 | } | ||||||
6058 | return true; | ||||||
6059 | }; | ||||||
6060 | if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions)) | ||||||
6061 | return None; | ||||||
6062 | |||||||
6063 | // Convert VariantRef expression to the type of the original function to | ||||||
6064 | // resolve possible conflicts. | ||||||
6065 | ExprResult VariantRefCast; | ||||||
6066 | if (LangOpts.CPlusPlus) { | ||||||
6067 | QualType FnPtrType; | ||||||
6068 | auto *Method = dyn_cast<CXXMethodDecl>(FD); | ||||||
6069 | if (Method && !Method->isStatic()) { | ||||||
6070 | const Type *ClassType = | ||||||
6071 | Context.getTypeDeclType(Method->getParent()).getTypePtr(); | ||||||
6072 | FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); | ||||||
6073 | ExprResult ER; | ||||||
6074 | { | ||||||
6075 | // Build adrr_of unary op to correctly handle type checks for member | ||||||
6076 | // functions. | ||||||
6077 | Sema::TentativeAnalysisScope Trap(*this); | ||||||
6078 | ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, | ||||||
6079 | VariantRef); | ||||||
6080 | } | ||||||
6081 | if (!ER.isUsable()) { | ||||||
6082 | Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) | ||||||
6083 | << VariantId << VariantRef->getSourceRange(); | ||||||
6084 | return None; | ||||||
6085 | } | ||||||
6086 | VariantRef = ER.get(); | ||||||
6087 | } else { | ||||||
6088 | FnPtrType = Context.getPointerType(FD->getType()); | ||||||
6089 | } | ||||||
6090 | ImplicitConversionSequence ICS = | ||||||
6091 | TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), | ||||||
6092 | /*SuppressUserConversions=*/false, | ||||||
6093 | AllowedExplicit::None, | ||||||
6094 | /*InOverloadResolution=*/false, | ||||||
6095 | /*CStyle=*/false, | ||||||
6096 | /*AllowObjCWritebackConversion=*/false); | ||||||
6097 | if (ICS.isFailure()) { | ||||||
6098 | Diag(VariantRef->getExprLoc(), | ||||||
6099 | diag::err_omp_declare_variant_incompat_types) | ||||||
6100 | << VariantRef->getType() | ||||||
6101 | << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) | ||||||
6102 | << VariantRef->getSourceRange(); | ||||||
6103 | return None; | ||||||
6104 | } | ||||||
6105 | VariantRefCast = PerformImplicitConversion( | ||||||
6106 | VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); | ||||||
6107 | if (!VariantRefCast.isUsable()) | ||||||
6108 | return None; | ||||||
6109 | // Drop previously built artificial addr_of unary op for member functions. | ||||||
6110 | if (Method && !Method->isStatic()) { | ||||||
6111 | Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); | ||||||
6112 | if (auto *UO = dyn_cast<UnaryOperator>( | ||||||
6113 | PossibleAddrOfVariantRef->IgnoreImplicit())) | ||||||
6114 | VariantRefCast = UO->getSubExpr(); | ||||||
6115 | } | ||||||
6116 | } else { | ||||||
6117 | VariantRefCast = VariantRef; | ||||||
6118 | } | ||||||
6119 | |||||||
6120 | ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); | ||||||
6121 | if (!ER.isUsable() || | ||||||
6122 | !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { | ||||||
6123 | Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) | ||||||
6124 | << VariantId << VariantRef->getSourceRange(); | ||||||
6125 | return None; | ||||||
6126 | } | ||||||
6127 | |||||||
6128 | // The VariantRef must point to function. | ||||||
6129 | auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); | ||||||
6130 | if (!DRE) { | ||||||
6131 | Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) | ||||||
6132 | << VariantId << VariantRef->getSourceRange(); | ||||||
6133 | return None; | ||||||
6134 | } | ||||||
6135 | auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); | ||||||
6136 | if (!NewFD) { | ||||||
6137 | Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) | ||||||
6138 | << VariantId << VariantRef->getSourceRange(); | ||||||
6139 | return None; | ||||||
6140 | } | ||||||
6141 | |||||||
6142 | // Check if function types are compatible in C. | ||||||
6143 | if (!LangOpts.CPlusPlus) { | ||||||
6144 | QualType NewType = | ||||||
6145 | Context.mergeFunctionTypes(FD->getType(), NewFD->getType()); | ||||||
6146 | if (NewType.isNull()) { | ||||||
6147 | Diag(VariantRef->getExprLoc(), | ||||||
6148 | diag::err_omp_declare_variant_incompat_types) | ||||||
6149 | << NewFD->getType() << FD->getType() << VariantRef->getSourceRange(); | ||||||
6150 | return None; | ||||||
6151 | } | ||||||
6152 | if (NewType->isFunctionProtoType()) { | ||||||
6153 | if (FD->getType()->isFunctionNoProtoType()) | ||||||
6154 | setPrototype(*this, FD, NewFD, NewType); | ||||||
6155 | else if (NewFD->getType()->isFunctionNoProtoType()) | ||||||
6156 | setPrototype(*this, NewFD, FD, NewType); | ||||||
6157 | } | ||||||
6158 | } | ||||||
6159 | |||||||
6160 | // Check if variant function is not marked with declare variant directive. | ||||||
6161 | if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { | ||||||
6162 | Diag(VariantRef->getExprLoc(), | ||||||
6163 | diag::warn_omp_declare_variant_marked_as_declare_variant) | ||||||
6164 | << VariantRef->getSourceRange(); | ||||||
6165 | SourceRange SR = | ||||||
6166 | NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); | ||||||
6167 | Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; | ||||||
6168 | return None; | ||||||
6169 | } | ||||||
6170 | |||||||
6171 | enum DoesntSupport { | ||||||
6172 | VirtFuncs = 1, | ||||||
6173 | Constructors = 3, | ||||||
6174 | Destructors = 4, | ||||||
6175 | DeletedFuncs = 5, | ||||||
6176 | DefaultedFuncs = 6, | ||||||
6177 | ConstexprFuncs = 7, | ||||||
6178 | ConstevalFuncs = 8, | ||||||
6179 | }; | ||||||
6180 | if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { | ||||||
6181 | if (CXXFD->isVirtual()) { | ||||||
6182 | Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) | ||||||
6183 | << VirtFuncs; | ||||||
6184 | return None; | ||||||
6185 | } | ||||||
6186 | |||||||
6187 | if (isa<CXXConstructorDecl>(FD)) { | ||||||
6188 | Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) | ||||||
6189 | << Constructors; | ||||||
6190 | return None; | ||||||
6191 | } | ||||||
6192 | |||||||
6193 | if (isa<CXXDestructorDecl>(FD)) { | ||||||
6194 | Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) | ||||||
6195 | << Destructors; | ||||||
6196 | return None; | ||||||
6197 | } | ||||||
6198 | } | ||||||
6199 | |||||||
6200 | if (FD->isDeleted()) { | ||||||
6201 | Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) | ||||||
6202 | << DeletedFuncs; | ||||||
6203 | return None; | ||||||
6204 | } | ||||||
6205 | |||||||
6206 | if (FD->isDefaulted()) { | ||||||
6207 | Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) | ||||||
6208 | << DefaultedFuncs; | ||||||
6209 | return None; | ||||||
6210 | } | ||||||
6211 | |||||||
6212 | if (FD->isConstexpr()) { | ||||||
6213 | Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) | ||||||
6214 | << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); | ||||||
6215 | return None; | ||||||
6216 | } | ||||||
6217 | |||||||
6218 | // Check general compatibility. | ||||||
6219 | if (areMultiversionVariantFunctionsCompatible( | ||||||
6220 | FD, NewFD, PartialDiagnostic::NullDiagnostic(), | ||||||
6221 | PartialDiagnosticAt(SourceLocation(), | ||||||
6222 | PartialDiagnostic::NullDiagnostic()), | ||||||
6223 | PartialDiagnosticAt( | ||||||
6224 | VariantRef->getExprLoc(), | ||||||
6225 | PDiag(diag::err_omp_declare_variant_doesnt_support)), | ||||||
6226 | PartialDiagnosticAt(VariantRef->getExprLoc(), | ||||||
6227 | PDiag(diag::err_omp_declare_variant_diff) | ||||||
6228 | << FD->getLocation()), | ||||||
6229 | /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, | ||||||
6230 | /*CLinkageMayDiffer=*/true)) | ||||||
6231 | return None; | ||||||
6232 | return std::make_pair(FD, cast<Expr>(DRE)); | ||||||
6233 | } | ||||||
6234 | |||||||
6235 | void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, | ||||||
6236 | Expr *VariantRef, | ||||||
6237 | OMPTraitInfo &TI, | ||||||
6238 | SourceRange SR) { | ||||||
6239 | auto *NewAttr = | ||||||
6240 | OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR); | ||||||
6241 | FD->addAttr(NewAttr); | ||||||
6242 | } | ||||||
6243 | |||||||
6244 | StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, | ||||||
6245 | Stmt *AStmt, | ||||||
6246 | SourceLocation StartLoc, | ||||||
6247 | SourceLocation EndLoc) { | ||||||
6248 | if (!AStmt) | ||||||
6249 | return StmtError(); | ||||||
6250 | |||||||
6251 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
6252 | // 1.2.2 OpenMP Language Terminology | ||||||
6253 | // Structured block - An executable statement with a single entry at the | ||||||
6254 | // top and a single exit at the bottom. | ||||||
6255 | // The point of exit cannot be a branch out of the structured block. | ||||||
6256 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
6257 | CS->getCapturedDecl()->setNothrow(); | ||||||
6258 | |||||||
6259 | setFunctionHasBranchProtectedScope(); | ||||||
6260 | |||||||
6261 | return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, | ||||||
6262 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), | ||||||
6263 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||
6264 | } | ||||||
6265 | |||||||
6266 | namespace { | ||||||
6267 | /// Iteration space of a single for loop. | ||||||
6268 | struct LoopIterationSpace final { | ||||||
6269 | /// True if the condition operator is the strict compare operator (<, > or | ||||||
6270 | /// !=). | ||||||
6271 | bool IsStrictCompare = false; | ||||||
6272 | /// Condition of the loop. | ||||||
6273 | Expr *PreCond = nullptr; | ||||||
6274 | /// This expression calculates the number of iterations in the loop. | ||||||
6275 | /// It is always possible to calculate it before starting the loop. | ||||||
6276 | Expr *NumIterations = nullptr; | ||||||
6277 | /// The loop counter variable. | ||||||
6278 | Expr *CounterVar = nullptr; | ||||||
6279 | /// Private loop counter variable. | ||||||
6280 | Expr *PrivateCounterVar = nullptr; | ||||||
6281 | /// This is initializer for the initial value of #CounterVar. | ||||||
6282 | Expr *CounterInit = nullptr; | ||||||
6283 | /// This is step for the #CounterVar used to generate its update: | ||||||
6284 | /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. | ||||||
6285 | Expr *CounterStep = nullptr; | ||||||
6286 | /// Should step be subtracted? | ||||||
6287 | bool Subtract = false; | ||||||
6288 | /// Source range of the loop init. | ||||||
6289 | SourceRange InitSrcRange; | ||||||
6290 | /// Source range of the loop condition. | ||||||
6291 | SourceRange CondSrcRange; | ||||||
6292 | /// Source range of the loop increment. | ||||||
6293 | SourceRange IncSrcRange; | ||||||
6294 | /// Minimum value that can have the loop control variable. Used to support | ||||||
6295 | /// non-rectangular loops. Applied only for LCV with the non-iterator types, | ||||||
6296 | /// since only such variables can be used in non-loop invariant expressions. | ||||||
6297 | Expr *MinValue = nullptr; | ||||||
6298 | /// Maximum value that can have the loop control variable. Used to support | ||||||
6299 | /// non-rectangular loops. Applied only for LCV with the non-iterator type, | ||||||
6300 | /// since only such variables can be used in non-loop invariant expressions. | ||||||
6301 | Expr *MaxValue = nullptr; | ||||||
6302 | /// true, if the lower bound depends on the outer loop control var. | ||||||
6303 | bool IsNonRectangularLB = false; | ||||||
6304 | /// true, if the upper bound depends on the outer loop control var. | ||||||
6305 | bool IsNonRectangularUB = false; | ||||||
6306 | /// Index of the loop this loop depends on and forms non-rectangular loop | ||||||
6307 | /// nest. | ||||||
6308 | unsigned LoopDependentIdx = 0; | ||||||
6309 | /// Final condition for the non-rectangular loop nest support. It is used to | ||||||
6310 | /// check that the number of iterations for this particular counter must be | ||||||
6311 | /// finished. | ||||||
6312 | Expr *FinalCondition = nullptr; | ||||||
6313 | }; | ||||||
6314 | |||||||
6315 | /// Helper class for checking canonical form of the OpenMP loops and | ||||||
6316 | /// extracting iteration space of each loop in the loop nest, that will be used | ||||||
6317 | /// for IR generation. | ||||||
6318 | class OpenMPIterationSpaceChecker { | ||||||
6319 | /// Reference to Sema. | ||||||
6320 | Sema &SemaRef; | ||||||
6321 | /// Data-sharing stack. | ||||||
6322 | DSAStackTy &Stack; | ||||||
6323 | /// A location for diagnostics (when there is no some better location). | ||||||
6324 | SourceLocation DefaultLoc; | ||||||
6325 | /// A location for diagnostics (when increment is not compatible). | ||||||
6326 | SourceLocation ConditionLoc; | ||||||
6327 | /// A source location for referring to loop init later. | ||||||
6328 | SourceRange InitSrcRange; | ||||||
6329 | /// A source location for referring to condition later. | ||||||
6330 | SourceRange ConditionSrcRange; | ||||||
6331 | /// A source location for referring to increment later. | ||||||
6332 | SourceRange IncrementSrcRange; | ||||||
6333 | /// Loop variable. | ||||||
6334 | ValueDecl *LCDecl = nullptr; | ||||||
6335 | /// Reference to loop variable. | ||||||
6336 | Expr *LCRef = nullptr; | ||||||
6337 | /// Lower bound (initializer for the var). | ||||||
6338 | Expr *LB = nullptr; | ||||||
6339 | /// Upper bound. | ||||||
6340 | Expr *UB = nullptr; | ||||||
6341 | /// Loop step (increment). | ||||||
6342 | Expr *Step = nullptr; | ||||||
6343 | /// This flag is true when condition is one of: | ||||||
6344 | /// Var < UB | ||||||
6345 | /// Var <= UB | ||||||
6346 | /// UB > Var | ||||||
6347 | /// UB >= Var | ||||||
6348 | /// This will have no value when the condition is != | ||||||
6349 | llvm::Optional<bool> TestIsLessOp; | ||||||
6350 | /// This flag is true when condition is strict ( < or > ). | ||||||
6351 | bool TestIsStrictOp = false; | ||||||
6352 | /// This flag is true when step is subtracted on each iteration. | ||||||
6353 | bool SubtractStep = false; | ||||||
6354 | /// The outer loop counter this loop depends on (if any). | ||||||
6355 | const ValueDecl *DepDecl = nullptr; | ||||||
6356 | /// Contains number of loop (starts from 1) on which loop counter init | ||||||
6357 | /// expression of this loop depends on. | ||||||
6358 | Optional<unsigned> InitDependOnLC; | ||||||
6359 | /// Contains number of loop (starts from 1) on which loop counter condition | ||||||
6360 | /// expression of this loop depends on. | ||||||
6361 | Optional<unsigned> CondDependOnLC; | ||||||
6362 | /// Checks if the provide statement depends on the loop counter. | ||||||
6363 | Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); | ||||||
6364 | /// Original condition required for checking of the exit condition for | ||||||
6365 | /// non-rectangular loop. | ||||||
6366 | Expr *Condition = nullptr; | ||||||
6367 | |||||||
6368 | public: | ||||||
6369 | OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, | ||||||
6370 | SourceLocation DefaultLoc) | ||||||
6371 | : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), | ||||||
6372 | ConditionLoc(DefaultLoc) {} | ||||||
6373 | /// Check init-expr for canonical loop form and save loop counter | ||||||
6374 | /// variable - #Var and its initialization value - #LB. | ||||||
6375 | bool checkAndSetInit(Stmt *S, bool EmitDiags = true); | ||||||
6376 | /// Check test-expr for canonical form, save upper-bound (#UB), flags | ||||||
6377 | /// for less/greater and for strict/non-strict comparison. | ||||||
6378 | bool checkAndSetCond(Expr *S); | ||||||
6379 | /// Check incr-expr for canonical loop form and return true if it | ||||||
6380 | /// does not conform, otherwise save loop step (#Step). | ||||||
6381 | bool checkAndSetInc(Expr *S); | ||||||
6382 | /// Return the loop counter variable. | ||||||
6383 | ValueDecl *getLoopDecl() const { return LCDecl; } | ||||||
6384 | /// Return the reference expression to loop counter variable. | ||||||
6385 | Expr *getLoopDeclRefExpr() const { return LCRef; } | ||||||
6386 | /// Source range of the loop init. | ||||||
6387 | SourceRange getInitSrcRange() const { return InitSrcRange; } | ||||||
6388 | /// Source range of the loop condition. | ||||||
6389 | SourceRange getConditionSrcRange() const { return ConditionSrcRange; } | ||||||
6390 | /// Source range of the loop increment. | ||||||
6391 | SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } | ||||||
6392 | /// True if the step should be subtracted. | ||||||
6393 | bool shouldSubtractStep() const { return SubtractStep; } | ||||||
6394 | /// True, if the compare operator is strict (<, > or !=). | ||||||
6395 | bool isStrictTestOp() const { return TestIsStrictOp; } | ||||||
6396 | /// Build the expression to calculate the number of iterations. | ||||||
6397 | Expr *buildNumIterations( | ||||||
6398 | Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, | ||||||
6399 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; | ||||||
6400 | /// Build the precondition expression for the loops. | ||||||
6401 | Expr * | ||||||
6402 | buildPreCond(Scope *S, Expr *Cond, | ||||||
6403 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; | ||||||
6404 | /// Build reference expression to the counter be used for codegen. | ||||||
6405 | DeclRefExpr * | ||||||
6406 | buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, | ||||||
6407 | DSAStackTy &DSA) const; | ||||||
6408 | /// Build reference expression to the private counter be used for | ||||||
6409 | /// codegen. | ||||||
6410 | Expr *buildPrivateCounterVar() const; | ||||||
6411 | /// Build initialization of the counter be used for codegen. | ||||||
6412 | Expr *buildCounterInit() const; | ||||||
6413 | /// Build step of the counter be used for codegen. | ||||||
6414 | Expr *buildCounterStep() const; | ||||||
6415 | /// Build loop data with counter value for depend clauses in ordered | ||||||
6416 | /// directives. | ||||||
6417 | Expr * | ||||||
6418 | buildOrderedLoopData(Scope *S, Expr *Counter, | ||||||
6419 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, | ||||||
6420 | SourceLocation Loc, Expr *Inc = nullptr, | ||||||
6421 | OverloadedOperatorKind OOK = OO_Amp); | ||||||
6422 | /// Builds the minimum value for the loop counter. | ||||||
6423 | std::pair<Expr *, Expr *> buildMinMaxValues( | ||||||
6424 | Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; | ||||||
6425 | /// Builds final condition for the non-rectangular loops. | ||||||
6426 | Expr *buildFinalCondition(Scope *S) const; | ||||||
6427 | /// Return true if any expression is dependent. | ||||||
6428 | bool dependent() const; | ||||||
6429 | /// Returns true if the initializer forms non-rectangular loop. | ||||||
6430 | bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } | ||||||
6431 | /// Returns true if the condition forms non-rectangular loop. | ||||||
6432 | bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } | ||||||
6433 | /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. | ||||||
6434 | unsigned getLoopDependentIdx() const { | ||||||
6435 | return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); | ||||||
6436 | } | ||||||
6437 | |||||||
6438 | private: | ||||||
6439 | /// Check the right-hand side of an assignment in the increment | ||||||
6440 | /// expression. | ||||||
6441 | bool checkAndSetIncRHS(Expr *RHS); | ||||||
6442 | /// Helper to set loop counter variable and its initializer. | ||||||
6443 | bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, | ||||||
6444 | bool EmitDiags); | ||||||
6445 | /// Helper to set upper bound. | ||||||
6446 | bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, | ||||||
6447 | SourceRange SR, SourceLocation SL); | ||||||
6448 | /// Helper to set loop increment. | ||||||
6449 | bool setStep(Expr *NewStep, bool Subtract); | ||||||
6450 | }; | ||||||
6451 | |||||||
6452 | bool OpenMPIterationSpaceChecker::dependent() const { | ||||||
6453 | if (!LCDecl) { | ||||||
6454 | assert(!LB && !UB && !Step)((!LB && !UB && !Step) ? static_cast<void> (0) : __assert_fail ("!LB && !UB && !Step", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 6454, __PRETTY_FUNCTION__)); | ||||||
6455 | return false; | ||||||
6456 | } | ||||||
6457 | return LCDecl->getType()->isDependentType() || | ||||||
6458 | (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || | ||||||
6459 | (Step && Step->isValueDependent()); | ||||||
6460 | } | ||||||
6461 | |||||||
6462 | bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, | ||||||
6463 | Expr *NewLCRefExpr, | ||||||
6464 | Expr *NewLB, bool EmitDiags) { | ||||||
6465 | // State consistency checking to ensure correct usage. | ||||||
6466 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 6467, __PRETTY_FUNCTION__)) | ||||||
6467 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 6467, __PRETTY_FUNCTION__)); | ||||||
6468 | if (!NewLCDecl || !NewLB) | ||||||
6469 | return true; | ||||||
6470 | LCDecl = getCanonicalDecl(NewLCDecl); | ||||||
6471 | LCRef = NewLCRefExpr; | ||||||
6472 | if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) | ||||||
6473 | if (const CXXConstructorDecl *Ctor = CE->getConstructor()) | ||||||
6474 | if ((Ctor->isCopyOrMoveConstructor() || | ||||||
6475 | Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && | ||||||
6476 | CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) | ||||||
6477 | NewLB = CE->getArg(0)->IgnoreParenImpCasts(); | ||||||
6478 | LB = NewLB; | ||||||
6479 | if (EmitDiags) | ||||||
6480 | InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); | ||||||
6481 | return false; | ||||||
6482 | } | ||||||
6483 | |||||||
6484 | bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, | ||||||
6485 | llvm::Optional<bool> LessOp, | ||||||
6486 | bool StrictOp, SourceRange SR, | ||||||
6487 | SourceLocation SL) { | ||||||
6488 | // State consistency checking to ensure correct usage. | ||||||
6489 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 6490, __PRETTY_FUNCTION__)) | ||||||
6490 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 6490, __PRETTY_FUNCTION__)); | ||||||
6491 | if (!NewUB) | ||||||
6492 | return true; | ||||||
6493 | UB = NewUB; | ||||||
6494 | if (LessOp) | ||||||
6495 | TestIsLessOp = LessOp; | ||||||
6496 | TestIsStrictOp = StrictOp; | ||||||
6497 | ConditionSrcRange = SR; | ||||||
6498 | ConditionLoc = SL; | ||||||
6499 | CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); | ||||||
6500 | return false; | ||||||
6501 | } | ||||||
6502 | |||||||
6503 | bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { | ||||||
6504 | // State consistency checking to ensure correct usage. | ||||||
6505 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 6505, __PRETTY_FUNCTION__)); | ||||||
6506 | if (!NewStep) | ||||||
6507 | return true; | ||||||
6508 | if (!NewStep->isValueDependent()) { | ||||||
6509 | // Check that the step is integer expression. | ||||||
6510 | SourceLocation StepLoc = NewStep->getBeginLoc(); | ||||||
6511 | ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( | ||||||
6512 | StepLoc, getExprAsWritten(NewStep)); | ||||||
6513 | if (Val.isInvalid()) | ||||||
6514 | return true; | ||||||
6515 | NewStep = Val.get(); | ||||||
6516 | |||||||
6517 | // OpenMP [2.6, Canonical Loop Form, Restrictions] | ||||||
6518 | // If test-expr is of form var relational-op b and relational-op is < or | ||||||
6519 | // <= then incr-expr must cause var to increase on each iteration of the | ||||||
6520 | // loop. If test-expr is of form var relational-op b and relational-op is | ||||||
6521 | // > or >= then incr-expr must cause var to decrease on each iteration of | ||||||
6522 | // the loop. | ||||||
6523 | // If test-expr is of form b relational-op var and relational-op is < or | ||||||
6524 | // <= then incr-expr must cause var to decrease on each iteration of the | ||||||
6525 | // loop. If test-expr is of form b relational-op var and relational-op is | ||||||
6526 | // > or >= then incr-expr must cause var to increase on each iteration of | ||||||
6527 | // the loop. | ||||||
6528 | Optional<llvm::APSInt> Result = | ||||||
6529 | NewStep->getIntegerConstantExpr(SemaRef.Context); | ||||||
6530 | bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); | ||||||
6531 | bool IsConstNeg = | ||||||
6532 | Result && Result->isSigned() && (Subtract != Result->isNegative()); | ||||||
6533 | bool IsConstPos = | ||||||
6534 | Result && Result->isSigned() && (Subtract == Result->isNegative()); | ||||||
6535 | bool IsConstZero = Result && !Result->getBoolValue(); | ||||||
6536 | |||||||
6537 | // != with increment is treated as <; != with decrement is treated as > | ||||||
6538 | if (!TestIsLessOp.hasValue()) | ||||||
6539 | TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); | ||||||
6540 | if (UB && (IsConstZero || | ||||||
6541 | (TestIsLessOp.getValue() ? | ||||||
6542 | (IsConstNeg || (IsUnsigned && Subtract)) : | ||||||
6543 | (IsConstPos || (IsUnsigned && !Subtract))))) { | ||||||
6544 | SemaRef.Diag(NewStep->getExprLoc(), | ||||||
6545 | diag::err_omp_loop_incr_not_compatible) | ||||||
6546 | << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); | ||||||
6547 | SemaRef.Diag(ConditionLoc, | ||||||
6548 | diag::note_omp_loop_cond_requres_compatible_incr) | ||||||
6549 | << TestIsLessOp.getValue() << ConditionSrcRange; | ||||||
6550 | return true; | ||||||
6551 | } | ||||||
6552 | if (TestIsLessOp.getValue() == Subtract) { | ||||||
6553 | NewStep = | ||||||
6554 | SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) | ||||||
6555 | .get(); | ||||||
6556 | Subtract = !Subtract; | ||||||
6557 | } | ||||||
6558 | } | ||||||
6559 | |||||||
6560 | Step = NewStep; | ||||||
6561 | SubtractStep = Subtract; | ||||||
6562 | return false; | ||||||
6563 | } | ||||||
6564 | |||||||
6565 | namespace { | ||||||
6566 | /// Checker for the non-rectangular loops. Checks if the initializer or | ||||||
6567 | /// condition expression references loop counter variable. | ||||||
6568 | class LoopCounterRefChecker final | ||||||
6569 | : public ConstStmtVisitor<LoopCounterRefChecker, bool> { | ||||||
6570 | Sema &SemaRef; | ||||||
6571 | DSAStackTy &Stack; | ||||||
6572 | const ValueDecl *CurLCDecl = nullptr; | ||||||
6573 | const ValueDecl *DepDecl = nullptr; | ||||||
6574 | const ValueDecl *PrevDepDecl = nullptr; | ||||||
6575 | bool IsInitializer = true; | ||||||
6576 | unsigned BaseLoopId = 0; | ||||||
6577 | bool checkDecl(const Expr *E, const ValueDecl *VD) { | ||||||
6578 | if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { | ||||||
6579 | SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) | ||||||
6580 | << (IsInitializer ? 0 : 1); | ||||||
6581 | return false; | ||||||
6582 | } | ||||||
6583 | const auto &&Data = Stack.isLoopControlVariable(VD); | ||||||
6584 | // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. | ||||||
6585 | // The type of the loop iterator on which we depend may not have a random | ||||||
6586 | // access iterator type. | ||||||
6587 | if (Data.first && VD->getType()->isRecordType()) { | ||||||
6588 | SmallString<128> Name; | ||||||
6589 | llvm::raw_svector_ostream OS(Name); | ||||||
6590 | VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), | ||||||
6591 | /*Qualified=*/true); | ||||||
6592 | SemaRef.Diag(E->getExprLoc(), | ||||||
6593 | diag::err_omp_wrong_dependency_iterator_type) | ||||||
6594 | << OS.str(); | ||||||
6595 | SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; | ||||||
6596 | return false; | ||||||
6597 | } | ||||||
6598 | if (Data.first && | ||||||
6599 | (DepDecl || (PrevDepDecl && | ||||||
6600 | getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { | ||||||
6601 | if (!DepDecl && PrevDepDecl) | ||||||
6602 | DepDecl = PrevDepDecl; | ||||||
6603 | SmallString<128> Name; | ||||||
6604 | llvm::raw_svector_ostream OS(Name); | ||||||
6605 | DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), | ||||||
6606 | /*Qualified=*/true); | ||||||
6607 | SemaRef.Diag(E->getExprLoc(), | ||||||
6608 | diag::err_omp_invariant_or_linear_dependency) | ||||||
6609 | << OS.str(); | ||||||
6610 | return false; | ||||||
6611 | } | ||||||
6612 | if (Data.first) { | ||||||
6613 | DepDecl = VD; | ||||||
6614 | BaseLoopId = Data.first; | ||||||
6615 | } | ||||||
6616 | return Data.first; | ||||||
6617 | } | ||||||
6618 | |||||||
6619 | public: | ||||||
6620 | bool VisitDeclRefExpr(const DeclRefExpr *E) { | ||||||
6621 | const ValueDecl *VD = E->getDecl(); | ||||||
6622 | if (isa<VarDecl>(VD)) | ||||||
6623 | return checkDecl(E, VD); | ||||||
6624 | return false; | ||||||
6625 | } | ||||||
6626 | bool VisitMemberExpr(const MemberExpr *E) { | ||||||
6627 | if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { | ||||||
6628 | const ValueDecl *VD = E->getMemberDecl(); | ||||||
6629 | if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) | ||||||
6630 | return checkDecl(E, VD); | ||||||
6631 | } | ||||||
6632 | return false; | ||||||
6633 | } | ||||||
6634 | bool VisitStmt(const Stmt *S) { | ||||||
6635 | bool Res = false; | ||||||
6636 | for (const Stmt *Child : S->children()) | ||||||
6637 | Res = (Child && Visit(Child)) || Res; | ||||||
6638 | return Res; | ||||||
6639 | } | ||||||
6640 | explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, | ||||||
6641 | const ValueDecl *CurLCDecl, bool IsInitializer, | ||||||
6642 | const ValueDecl *PrevDepDecl = nullptr) | ||||||
6643 | : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), | ||||||
6644 | PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} | ||||||
6645 | unsigned getBaseLoopId() const { | ||||||
6646 | assert(CurLCDecl && "Expected loop dependency.")((CurLCDecl && "Expected loop dependency.") ? static_cast <void> (0) : __assert_fail ("CurLCDecl && \"Expected loop dependency.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 6646, __PRETTY_FUNCTION__)); | ||||||
6647 | return BaseLoopId; | ||||||
6648 | } | ||||||
6649 | const ValueDecl *getDepDecl() const { | ||||||
6650 | assert(CurLCDecl && "Expected loop dependency.")((CurLCDecl && "Expected loop dependency.") ? static_cast <void> (0) : __assert_fail ("CurLCDecl && \"Expected loop dependency.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 6650, __PRETTY_FUNCTION__)); | ||||||
6651 | return DepDecl; | ||||||
6652 | } | ||||||
6653 | }; | ||||||
6654 | } // namespace | ||||||
6655 | |||||||
6656 | Optional<unsigned> | ||||||
6657 | OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, | ||||||
6658 | bool IsInitializer) { | ||||||
6659 | // Check for the non-rectangular loops. | ||||||
6660 | LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, | ||||||
6661 | DepDecl); | ||||||
6662 | if (LoopStmtChecker.Visit(S)) { | ||||||
6663 | DepDecl = LoopStmtChecker.getDepDecl(); | ||||||
6664 | return LoopStmtChecker.getBaseLoopId(); | ||||||
6665 | } | ||||||
6666 | return llvm::None; | ||||||
6667 | } | ||||||
6668 | |||||||
6669 | bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { | ||||||
6670 | // Check init-expr for canonical loop form and save loop counter | ||||||
6671 | // variable - #Var and its initialization value - #LB. | ||||||
6672 | // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: | ||||||
6673 | // var = lb | ||||||
6674 | // integer-type var = lb | ||||||
6675 | // random-access-iterator-type var = lb | ||||||
6676 | // pointer-type var = lb | ||||||
6677 | // | ||||||
6678 | if (!S) { | ||||||
6679 | if (EmitDiags) { | ||||||
6680 | SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); | ||||||
6681 | } | ||||||
6682 | return true; | ||||||
6683 | } | ||||||
6684 | if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) | ||||||
6685 | if (!ExprTemp->cleanupsHaveSideEffects()) | ||||||
6686 | S = ExprTemp->getSubExpr(); | ||||||
6687 | |||||||
6688 | InitSrcRange = S->getSourceRange(); | ||||||
6689 | if (Expr *E = dyn_cast<Expr>(S)) | ||||||
6690 | S = E->IgnoreParens(); | ||||||
6691 | if (auto *BO = dyn_cast<BinaryOperator>(S)) { | ||||||
6692 | if (BO->getOpcode() == BO_Assign) { | ||||||
6693 | Expr *LHS = BO->getLHS()->IgnoreParens(); | ||||||
6694 | if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { | ||||||
6695 | if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) | ||||||
6696 | if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) | ||||||
6697 | return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), | ||||||
6698 | EmitDiags); | ||||||
6699 | return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); | ||||||
6700 | } | ||||||
6701 | if (auto *ME = dyn_cast<MemberExpr>(LHS)) { | ||||||
6702 | if (ME->isArrow() && | ||||||
6703 | isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) | ||||||
6704 | return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), | ||||||
6705 | EmitDiags); | ||||||
6706 | } | ||||||
6707 | } | ||||||
6708 | } else if (auto *DS = dyn_cast<DeclStmt>(S)) { | ||||||
6709 | if (DS->isSingleDecl()) { | ||||||
6710 | if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { | ||||||
6711 | if (Var->hasInit() && !Var->getType()->isReferenceType()) { | ||||||
6712 | // Accept non-canonical init form here but emit ext. warning. | ||||||
6713 | if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) | ||||||
6714 | SemaRef.Diag(S->getBeginLoc(), | ||||||
6715 | diag::ext_omp_loop_not_canonical_init) | ||||||
6716 | << S->getSourceRange(); | ||||||
6717 | return setLCDeclAndLB( | ||||||
6718 | Var, | ||||||
6719 | buildDeclRefExpr(SemaRef, Var, | ||||||
6720 | Var->getType().getNonReferenceType(), | ||||||
6721 | DS->getBeginLoc()), | ||||||
6722 | Var->getInit(), EmitDiags); | ||||||
6723 | } | ||||||
6724 | } | ||||||
6725 | } | ||||||
6726 | } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { | ||||||
6727 | if (CE->getOperator() == OO_Equal) { | ||||||
6728 | Expr *LHS = CE->getArg(0); | ||||||
6729 | if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { | ||||||
6730 | if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) | ||||||
6731 | if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) | ||||||
6732 | return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), | ||||||
6733 | EmitDiags); | ||||||
6734 | return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); | ||||||
6735 | } | ||||||
6736 | if (auto *ME = dyn_cast<MemberExpr>(LHS)) { | ||||||
6737 | if (ME->isArrow() && | ||||||
6738 | isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) | ||||||
6739 | return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), | ||||||
6740 | EmitDiags); | ||||||
6741 | } | ||||||
6742 | } | ||||||
6743 | } | ||||||
6744 | |||||||
6745 | if (dependent() || SemaRef.CurContext->isDependentContext()) | ||||||
6746 | return false; | ||||||
6747 | if (EmitDiags) { | ||||||
6748 | SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) | ||||||
6749 | << S->getSourceRange(); | ||||||
6750 | } | ||||||
6751 | return true; | ||||||
6752 | } | ||||||
6753 | |||||||
6754 | /// Ignore parenthesizes, implicit casts, copy constructor and return the | ||||||
6755 | /// variable (which may be the loop variable) if possible. | ||||||
6756 | static const ValueDecl *getInitLCDecl(const Expr *E) { | ||||||
6757 | if (!E) | ||||||
6758 | return nullptr; | ||||||
6759 | E = getExprAsWritten(E); | ||||||
6760 | if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) | ||||||
6761 | if (const CXXConstructorDecl *Ctor = CE->getConstructor()) | ||||||
6762 | if ((Ctor->isCopyOrMoveConstructor() || | ||||||
6763 | Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && | ||||||
6764 | CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) | ||||||
6765 | E = CE->getArg(0)->IgnoreParenImpCasts(); | ||||||
6766 | if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { | ||||||
6767 | if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) | ||||||
6768 | return getCanonicalDecl(VD); | ||||||
6769 | } | ||||||
6770 | if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) | ||||||
6771 | if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) | ||||||
6772 | return getCanonicalDecl(ME->getMemberDecl()); | ||||||
6773 | return nullptr; | ||||||
6774 | } | ||||||
6775 | |||||||
6776 | bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { | ||||||
6777 | // Check test-expr for canonical form, save upper-bound UB, flags for | ||||||
6778 | // less/greater and for strict/non-strict comparison. | ||||||
6779 | // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: | ||||||
6780 | // var relational-op b | ||||||
6781 | // b relational-op var | ||||||
6782 | // | ||||||
6783 | bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; | ||||||
6784 | if (!S) { | ||||||
6785 | SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) | ||||||
6786 | << (IneqCondIsCanonical ? 1 : 0) << LCDecl; | ||||||
6787 | return true; | ||||||
6788 | } | ||||||
6789 | Condition = S; | ||||||
6790 | S = getExprAsWritten(S); | ||||||
6791 | SourceLocation CondLoc = S->getBeginLoc(); | ||||||
6792 | if (auto *BO = dyn_cast<BinaryOperator>(S)) { | ||||||
6793 | if (BO->isRelationalOp()) { | ||||||
6794 | if (getInitLCDecl(BO->getLHS()) == LCDecl) | ||||||
6795 | return setUB(BO->getRHS(), | ||||||
6796 | (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), | ||||||
6797 | (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), | ||||||
6798 | BO->getSourceRange(), BO->getOperatorLoc()); | ||||||
6799 | if (getInitLCDecl(BO->getRHS()) == LCDecl) | ||||||
6800 | return setUB(BO->getLHS(), | ||||||
6801 | (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), | ||||||
6802 | (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), | ||||||
6803 | BO->getSourceRange(), BO->getOperatorLoc()); | ||||||
6804 | } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) | ||||||
6805 | return setUB( | ||||||
6806 | getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), | ||||||
6807 | /*LessOp=*/llvm::None, | ||||||
6808 | /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); | ||||||
6809 | } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { | ||||||
6810 | if (CE->getNumArgs() == 2) { | ||||||
6811 | auto Op = CE->getOperator(); | ||||||
6812 | switch (Op) { | ||||||
6813 | case OO_Greater: | ||||||
6814 | case OO_GreaterEqual: | ||||||
6815 | case OO_Less: | ||||||
6816 | case OO_LessEqual: | ||||||
6817 | if (getInitLCDecl(CE->getArg(0)) == LCDecl) | ||||||
6818 | return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, | ||||||
6819 | Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), | ||||||
6820 | CE->getOperatorLoc()); | ||||||
6821 | if (getInitLCDecl(CE->getArg(1)) == LCDecl) | ||||||
6822 | return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, | ||||||
6823 | Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), | ||||||
6824 | CE->getOperatorLoc()); | ||||||
6825 | break; | ||||||
6826 | case OO_ExclaimEqual: | ||||||
6827 | if (IneqCondIsCanonical) | ||||||
6828 | return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) | ||||||
6829 | : CE->getArg(0), | ||||||
6830 | /*LessOp=*/llvm::None, | ||||||
6831 | /*StrictOp=*/true, CE->getSourceRange(), | ||||||
6832 | CE->getOperatorLoc()); | ||||||
6833 | break; | ||||||
6834 | default: | ||||||
6835 | break; | ||||||
6836 | } | ||||||
6837 | } | ||||||
6838 | } | ||||||
6839 | if (dependent() || SemaRef.CurContext->isDependentContext()) | ||||||
6840 | return false; | ||||||
6841 | SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) | ||||||
6842 | << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; | ||||||
6843 | return true; | ||||||
6844 | } | ||||||
6845 | |||||||
6846 | bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { | ||||||
6847 | // RHS of canonical loop form increment can be: | ||||||
6848 | // var + incr | ||||||
6849 | // incr + var | ||||||
6850 | // var - incr | ||||||
6851 | // | ||||||
6852 | RHS = RHS->IgnoreParenImpCasts(); | ||||||
6853 | if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { | ||||||
6854 | if (BO->isAdditiveOp()) { | ||||||
6855 | bool IsAdd = BO->getOpcode() == BO_Add; | ||||||
6856 | if (getInitLCDecl(BO->getLHS()) == LCDecl) | ||||||
6857 | return setStep(BO->getRHS(), !IsAdd); | ||||||
6858 | if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) | ||||||
6859 | return setStep(BO->getLHS(), /*Subtract=*/false); | ||||||
6860 | } | ||||||
6861 | } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { | ||||||
6862 | bool IsAdd = CE->getOperator() == OO_Plus; | ||||||
6863 | if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { | ||||||
6864 | if (getInitLCDecl(CE->getArg(0)) == LCDecl) | ||||||
6865 | return setStep(CE->getArg(1), !IsAdd); | ||||||
6866 | if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) | ||||||
6867 | return setStep(CE->getArg(0), /*Subtract=*/false); | ||||||
6868 | } | ||||||
6869 | } | ||||||
6870 | if (dependent() || SemaRef.CurContext->isDependentContext()) | ||||||
6871 | return false; | ||||||
6872 | SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) | ||||||
6873 | << RHS->getSourceRange() << LCDecl; | ||||||
6874 | return true; | ||||||
6875 | } | ||||||
6876 | |||||||
6877 | bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { | ||||||
6878 | // Check incr-expr for canonical loop form and return true if it | ||||||
6879 | // does not conform. | ||||||
6880 | // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: | ||||||
6881 | // ++var | ||||||
6882 | // var++ | ||||||
6883 | // --var | ||||||
6884 | // var-- | ||||||
6885 | // var += incr | ||||||
6886 | // var -= incr | ||||||
6887 | // var = var + incr | ||||||
6888 | // var = incr + var | ||||||
6889 | // var = var - incr | ||||||
6890 | // | ||||||
6891 | if (!S) { | ||||||
6892 | SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; | ||||||
6893 | return true; | ||||||
6894 | } | ||||||
6895 | if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) | ||||||
6896 | if (!ExprTemp->cleanupsHaveSideEffects()) | ||||||
6897 | S = ExprTemp->getSubExpr(); | ||||||
6898 | |||||||
6899 | IncrementSrcRange = S->getSourceRange(); | ||||||
6900 | S = S->IgnoreParens(); | ||||||
6901 | if (auto *UO = dyn_cast<UnaryOperator>(S)) { | ||||||
6902 | if (UO->isIncrementDecrementOp() && | ||||||
6903 | getInitLCDecl(UO->getSubExpr()) == LCDecl) | ||||||
6904 | return setStep(SemaRef | ||||||
6905 | .ActOnIntegerConstant(UO->getBeginLoc(), | ||||||
6906 | (UO->isDecrementOp() ? -1 : 1)) | ||||||
6907 | .get(), | ||||||
6908 | /*Subtract=*/false); | ||||||
6909 | } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { | ||||||
6910 | switch (BO->getOpcode()) { | ||||||
6911 | case BO_AddAssign: | ||||||
6912 | case BO_SubAssign: | ||||||
6913 | if (getInitLCDecl(BO->getLHS()) == LCDecl) | ||||||
6914 | return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); | ||||||
6915 | break; | ||||||
6916 | case BO_Assign: | ||||||
6917 | if (getInitLCDecl(BO->getLHS()) == LCDecl) | ||||||
6918 | return checkAndSetIncRHS(BO->getRHS()); | ||||||
6919 | break; | ||||||
6920 | default: | ||||||
6921 | break; | ||||||
6922 | } | ||||||
6923 | } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { | ||||||
6924 | switch (CE->getOperator()) { | ||||||
6925 | case OO_PlusPlus: | ||||||
6926 | case OO_MinusMinus: | ||||||
6927 | if (getInitLCDecl(CE->getArg(0)) == LCDecl) | ||||||
6928 | return setStep(SemaRef | ||||||
6929 | .ActOnIntegerConstant( | ||||||
6930 | CE->getBeginLoc(), | ||||||
6931 | ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) | ||||||
6932 | .get(), | ||||||
6933 | /*Subtract=*/false); | ||||||
6934 | break; | ||||||
6935 | case OO_PlusEqual: | ||||||
6936 | case OO_MinusEqual: | ||||||
6937 | if (getInitLCDecl(CE->getArg(0)) == LCDecl) | ||||||
6938 | return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); | ||||||
6939 | break; | ||||||
6940 | case OO_Equal: | ||||||
6941 | if (getInitLCDecl(CE->getArg(0)) == LCDecl) | ||||||
6942 | return checkAndSetIncRHS(CE->getArg(1)); | ||||||
6943 | break; | ||||||
6944 | default: | ||||||
6945 | break; | ||||||
6946 | } | ||||||
6947 | } | ||||||
6948 | if (dependent() || SemaRef.CurContext->isDependentContext()) | ||||||
6949 | return false; | ||||||
6950 | SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) | ||||||
6951 | << S->getSourceRange() << LCDecl; | ||||||
6952 | return true; | ||||||
6953 | } | ||||||
6954 | |||||||
6955 | static ExprResult | ||||||
6956 | tryBuildCapture(Sema &SemaRef, Expr *Capture, | ||||||
6957 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { | ||||||
6958 | if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors()) | ||||||
6959 | return Capture; | ||||||
6960 | if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) | ||||||
6961 | return SemaRef.PerformImplicitConversion( | ||||||
6962 | Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, | ||||||
6963 | /*AllowExplicit=*/true); | ||||||
6964 | auto I = Captures.find(Capture); | ||||||
6965 | if (I != Captures.end()) | ||||||
6966 | return buildCapture(SemaRef, Capture, I->second); | ||||||
6967 | DeclRefExpr *Ref = nullptr; | ||||||
6968 | ExprResult Res = buildCapture(SemaRef, Capture, Ref); | ||||||
6969 | Captures[Capture] = Ref; | ||||||
6970 | return Res; | ||||||
6971 | } | ||||||
6972 | |||||||
6973 | /// Calculate number of iterations, transforming to unsigned, if number of | ||||||
6974 | /// iterations may be larger than the original type. | ||||||
6975 | static Expr * | ||||||
6976 | calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc, | ||||||
6977 | Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy, | ||||||
6978 | bool TestIsStrictOp, bool RoundToStep, | ||||||
6979 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { | ||||||
6980 | ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); | ||||||
6981 | if (!NewStep.isUsable()) | ||||||
6982 | return nullptr; | ||||||
6983 | llvm::APSInt LRes, SRes; | ||||||
6984 | bool IsLowerConst = false, IsStepConst = false; | ||||||
6985 | if (Optional<llvm::APSInt> Res = Lower->getIntegerConstantExpr(SemaRef.Context)) { | ||||||
6986 | LRes = *Res; | ||||||
6987 | IsLowerConst = true; | ||||||
6988 | } | ||||||
6989 | if (Optional<llvm::APSInt> Res = Step->getIntegerConstantExpr(SemaRef.Context)) { | ||||||
6990 | SRes = *Res; | ||||||
6991 | IsStepConst = true; | ||||||
6992 | } | ||||||
6993 | bool NoNeedToConvert = IsLowerConst && !RoundToStep && | ||||||
6994 | ((!TestIsStrictOp && LRes.isNonNegative()) || | ||||||
6995 | (TestIsStrictOp && LRes.isStrictlyPositive())); | ||||||
6996 | bool NeedToReorganize = false; | ||||||
6997 | // Check if any subexpressions in Lower -Step [+ 1] lead to overflow. | ||||||
6998 | if (!NoNeedToConvert && IsLowerConst && | ||||||
6999 | (TestIsStrictOp || (RoundToStep && IsStepConst))) { | ||||||
7000 | NoNeedToConvert = true; | ||||||
7001 | if (RoundToStep) { | ||||||
7002 | unsigned BW = LRes.getBitWidth() > SRes.getBitWidth() | ||||||
7003 | ? LRes.getBitWidth() | ||||||
7004 | : SRes.getBitWidth(); | ||||||
7005 | LRes = LRes.extend(BW + 1); | ||||||
7006 | LRes.setIsSigned(true); | ||||||
7007 | SRes = SRes.extend(BW + 1); | ||||||
7008 | SRes.setIsSigned(true); | ||||||
7009 | LRes -= SRes; | ||||||
7010 | NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes; | ||||||
7011 | LRes = LRes.trunc(BW); | ||||||
7012 | } | ||||||
7013 | if (TestIsStrictOp) { | ||||||
7014 | unsigned BW = LRes.getBitWidth(); | ||||||
7015 | LRes = LRes.extend(BW + 1); | ||||||
7016 | LRes.setIsSigned(true); | ||||||
7017 | ++LRes; | ||||||
7018 | NoNeedToConvert = | ||||||
7019 | NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes; | ||||||
7020 | // truncate to the original bitwidth. | ||||||
7021 | LRes = LRes.trunc(BW); | ||||||
7022 | } | ||||||
7023 | NeedToReorganize = NoNeedToConvert; | ||||||
7024 | } | ||||||
7025 | llvm::APSInt URes; | ||||||
7026 | bool IsUpperConst = false; | ||||||
7027 | if (Optional<llvm::APSInt> Res = Upper->getIntegerConstantExpr(SemaRef.Context)) { | ||||||
7028 | URes = *Res; | ||||||
7029 | IsUpperConst = true; | ||||||
7030 | } | ||||||
7031 | if (NoNeedToConvert && IsLowerConst && IsUpperConst && | ||||||
7032 | (!RoundToStep || IsStepConst)) { | ||||||
7033 | unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth() | ||||||
7034 | : URes.getBitWidth(); | ||||||
7035 | LRes = LRes.extend(BW + 1); | ||||||
7036 | LRes.setIsSigned(true); | ||||||
7037 | URes = URes.extend(BW + 1); | ||||||
7038 | URes.setIsSigned(true); | ||||||
7039 | URes -= LRes; | ||||||
7040 | NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes; | ||||||
7041 | NeedToReorganize = NoNeedToConvert; | ||||||
7042 | } | ||||||
7043 | // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant | ||||||
7044 | // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to | ||||||
7045 | // unsigned. | ||||||
7046 | if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) && | ||||||
7047 | !LCTy->isDependentType() && LCTy->isIntegerType()) { | ||||||
7048 | QualType LowerTy = Lower->getType(); | ||||||
7049 | QualType UpperTy = Upper->getType(); | ||||||
7050 | uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy); | ||||||
7051 | uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy); | ||||||
7052 | if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) || | ||||||
7053 | (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) { | ||||||
7054 | QualType CastType = SemaRef.Context.getIntTypeForBitwidth( | ||||||
7055 | LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0); | ||||||
7056 | Upper = | ||||||
7057 | SemaRef | ||||||
7058 | .PerformImplicitConversion( | ||||||
7059 | SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), | ||||||
7060 | CastType, Sema::AA_Converting) | ||||||
7061 | .get(); | ||||||
7062 | Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(); | ||||||
7063 | NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get()); | ||||||
7064 | } | ||||||
7065 | } | ||||||
7066 | if (!Lower || !Upper || NewStep.isInvalid()) | ||||||
7067 | return nullptr; | ||||||
7068 | |||||||
7069 | ExprResult Diff; | ||||||
7070 | // If need to reorganize, then calculate the form as Upper - (Lower - Step [+ | ||||||
7071 | // 1]). | ||||||
7072 | if (NeedToReorganize) { | ||||||
7073 | Diff = Lower; | ||||||
7074 | |||||||
7075 | if (RoundToStep) { | ||||||
7076 | // Lower - Step | ||||||
7077 | Diff = | ||||||
7078 | SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get()); | ||||||
7079 | if (!Diff.isUsable()) | ||||||
7080 | return nullptr; | ||||||
7081 | } | ||||||
7082 | |||||||
7083 | // Lower - Step [+ 1] | ||||||
7084 | if (TestIsStrictOp) | ||||||
7085 | Diff = SemaRef.BuildBinOp( | ||||||
7086 | S, DefaultLoc, BO_Add, Diff.get(), | ||||||
7087 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); | ||||||
7088 | if (!Diff.isUsable()) | ||||||
7089 | return nullptr; | ||||||
7090 | |||||||
7091 | Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); | ||||||
7092 | if (!Diff.isUsable()) | ||||||
7093 | return nullptr; | ||||||
7094 | |||||||
7095 | // Upper - (Lower - Step [+ 1]). | ||||||
7096 | Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); | ||||||
7097 | if (!Diff.isUsable()) | ||||||
7098 | return nullptr; | ||||||
7099 | } else { | ||||||
7100 | Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); | ||||||
7101 | |||||||
7102 | if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) { | ||||||
7103 | // BuildBinOp already emitted error, this one is to point user to upper | ||||||
7104 | // and lower bound, and to tell what is passed to 'operator-'. | ||||||
7105 | SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) | ||||||
7106 | << Upper->getSourceRange() << Lower->getSourceRange(); | ||||||
7107 | return nullptr; | ||||||
7108 | } | ||||||
7109 | |||||||
7110 | if (!Diff.isUsable()) | ||||||
7111 | return nullptr; | ||||||
7112 | |||||||
7113 | // Upper - Lower [- 1] | ||||||
7114 | if (TestIsStrictOp) | ||||||
7115 | Diff = SemaRef.BuildBinOp( | ||||||
7116 | S, DefaultLoc, BO_Sub, Diff.get(), | ||||||
7117 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); | ||||||
7118 | if (!Diff.isUsable()) | ||||||
7119 | return nullptr; | ||||||
7120 | |||||||
7121 | if (RoundToStep) { | ||||||
7122 | // Upper - Lower [- 1] + Step | ||||||
7123 | Diff = | ||||||
7124 | SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); | ||||||
7125 | if (!Diff.isUsable()) | ||||||
7126 | return nullptr; | ||||||
7127 | } | ||||||
7128 | } | ||||||
7129 | |||||||
7130 | // Parentheses (for dumping/debugging purposes only). | ||||||
7131 | Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); | ||||||
7132 | if (!Diff.isUsable()) | ||||||
7133 | return nullptr; | ||||||
7134 | |||||||
7135 | // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step | ||||||
7136 | Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); | ||||||
7137 | if (!Diff.isUsable()) | ||||||
7138 | return nullptr; | ||||||
7139 | |||||||
7140 | return Diff.get(); | ||||||
7141 | } | ||||||
7142 | |||||||
7143 | /// Build the expression to calculate the number of iterations. | ||||||
7144 | Expr *OpenMPIterationSpaceChecker::buildNumIterations( | ||||||
7145 | Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, | ||||||
7146 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { | ||||||
7147 | QualType VarType = LCDecl->getType().getNonReferenceType(); | ||||||
7148 | if (!VarType->isIntegerType() && !VarType->isPointerType() && | ||||||
7149 | !SemaRef.getLangOpts().CPlusPlus) | ||||||
7150 | return nullptr; | ||||||
7151 | Expr *LBVal = LB; | ||||||
7152 | Expr *UBVal = UB; | ||||||
7153 | // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : | ||||||
7154 | // max(LB(MinVal), LB(MaxVal)) | ||||||
7155 | if (InitDependOnLC) { | ||||||
7156 | const LoopIterationSpace &IS = | ||||||
7157 | ResultIterSpaces[ResultIterSpaces.size() - 1 - | ||||||
7158 | InitDependOnLC.getValueOr( | ||||||
7159 | CondDependOnLC.getValueOr(0))]; | ||||||
7160 | if (!IS.MinValue || !IS.MaxValue) | ||||||
7161 | return nullptr; | ||||||
7162 | // OuterVar = Min | ||||||
7163 | ExprResult MinValue = | ||||||
7164 | SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); | ||||||
7165 | if (!MinValue.isUsable()) | ||||||
7166 | return nullptr; | ||||||
7167 | |||||||
7168 | ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, | ||||||
7169 | IS.CounterVar, MinValue.get()); | ||||||
7170 | if (!LBMinVal.isUsable()) | ||||||
7171 | return nullptr; | ||||||
7172 | // OuterVar = Min, LBVal | ||||||
7173 | LBMinVal = | ||||||
7174 | SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); | ||||||
7175 | if (!LBMinVal.isUsable()) | ||||||
7176 | return nullptr; | ||||||
7177 | // (OuterVar = Min, LBVal) | ||||||
7178 | LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); | ||||||
7179 | if (!LBMinVal.isUsable()) | ||||||
7180 | return nullptr; | ||||||
7181 | |||||||
7182 | // OuterVar = Max | ||||||
7183 | ExprResult MaxValue = | ||||||
7184 | SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); | ||||||
7185 | if (!MaxValue.isUsable()) | ||||||
7186 | return nullptr; | ||||||
7187 | |||||||
7188 | ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, | ||||||
7189 | IS.CounterVar, MaxValue.get()); | ||||||
7190 | if (!LBMaxVal.isUsable()) | ||||||
7191 | return nullptr; | ||||||
7192 | // OuterVar = Max, LBVal | ||||||
7193 | LBMaxVal = | ||||||
7194 | SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); | ||||||
7195 | if (!LBMaxVal.isUsable()) | ||||||
7196 | return nullptr; | ||||||
7197 | // (OuterVar = Max, LBVal) | ||||||
7198 | LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); | ||||||
7199 | if (!LBMaxVal.isUsable()) | ||||||
7200 | return nullptr; | ||||||
7201 | |||||||
7202 | Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); | ||||||
7203 | Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); | ||||||
7204 | if (!LBMin || !LBMax) | ||||||
7205 | return nullptr; | ||||||
7206 | // LB(MinVal) < LB(MaxVal) | ||||||
7207 | ExprResult MinLessMaxRes = | ||||||
7208 | SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); | ||||||
7209 | if (!MinLessMaxRes.isUsable()) | ||||||
7210 | return nullptr; | ||||||
7211 | Expr *MinLessMax = | ||||||
7212 | tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); | ||||||
7213 | if (!MinLessMax) | ||||||
7214 | return nullptr; | ||||||
7215 | if (TestIsLessOp.getValue()) { | ||||||
7216 | // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), | ||||||
7217 | // LB(MaxVal)) | ||||||
7218 | ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, | ||||||
7219 | MinLessMax, LBMin, LBMax); | ||||||
7220 | if (!MinLB.isUsable()) | ||||||
7221 | return nullptr; | ||||||
7222 | LBVal = MinLB.get(); | ||||||
7223 | } else { | ||||||
7224 | // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), | ||||||
7225 | // LB(MaxVal)) | ||||||
7226 | ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, | ||||||
7227 | MinLessMax, LBMax, LBMin); | ||||||
7228 | if (!MaxLB.isUsable()) | ||||||
7229 | return nullptr; | ||||||
7230 | LBVal = MaxLB.get(); | ||||||
7231 | } | ||||||
7232 | } | ||||||
7233 | // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : | ||||||
7234 | // min(UB(MinVal), UB(MaxVal)) | ||||||
7235 | if (CondDependOnLC) { | ||||||
7236 | const LoopIterationSpace &IS = | ||||||
7237 | ResultIterSpaces[ResultIterSpaces.size() - 1 - | ||||||
7238 | InitDependOnLC.getValueOr( | ||||||
7239 | CondDependOnLC.getValueOr(0))]; | ||||||
7240 | if (!IS.MinValue || !IS.MaxValue) | ||||||
7241 | return nullptr; | ||||||
7242 | // OuterVar = Min | ||||||
7243 | ExprResult MinValue = | ||||||
7244 | SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); | ||||||
7245 | if (!MinValue.isUsable()) | ||||||
7246 | return nullptr; | ||||||
7247 | |||||||
7248 | ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, | ||||||
7249 | IS.CounterVar, MinValue.get()); | ||||||
7250 | if (!UBMinVal.isUsable()) | ||||||
7251 | return nullptr; | ||||||
7252 | // OuterVar = Min, UBVal | ||||||
7253 | UBMinVal = | ||||||
7254 | SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); | ||||||
7255 | if (!UBMinVal.isUsable()) | ||||||
7256 | return nullptr; | ||||||
7257 | // (OuterVar = Min, UBVal) | ||||||
7258 | UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); | ||||||
7259 | if (!UBMinVal.isUsable()) | ||||||
7260 | return nullptr; | ||||||
7261 | |||||||
7262 | // OuterVar = Max | ||||||
7263 | ExprResult MaxValue = | ||||||
7264 | SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); | ||||||
7265 | if (!MaxValue.isUsable()) | ||||||
7266 | return nullptr; | ||||||
7267 | |||||||
7268 | ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, | ||||||
7269 | IS.CounterVar, MaxValue.get()); | ||||||
7270 | if (!UBMaxVal.isUsable()) | ||||||
7271 | return nullptr; | ||||||
7272 | // OuterVar = Max, UBVal | ||||||
7273 | UBMaxVal = | ||||||
7274 | SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); | ||||||
7275 | if (!UBMaxVal.isUsable()) | ||||||
7276 | return nullptr; | ||||||
7277 | // (OuterVar = Max, UBVal) | ||||||
7278 | UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); | ||||||
7279 | if (!UBMaxVal.isUsable()) | ||||||
7280 | return nullptr; | ||||||
7281 | |||||||
7282 | Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); | ||||||
7283 | Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); | ||||||
7284 | if (!UBMin || !UBMax) | ||||||
7285 | return nullptr; | ||||||
7286 | // UB(MinVal) > UB(MaxVal) | ||||||
7287 | ExprResult MinGreaterMaxRes = | ||||||
7288 | SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); | ||||||
7289 | if (!MinGreaterMaxRes.isUsable()) | ||||||
7290 | return nullptr; | ||||||
7291 | Expr *MinGreaterMax = | ||||||
7292 | tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); | ||||||
7293 | if (!MinGreaterMax) | ||||||
7294 | return nullptr; | ||||||
7295 | if (TestIsLessOp.getValue()) { | ||||||
7296 | // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), | ||||||
7297 | // UB(MaxVal)) | ||||||
7298 | ExprResult MaxUB = SemaRef.ActOnConditionalOp( | ||||||
7299 | DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); | ||||||
7300 | if (!MaxUB.isUsable()) | ||||||
7301 | return nullptr; | ||||||
7302 | UBVal = MaxUB.get(); | ||||||
7303 | } else { | ||||||
7304 | // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), | ||||||
7305 | // UB(MaxVal)) | ||||||
7306 | ExprResult MinUB = SemaRef.ActOnConditionalOp( | ||||||
7307 | DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); | ||||||
7308 | if (!MinUB.isUsable()) | ||||||
7309 | return nullptr; | ||||||
7310 | UBVal = MinUB.get(); | ||||||
7311 | } | ||||||
7312 | } | ||||||
7313 | Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; | ||||||
7314 | Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; | ||||||
7315 | Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); | ||||||
7316 | Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); | ||||||
7317 | if (!Upper || !Lower) | ||||||
7318 | return nullptr; | ||||||
7319 | |||||||
7320 | ExprResult Diff = | ||||||
7321 | calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType, | ||||||
7322 | TestIsStrictOp, /*RoundToStep=*/true, Captures); | ||||||
7323 | if (!Diff.isUsable()) | ||||||
7324 | return nullptr; | ||||||
7325 | |||||||
7326 | // OpenMP runtime requires 32-bit or 64-bit loop variables. | ||||||
7327 | QualType Type = Diff.get()->getType(); | ||||||
7328 | ASTContext &C = SemaRef.Context; | ||||||
7329 | bool UseVarType = VarType->hasIntegerRepresentation() && | ||||||
7330 | C.getTypeSize(Type) > C.getTypeSize(VarType); | ||||||
7331 | if (!Type->isIntegerType() || UseVarType) { | ||||||
7332 | unsigned NewSize = | ||||||
7333 | UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); | ||||||
7334 | bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() | ||||||
7335 | : Type->hasSignedIntegerRepresentation(); | ||||||
7336 | Type = C.getIntTypeForBitwidth(NewSize, IsSigned); | ||||||
7337 | if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { | ||||||
7338 | Diff = SemaRef.PerformImplicitConversion( | ||||||
7339 | Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); | ||||||
7340 | if (!Diff.isUsable()) | ||||||
7341 | return nullptr; | ||||||
7342 | } | ||||||
7343 | } | ||||||
7344 | if (LimitedType) { | ||||||
7345 | unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; | ||||||
7346 | if (NewSize != C.getTypeSize(Type)) { | ||||||
7347 | if (NewSize < C.getTypeSize(Type)) { | ||||||
7348 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 7348, __PRETTY_FUNCTION__)); | ||||||
7349 | SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) | ||||||
7350 | << InitSrcRange << ConditionSrcRange; | ||||||
7351 | } | ||||||
7352 | QualType NewType = C.getIntTypeForBitwidth( | ||||||
7353 | NewSize, Type->hasSignedIntegerRepresentation() || | ||||||
7354 | C.getTypeSize(Type) < NewSize); | ||||||
7355 | if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { | ||||||
7356 | Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, | ||||||
7357 | Sema::AA_Converting, true); | ||||||
7358 | if (!Diff.isUsable()) | ||||||
7359 | return nullptr; | ||||||
7360 | } | ||||||
7361 | } | ||||||
7362 | } | ||||||
7363 | |||||||
7364 | return Diff.get(); | ||||||
7365 | } | ||||||
7366 | |||||||
7367 | std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( | ||||||
7368 | Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { | ||||||
7369 | // Do not build for iterators, they cannot be used in non-rectangular loop | ||||||
7370 | // nests. | ||||||
7371 | if (LCDecl->getType()->isRecordType()) | ||||||
7372 | return std::make_pair(nullptr, nullptr); | ||||||
7373 | // If we subtract, the min is in the condition, otherwise the min is in the | ||||||
7374 | // init value. | ||||||
7375 | Expr *MinExpr = nullptr; | ||||||
7376 | Expr *MaxExpr = nullptr; | ||||||
7377 | Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; | ||||||
7378 | Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; | ||||||
7379 | bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() | ||||||
7380 | : CondDependOnLC.hasValue(); | ||||||
7381 | bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() | ||||||
7382 | : InitDependOnLC.hasValue(); | ||||||
7383 | Expr *Lower = | ||||||
7384 | LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); | ||||||
7385 | Expr *Upper = | ||||||
7386 | UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); | ||||||
7387 | if (!Upper || !Lower) | ||||||
7388 | return std::make_pair(nullptr, nullptr); | ||||||
7389 | |||||||
7390 | if (TestIsLessOp.getValue()) | ||||||
7391 | MinExpr = Lower; | ||||||
7392 | else | ||||||
7393 | MaxExpr = Upper; | ||||||
7394 | |||||||
7395 | // Build minimum/maximum value based on number of iterations. | ||||||
7396 | QualType VarType = LCDecl->getType().getNonReferenceType(); | ||||||
7397 | |||||||
7398 | ExprResult Diff = | ||||||
7399 | calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType, | ||||||
7400 | TestIsStrictOp, /*RoundToStep=*/false, Captures); | ||||||
7401 | if (!Diff.isUsable()) | ||||||
7402 | return std::make_pair(nullptr, nullptr); | ||||||
7403 | |||||||
7404 | // ((Upper - Lower [- 1]) / Step) * Step | ||||||
7405 | // Parentheses (for dumping/debugging purposes only). | ||||||
7406 | Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); | ||||||
7407 | if (!Diff.isUsable()) | ||||||
7408 | return std::make_pair(nullptr, nullptr); | ||||||
7409 | |||||||
7410 | ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); | ||||||
7411 | if (!NewStep.isUsable()) | ||||||
7412 | return std::make_pair(nullptr, nullptr); | ||||||
7413 | Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); | ||||||
7414 | if (!Diff.isUsable()) | ||||||
7415 | return std::make_pair(nullptr, nullptr); | ||||||
7416 | |||||||
7417 | // Parentheses (for dumping/debugging purposes only). | ||||||
7418 | Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); | ||||||
7419 | if (!Diff.isUsable()) | ||||||
7420 | return std::make_pair(nullptr, nullptr); | ||||||
7421 | |||||||
7422 | // Convert to the ptrdiff_t, if original type is pointer. | ||||||
7423 | if (VarType->isAnyPointerType() && | ||||||
7424 | !SemaRef.Context.hasSameType( | ||||||
7425 | Diff.get()->getType(), | ||||||
7426 | SemaRef.Context.getUnsignedPointerDiffType())) { | ||||||
7427 | Diff = SemaRef.PerformImplicitConversion( | ||||||
7428 | Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), | ||||||
7429 | Sema::AA_Converting, /*AllowExplicit=*/true); | ||||||
7430 | } | ||||||
7431 | if (!Diff.isUsable()) | ||||||
7432 | return std::make_pair(nullptr, nullptr); | ||||||
7433 | |||||||
7434 | if (TestIsLessOp.getValue()) { | ||||||
7435 | // MinExpr = Lower; | ||||||
7436 | // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) | ||||||
7437 | Diff = SemaRef.BuildBinOp( | ||||||
7438 | S, DefaultLoc, BO_Add, | ||||||
7439 | SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(), | ||||||
7440 | Diff.get()); | ||||||
7441 | if (!Diff.isUsable()) | ||||||
7442 | return std::make_pair(nullptr, nullptr); | ||||||
7443 | } else { | ||||||
7444 | // MaxExpr = Upper; | ||||||
7445 | // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) | ||||||
7446 | Diff = SemaRef.BuildBinOp( | ||||||
7447 | S, DefaultLoc, BO_Sub, | ||||||
7448 | SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), | ||||||
7449 | Diff.get()); | ||||||
7450 | if (!Diff.isUsable()) | ||||||
7451 | return std::make_pair(nullptr, nullptr); | ||||||
7452 | } | ||||||
7453 | |||||||
7454 | // Convert to the original type. | ||||||
7455 | if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) | ||||||
7456 | Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType, | ||||||
7457 | Sema::AA_Converting, | ||||||
7458 | /*AllowExplicit=*/true); | ||||||
7459 | if (!Diff.isUsable()) | ||||||
7460 | return std::make_pair(nullptr, nullptr); | ||||||
7461 | |||||||
7462 | Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false); | ||||||
7463 | if (!Diff.isUsable()) | ||||||
7464 | return std::make_pair(nullptr, nullptr); | ||||||
7465 | |||||||
7466 | if (TestIsLessOp.getValue()) | ||||||
7467 | MaxExpr = Diff.get(); | ||||||
7468 | else | ||||||
7469 | MinExpr = Diff.get(); | ||||||
7470 | |||||||
7471 | return std::make_pair(MinExpr, MaxExpr); | ||||||
7472 | } | ||||||
7473 | |||||||
7474 | Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { | ||||||
7475 | if (InitDependOnLC || CondDependOnLC) | ||||||
7476 | return Condition; | ||||||
7477 | return nullptr; | ||||||
7478 | } | ||||||
7479 | |||||||
7480 | Expr *OpenMPIterationSpaceChecker::buildPreCond( | ||||||
7481 | Scope *S, Expr *Cond, | ||||||
7482 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { | ||||||
7483 | // Do not build a precondition when the condition/initialization is dependent | ||||||
7484 | // to prevent pessimistic early loop exit. | ||||||
7485 | // TODO: this can be improved by calculating min/max values but not sure that | ||||||
7486 | // it will be very effective. | ||||||
7487 | if (CondDependOnLC || InitDependOnLC) | ||||||
7488 | return SemaRef.PerformImplicitConversion( | ||||||
7489 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), | ||||||
7490 | SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, | ||||||
7491 | /*AllowExplicit=*/true).get(); | ||||||
7492 | |||||||
7493 | // Try to build LB <op> UB, where <op> is <, >, <=, or >=. | ||||||
7494 | Sema::TentativeAnalysisScope Trap(SemaRef); | ||||||
7495 | |||||||
7496 | ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); | ||||||
7497 | ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); | ||||||
7498 | if (!NewLB.isUsable() || !NewUB.isUsable()) | ||||||
7499 | return nullptr; | ||||||
7500 | |||||||
7501 | ExprResult CondExpr = | ||||||
7502 | SemaRef.BuildBinOp(S, DefaultLoc, | ||||||
7503 | TestIsLessOp.getValue() ? | ||||||
7504 | (TestIsStrictOp ? BO_LT : BO_LE) : | ||||||
7505 | (TestIsStrictOp ? BO_GT : BO_GE), | ||||||
7506 | NewLB.get(), NewUB.get()); | ||||||
7507 | if (CondExpr.isUsable()) { | ||||||
7508 | if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), | ||||||
7509 | SemaRef.Context.BoolTy)) | ||||||
7510 | CondExpr = SemaRef.PerformImplicitConversion( | ||||||
7511 | CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, | ||||||
7512 | /*AllowExplicit=*/true); | ||||||
7513 | } | ||||||
7514 | |||||||
7515 | // Otherwise use original loop condition and evaluate it in runtime. | ||||||
7516 | return CondExpr.isUsable() ? CondExpr.get() : Cond; | ||||||
7517 | } | ||||||
7518 | |||||||
7519 | /// Build reference expression to the counter be used for codegen. | ||||||
7520 | DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( | ||||||
7521 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, | ||||||
7522 | DSAStackTy &DSA) const { | ||||||
7523 | auto *VD = dyn_cast<VarDecl>(LCDecl); | ||||||
7524 | if (!VD) { | ||||||
7525 | VD = SemaRef.isOpenMPCapturedDecl(LCDecl); | ||||||
7526 | DeclRefExpr *Ref = buildDeclRefExpr( | ||||||
7527 | SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); | ||||||
7528 | const DSAStackTy::DSAVarData Data = | ||||||
7529 | DSA.getTopDSA(LCDecl, /*FromParent=*/false); | ||||||
7530 | // If the loop control decl is explicitly marked as private, do not mark it | ||||||
7531 | // as captured again. | ||||||
7532 | if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) | ||||||
7533 | Captures.insert(std::make_pair(LCRef, Ref)); | ||||||
7534 | return Ref; | ||||||
7535 | } | ||||||
7536 | return cast<DeclRefExpr>(LCRef); | ||||||
7537 | } | ||||||
7538 | |||||||
7539 | Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { | ||||||
7540 | if (LCDecl && !LCDecl->isInvalidDecl()) { | ||||||
7541 | QualType Type = LCDecl->getType().getNonReferenceType(); | ||||||
7542 | VarDecl *PrivateVar = buildVarDecl( | ||||||
7543 | SemaRef, DefaultLoc, Type, LCDecl->getName(), | ||||||
7544 | LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, | ||||||
7545 | isa<VarDecl>(LCDecl) | ||||||
7546 | ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) | ||||||
7547 | : nullptr); | ||||||
7548 | if (PrivateVar->isInvalidDecl()) | ||||||
7549 | return nullptr; | ||||||
7550 | return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); | ||||||
7551 | } | ||||||
7552 | return nullptr; | ||||||
7553 | } | ||||||
7554 | |||||||
7555 | /// Build initialization of the counter to be used for codegen. | ||||||
7556 | Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } | ||||||
7557 | |||||||
7558 | /// Build step of the counter be used for codegen. | ||||||
7559 | Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } | ||||||
7560 | |||||||
7561 | Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( | ||||||
7562 | Scope *S, Expr *Counter, | ||||||
7563 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, | ||||||
7564 | Expr *Inc, OverloadedOperatorKind OOK) { | ||||||
7565 | Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); | ||||||
7566 | if (!Cnt) | ||||||
7567 | return nullptr; | ||||||
7568 | if (Inc) { | ||||||
7569 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 7570, __PRETTY_FUNCTION__)) | ||||||
7570 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 7570, __PRETTY_FUNCTION__)); | ||||||
7571 | BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; | ||||||
7572 | Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); | ||||||
7573 | if (!Cnt) | ||||||
7574 | return nullptr; | ||||||
7575 | } | ||||||
7576 | QualType VarType = LCDecl->getType().getNonReferenceType(); | ||||||
7577 | if (!VarType->isIntegerType() && !VarType->isPointerType() && | ||||||
7578 | !SemaRef.getLangOpts().CPlusPlus) | ||||||
7579 | return nullptr; | ||||||
7580 | // Upper - Lower | ||||||
7581 | Expr *Upper = TestIsLessOp.getValue() | ||||||
7582 | ? Cnt | ||||||
7583 | : tryBuildCapture(SemaRef, LB, Captures).get(); | ||||||
7584 | Expr *Lower = TestIsLessOp.getValue() | ||||||
7585 | ? tryBuildCapture(SemaRef, LB, Captures).get() | ||||||
7586 | : Cnt; | ||||||
7587 | if (!Upper || !Lower) | ||||||
7588 | return nullptr; | ||||||
7589 | |||||||
7590 | ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, | ||||||
7591 | Step, VarType, /*TestIsStrictOp=*/false, | ||||||
7592 | /*RoundToStep=*/false, Captures); | ||||||
7593 | if (!Diff.isUsable()) | ||||||
7594 | return nullptr; | ||||||
7595 | |||||||
7596 | return Diff.get(); | ||||||
7597 | } | ||||||
7598 | } // namespace | ||||||
7599 | |||||||
7600 | void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { | ||||||
7601 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 7601, __PRETTY_FUNCTION__)); | ||||||
7602 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 7602, __PRETTY_FUNCTION__)); | ||||||
7603 | unsigned AssociatedLoops = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getAssociatedLoops(); | ||||||
7604 | if (AssociatedLoops > 0 && | ||||||
7605 | isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective())) { | ||||||
7606 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->loopStart(); | ||||||
7607 | OpenMPIterationSpaceChecker ISC(*this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), ForLoc); | ||||||
7608 | if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { | ||||||
7609 | if (ValueDecl *D = ISC.getLoopDecl()) { | ||||||
7610 | auto *VD = dyn_cast<VarDecl>(D); | ||||||
7611 | DeclRefExpr *PrivateRef = nullptr; | ||||||
7612 | if (!VD) { | ||||||
7613 | if (VarDecl *Private = isOpenMPCapturedDecl(D)) { | ||||||
7614 | VD = Private; | ||||||
7615 | } else { | ||||||
7616 | PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), | ||||||
7617 | /*WithInit=*/false); | ||||||
7618 | VD = cast<VarDecl>(PrivateRef->getDecl()); | ||||||
7619 | } | ||||||
7620 | } | ||||||
7621 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addLoopControlVariable(D, VD); | ||||||
7622 | const Decl *LD = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getPossiblyLoopCunter(); | ||||||
7623 | if (LD != D->getCanonicalDecl()) { | ||||||
7624 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->resetPossibleLoopCounter(); | ||||||
7625 | if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) | ||||||
7626 | MarkDeclarationsReferencedInExpr( | ||||||
7627 | buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), | ||||||
7628 | Var->getType().getNonLValueExprType(Context), | ||||||
7629 | ForLoc, /*RefersToCapture=*/true)); | ||||||
7630 | } | ||||||
7631 | OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); | ||||||
7632 | // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables | ||||||
7633 | // Referenced in a Construct, C/C++]. The loop iteration variable in the | ||||||
7634 | // associated for-loop of a simd construct with just one associated | ||||||
7635 | // for-loop may be listed in a linear clause with a constant-linear-step | ||||||
7636 | // that is the increment of the associated for-loop. The loop iteration | ||||||
7637 | // variable(s) in the associated for-loop(s) of a for or parallel for | ||||||
7638 | // construct may be listed in a private or lastprivate clause. | ||||||
7639 | DSAStackTy::DSAVarData DVar = | ||||||
7640 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); | ||||||
7641 | // If LoopVarRefExpr is nullptr it means the corresponding loop variable | ||||||
7642 | // is declared in the loop and it is predetermined as a private. | ||||||
7643 | Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); | ||||||
7644 | OpenMPClauseKind PredeterminedCKind = | ||||||
7645 | isOpenMPSimdDirective(DKind) | ||||||
7646 | ? (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) | ||||||
7647 | : OMPC_private; | ||||||
7648 | if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && | ||||||
7649 | DVar.CKind != PredeterminedCKind && DVar.RefExpr && | ||||||
7650 | (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && | ||||||
7651 | DVar.CKind != OMPC_private))) || | ||||||
7652 | ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || | ||||||
7653 | DKind == OMPD_master_taskloop || | ||||||
7654 | DKind == OMPD_parallel_master_taskloop || | ||||||
7655 | isOpenMPDistributeDirective(DKind)) && | ||||||
7656 | !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && | ||||||
7657 | DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && | ||||||
7658 | (DVar.CKind != OMPC_private || DVar.RefExpr)) { | ||||||
7659 | Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) | ||||||
7660 | << getOpenMPClauseName(DVar.CKind) | ||||||
7661 | << getOpenMPDirectiveName(DKind) | ||||||
7662 | << getOpenMPClauseName(PredeterminedCKind); | ||||||
7663 | if (DVar.RefExpr == nullptr) | ||||||
7664 | DVar.CKind = PredeterminedCKind; | ||||||
7665 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar, | ||||||
7666 | /*IsLoopIterVar=*/true); | ||||||
7667 | } else if (LoopDeclRefExpr) { | ||||||
7668 | // Make the loop iteration variable private (for worksharing | ||||||
7669 | // constructs), linear (for simd directives with the only one | ||||||
7670 | // associated loop) or lastprivate (for simd directives with several | ||||||
7671 | // collapsed or ordered loops). | ||||||
7672 | if (DVar.CKind == OMPC_unknown) | ||||||
7673 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, | ||||||
7674 | PrivateRef); | ||||||
7675 | } | ||||||
7676 | } | ||||||
7677 | } | ||||||
7678 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setAssociatedLoops(AssociatedLoops - 1); | ||||||
7679 | } | ||||||
7680 | } | ||||||
7681 | |||||||
7682 | /// Called on a for stmt to check and extract its iteration space | ||||||
7683 | /// for further processing (such as collapsing). | ||||||
7684 | static bool checkOpenMPIterationSpace( | ||||||
7685 | OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, | ||||||
7686 | unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, | ||||||
7687 | unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, | ||||||
7688 | Expr *OrderedLoopCountExpr, | ||||||
7689 | Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, | ||||||
7690 | llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, | ||||||
7691 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { | ||||||
7692 | // OpenMP [2.9.1, Canonical Loop Form] | ||||||
7693 | // for (init-expr; test-expr; incr-expr) structured-block | ||||||
7694 | // for (range-decl: range-expr) structured-block | ||||||
7695 | auto *For = dyn_cast_or_null<ForStmt>(S); | ||||||
7696 | auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); | ||||||
7697 | // Ranged for is supported only in OpenMP 5.0. | ||||||
7698 | if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { | ||||||
7699 | SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) | ||||||
7700 | << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) | ||||||
7701 | << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount | ||||||
7702 | << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; | ||||||
7703 | if (TotalNestedLoopCount > 1) { | ||||||
7704 | if (CollapseLoopCountExpr && OrderedLoopCountExpr) | ||||||
7705 | SemaRef.Diag(DSA.getConstructLoc(), | ||||||
7706 | diag::note_omp_collapse_ordered_expr) | ||||||
7707 | << 2 << CollapseLoopCountExpr->getSourceRange() | ||||||
7708 | << OrderedLoopCountExpr->getSourceRange(); | ||||||
7709 | else if (CollapseLoopCountExpr) | ||||||
7710 | SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), | ||||||
7711 | diag::note_omp_collapse_ordered_expr) | ||||||
7712 | << 0 << CollapseLoopCountExpr->getSourceRange(); | ||||||
7713 | else | ||||||
7714 | SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), | ||||||
7715 | diag::note_omp_collapse_ordered_expr) | ||||||
7716 | << 1 << OrderedLoopCountExpr->getSourceRange(); | ||||||
7717 | } | ||||||
7718 | return true; | ||||||
7719 | } | ||||||
7720 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 7721, __PRETTY_FUNCTION__)) | ||||||
7721 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 7721, __PRETTY_FUNCTION__)); | ||||||
7722 | |||||||
7723 | OpenMPIterationSpaceChecker ISC(SemaRef, DSA, | ||||||
7724 | For ? For->getForLoc() : CXXFor->getForLoc()); | ||||||
7725 | |||||||
7726 | // Check init. | ||||||
7727 | Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); | ||||||
7728 | if (ISC.checkAndSetInit(Init)) | ||||||
7729 | return true; | ||||||
7730 | |||||||
7731 | bool HasErrors = false; | ||||||
7732 | |||||||
7733 | // Check loop variable's type. | ||||||
7734 | if (ValueDecl *LCDecl = ISC.getLoopDecl()) { | ||||||
7735 | // OpenMP [2.6, Canonical Loop Form] | ||||||
7736 | // Var is one of the following: | ||||||
7737 | // A variable of signed or unsigned integer type. | ||||||
7738 | // For C++, a variable of a random access iterator type. | ||||||
7739 | // For C, a variable of a pointer type. | ||||||
7740 | QualType VarType = LCDecl->getType().getNonReferenceType(); | ||||||
7741 | if (!VarType->isDependentType() && !VarType->isIntegerType() && | ||||||
7742 | !VarType->isPointerType() && | ||||||
7743 | !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { | ||||||
7744 | SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) | ||||||
7745 | << SemaRef.getLangOpts().CPlusPlus; | ||||||
7746 | HasErrors = true; | ||||||
7747 | } | ||||||
7748 | |||||||
7749 | // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in | ||||||
7750 | // a Construct | ||||||
7751 | // The loop iteration variable(s) in the associated for-loop(s) of a for or | ||||||
7752 | // parallel for construct is (are) private. | ||||||
7753 | // The loop iteration variable in the associated for-loop of a simd | ||||||
7754 | // construct with just one associated for-loop is linear with a | ||||||
7755 | // constant-linear-step that is the increment of the associated for-loop. | ||||||
7756 | // Exclude loop var from the list of variables with implicitly defined data | ||||||
7757 | // sharing attributes. | ||||||
7758 | VarsWithImplicitDSA.erase(LCDecl); | ||||||
7759 | |||||||
7760 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 7760, __PRETTY_FUNCTION__)); | ||||||
7761 | |||||||
7762 | // Check test-expr. | ||||||
7763 | HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); | ||||||
7764 | |||||||
7765 | // Check incr-expr. | ||||||
7766 | HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); | ||||||
7767 | } | ||||||
7768 | |||||||
7769 | if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) | ||||||
7770 | return HasErrors; | ||||||
7771 | |||||||
7772 | // Build the loop's iteration space representation. | ||||||
7773 | ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( | ||||||
7774 | DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); | ||||||
7775 | ResultIterSpaces[CurrentNestedLoopCount].NumIterations = | ||||||
7776 | ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, | ||||||
7777 | (isOpenMPWorksharingDirective(DKind) || | ||||||
7778 | isOpenMPTaskLoopDirective(DKind) || | ||||||
7779 | isOpenMPDistributeDirective(DKind)), | ||||||
7780 | Captures); | ||||||
7781 | ResultIterSpaces[CurrentNestedLoopCount].CounterVar = | ||||||
7782 | ISC.buildCounterVar(Captures, DSA); | ||||||
7783 | ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = | ||||||
7784 | ISC.buildPrivateCounterVar(); | ||||||
7785 | ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); | ||||||
7786 | ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); | ||||||
7787 | ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); | ||||||
7788 | ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = | ||||||
7789 | ISC.getConditionSrcRange(); | ||||||
7790 | ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = | ||||||
7791 | ISC.getIncrementSrcRange(); | ||||||
7792 | ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); | ||||||
7793 | ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = | ||||||
7794 | ISC.isStrictTestOp(); | ||||||
7795 | std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, | ||||||
7796 | ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = | ||||||
7797 | ISC.buildMinMaxValues(DSA.getCurScope(), Captures); | ||||||
7798 | ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = | ||||||
7799 | ISC.buildFinalCondition(DSA.getCurScope()); | ||||||
7800 | ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = | ||||||
7801 | ISC.doesInitDependOnLC(); | ||||||
7802 | ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = | ||||||
7803 | ISC.doesCondDependOnLC(); | ||||||
7804 | ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = | ||||||
7805 | ISC.getLoopDependentIdx(); | ||||||
7806 | |||||||
7807 | HasErrors |= | ||||||
7808 | (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || | ||||||
7809 | ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || | ||||||
7810 | ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || | ||||||
7811 | ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || | ||||||
7812 | ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || | ||||||
7813 | ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); | ||||||
7814 | if (!HasErrors && DSA.isOrderedRegion()) { | ||||||
7815 | if (DSA.getOrderedRegionParam().second->getNumForLoops()) { | ||||||
7816 | if (CurrentNestedLoopCount < | ||||||
7817 | DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { | ||||||
7818 | DSA.getOrderedRegionParam().second->setLoopNumIterations( | ||||||
7819 | CurrentNestedLoopCount, | ||||||
7820 | ResultIterSpaces[CurrentNestedLoopCount].NumIterations); | ||||||
7821 | DSA.getOrderedRegionParam().second->setLoopCounter( | ||||||
7822 | CurrentNestedLoopCount, | ||||||
7823 | ResultIterSpaces[CurrentNestedLoopCount].CounterVar); | ||||||
7824 | } | ||||||
7825 | } | ||||||
7826 | for (auto &Pair : DSA.getDoacrossDependClauses()) { | ||||||
7827 | if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { | ||||||
7828 | // Erroneous case - clause has some problems. | ||||||
7829 | continue; | ||||||
7830 | } | ||||||
7831 | if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && | ||||||
7832 | Pair.second.size() <= CurrentNestedLoopCount) { | ||||||
7833 | // Erroneous case - clause has some problems. | ||||||
7834 | Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); | ||||||
7835 | continue; | ||||||
7836 | } | ||||||
7837 | Expr *CntValue; | ||||||
7838 | if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) | ||||||
7839 | CntValue = ISC.buildOrderedLoopData( | ||||||
7840 | DSA.getCurScope(), | ||||||
7841 | ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, | ||||||
7842 | Pair.first->getDependencyLoc()); | ||||||
7843 | else | ||||||
7844 | CntValue = ISC.buildOrderedLoopData( | ||||||
7845 | DSA.getCurScope(), | ||||||
7846 | ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, | ||||||
7847 | Pair.first->getDependencyLoc(), | ||||||
7848 | Pair.second[CurrentNestedLoopCount].first, | ||||||
7849 | Pair.second[CurrentNestedLoopCount].second); | ||||||
7850 | Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); | ||||||
7851 | } | ||||||
7852 | } | ||||||
7853 | |||||||
7854 | return HasErrors; | ||||||
7855 | } | ||||||
7856 | |||||||
7857 | /// Build 'VarRef = Start. | ||||||
7858 | static ExprResult | ||||||
7859 | buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, | ||||||
7860 | ExprResult Start, bool IsNonRectangularLB, | ||||||
7861 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { | ||||||
7862 | // Build 'VarRef = Start. | ||||||
7863 | ExprResult NewStart = IsNonRectangularLB | ||||||
7864 | ? Start.get() | ||||||
7865 | : tryBuildCapture(SemaRef, Start.get(), Captures); | ||||||
7866 | if (!NewStart.isUsable()) | ||||||
7867 | return ExprError(); | ||||||
7868 | if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), | ||||||
7869 | VarRef.get()->getType())) { | ||||||
7870 | NewStart = SemaRef.PerformImplicitConversion( | ||||||
7871 | NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, | ||||||
7872 | /*AllowExplicit=*/true); | ||||||
7873 | if (!NewStart.isUsable()) | ||||||
7874 | return ExprError(); | ||||||
7875 | } | ||||||
7876 | |||||||
7877 | ExprResult Init = | ||||||
7878 | SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); | ||||||
7879 | return Init; | ||||||
7880 | } | ||||||
7881 | |||||||
7882 | /// Build 'VarRef = Start + Iter * Step'. | ||||||
7883 | static ExprResult buildCounterUpdate( | ||||||
7884 | Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, | ||||||
7885 | ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, | ||||||
7886 | bool IsNonRectangularLB, | ||||||
7887 | llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { | ||||||
7888 | // Add parentheses (for debugging purposes only). | ||||||
7889 | Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); | ||||||
7890 | if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || | ||||||
7891 | !Step.isUsable()) | ||||||
7892 | return ExprError(); | ||||||
7893 | |||||||
7894 | ExprResult NewStep = Step; | ||||||
7895 | if (Captures) | ||||||
7896 | NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); | ||||||
7897 | if (NewStep.isInvalid()) | ||||||
7898 | return ExprError(); | ||||||
7899 | ExprResult Update = | ||||||
7900 | SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); | ||||||
7901 | if (!Update.isUsable()) | ||||||
7902 | return ExprError(); | ||||||
7903 | |||||||
7904 | // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or | ||||||
7905 | // 'VarRef = Start (+|-) Iter * Step'. | ||||||
7906 | if (!Start.isUsable()) | ||||||
7907 | return ExprError(); | ||||||
7908 | ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); | ||||||
7909 | if (!NewStart.isUsable()) | ||||||
7910 | return ExprError(); | ||||||
7911 | if (Captures && !IsNonRectangularLB) | ||||||
7912 | NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); | ||||||
7913 | if (NewStart.isInvalid()) | ||||||
7914 | return ExprError(); | ||||||
7915 | |||||||
7916 | // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. | ||||||
7917 | ExprResult SavedUpdate = Update; | ||||||
7918 | ExprResult UpdateVal; | ||||||
7919 | if (VarRef.get()->getType()->isOverloadableType() || | ||||||
7920 | NewStart.get()->getType()->isOverloadableType() || | ||||||
7921 | Update.get()->getType()->isOverloadableType()) { | ||||||
7922 | Sema::TentativeAnalysisScope Trap(SemaRef); | ||||||
7923 | |||||||
7924 | Update = | ||||||
7925 | SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); | ||||||
7926 | if (Update.isUsable()) { | ||||||
7927 | UpdateVal = | ||||||
7928 | SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, | ||||||
7929 | VarRef.get(), SavedUpdate.get()); | ||||||
7930 | if (UpdateVal.isUsable()) { | ||||||
7931 | Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), | ||||||
7932 | UpdateVal.get()); | ||||||
7933 | } | ||||||
7934 | } | ||||||
7935 | } | ||||||
7936 | |||||||
7937 | // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. | ||||||
7938 | if (!Update.isUsable() || !UpdateVal.isUsable()) { | ||||||
7939 | Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, | ||||||
7940 | NewStart.get(), SavedUpdate.get()); | ||||||
7941 | if (!Update.isUsable()) | ||||||
7942 | return ExprError(); | ||||||
7943 | |||||||
7944 | if (!SemaRef.Context.hasSameType(Update.get()->getType(), | ||||||
7945 | VarRef.get()->getType())) { | ||||||
7946 | Update = SemaRef.PerformImplicitConversion( | ||||||
7947 | Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); | ||||||
7948 | if (!Update.isUsable()) | ||||||
7949 | return ExprError(); | ||||||
7950 | } | ||||||
7951 | |||||||
7952 | Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); | ||||||
7953 | } | ||||||
7954 | return Update; | ||||||
7955 | } | ||||||
7956 | |||||||
7957 | /// Convert integer expression \a E to make it have at least \a Bits | ||||||
7958 | /// bits. | ||||||
7959 | static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { | ||||||
7960 | if (E == nullptr) | ||||||
7961 | return ExprError(); | ||||||
7962 | ASTContext &C = SemaRef.Context; | ||||||
7963 | QualType OldType = E->getType(); | ||||||
7964 | unsigned HasBits = C.getTypeSize(OldType); | ||||||
7965 | if (HasBits >= Bits) | ||||||
7966 | return ExprResult(E); | ||||||
7967 | // OK to convert to signed, because new type has more bits than old. | ||||||
7968 | QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); | ||||||
7969 | return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, | ||||||
7970 | true); | ||||||
7971 | } | ||||||
7972 | |||||||
7973 | /// Check if the given expression \a E is a constant integer that fits | ||||||
7974 | /// into \a Bits bits. | ||||||
7975 | static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { | ||||||
7976 | if (E == nullptr) | ||||||
7977 | return false; | ||||||
7978 | if (Optional<llvm::APSInt> Result = | ||||||
7979 | E->getIntegerConstantExpr(SemaRef.Context)) | ||||||
7980 | return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits); | ||||||
7981 | return false; | ||||||
7982 | } | ||||||
7983 | |||||||
7984 | /// Build preinits statement for the given declarations. | ||||||
7985 | static Stmt *buildPreInits(ASTContext &Context, | ||||||
7986 | MutableArrayRef<Decl *> PreInits) { | ||||||
7987 | if (!PreInits.empty()) { | ||||||
7988 | return new (Context) DeclStmt( | ||||||
7989 | DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), | ||||||
7990 | SourceLocation(), SourceLocation()); | ||||||
7991 | } | ||||||
7992 | return nullptr; | ||||||
7993 | } | ||||||
7994 | |||||||
7995 | /// Build preinits statement for the given declarations. | ||||||
7996 | static Stmt * | ||||||
7997 | buildPreInits(ASTContext &Context, | ||||||
7998 | const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { | ||||||
7999 | if (!Captures.empty()) { | ||||||
8000 | SmallVector<Decl *, 16> PreInits; | ||||||
8001 | for (const auto &Pair : Captures) | ||||||
8002 | PreInits.push_back(Pair.second->getDecl()); | ||||||
8003 | return buildPreInits(Context, PreInits); | ||||||
8004 | } | ||||||
8005 | return nullptr; | ||||||
8006 | } | ||||||
8007 | |||||||
8008 | /// Build postupdate expression for the given list of postupdates expressions. | ||||||
8009 | static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { | ||||||
8010 | Expr *PostUpdate = nullptr; | ||||||
8011 | if (!PostUpdates.empty()) { | ||||||
8012 | for (Expr *E : PostUpdates) { | ||||||
8013 | Expr *ConvE = S.BuildCStyleCastExpr( | ||||||
8014 | E->getExprLoc(), | ||||||
8015 | S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), | ||||||
8016 | E->getExprLoc(), E) | ||||||
8017 | .get(); | ||||||
8018 | PostUpdate = PostUpdate | ||||||
8019 | ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, | ||||||
8020 | PostUpdate, ConvE) | ||||||
8021 | .get() | ||||||
8022 | : ConvE; | ||||||
8023 | } | ||||||
8024 | } | ||||||
8025 | return PostUpdate; | ||||||
8026 | } | ||||||
8027 | |||||||
8028 | /// Called on a for stmt to check itself and nested loops (if any). | ||||||
8029 | /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, | ||||||
8030 | /// number of collapsed loops otherwise. | ||||||
8031 | static unsigned | ||||||
8032 | checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, | ||||||
8033 | Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, | ||||||
8034 | DSAStackTy &DSA, | ||||||
8035 | Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, | ||||||
8036 | OMPLoopDirective::HelperExprs &Built) { | ||||||
8037 | unsigned NestedLoopCount = 1; | ||||||
8038 | if (CollapseLoopCountExpr) { | ||||||
8039 | // Found 'collapse' clause - calculate collapse number. | ||||||
8040 | Expr::EvalResult Result; | ||||||
8041 | if (!CollapseLoopCountExpr->isValueDependent() && | ||||||
8042 | CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { | ||||||
8043 | NestedLoopCount = Result.Val.getInt().getLimitedValue(); | ||||||
8044 | } else { | ||||||
8045 | Built.clear(/*Size=*/1); | ||||||
8046 | return 1; | ||||||
8047 | } | ||||||
8048 | } | ||||||
8049 | unsigned OrderedLoopCount = 1; | ||||||
8050 | if (OrderedLoopCountExpr) { | ||||||
8051 | // Found 'ordered' clause - calculate collapse number. | ||||||
8052 | Expr::EvalResult EVResult; | ||||||
8053 | if (!OrderedLoopCountExpr->isValueDependent() && | ||||||
8054 | OrderedLoopCountExpr->EvaluateAsInt(EVResult, | ||||||
8055 | SemaRef.getASTContext())) { | ||||||
8056 | llvm::APSInt Result = EVResult.Val.getInt(); | ||||||
8057 | if (Result.getLimitedValue() < NestedLoopCount) { | ||||||
8058 | SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), | ||||||
8059 | diag::err_omp_wrong_ordered_loop_count) | ||||||
8060 | << OrderedLoopCountExpr->getSourceRange(); | ||||||
8061 | SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), | ||||||
8062 | diag::note_collapse_loop_count) | ||||||
8063 | << CollapseLoopCountExpr->getSourceRange(); | ||||||
8064 | } | ||||||
8065 | OrderedLoopCount = Result.getLimitedValue(); | ||||||
8066 | } else { | ||||||
8067 | Built.clear(/*Size=*/1); | ||||||
8068 | return 1; | ||||||
8069 | } | ||||||
8070 | } | ||||||
8071 | // This is helper routine for loop directives (e.g., 'for', 'simd', | ||||||
8072 | // 'for simd', etc.). | ||||||
8073 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; | ||||||
8074 | SmallVector<LoopIterationSpace, 4> IterSpaces( | ||||||
8075 | std::max(OrderedLoopCount, NestedLoopCount)); | ||||||
8076 | Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); | ||||||
8077 | for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { | ||||||
8078 | if (checkOpenMPIterationSpace( | ||||||
8079 | DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, | ||||||
8080 | std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, | ||||||
8081 | OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) | ||||||
8082 | return 0; | ||||||
8083 | // Move on to the next nested for loop, or to the loop body. | ||||||
8084 | // OpenMP [2.8.1, simd construct, Restrictions] | ||||||
8085 | // All loops associated with the construct must be perfectly nested; that | ||||||
8086 | // is, there must be no intervening code nor any OpenMP directive between | ||||||
8087 | // any two loops. | ||||||
8088 | if (auto *For = dyn_cast<ForStmt>(CurStmt)) { | ||||||
8089 | CurStmt = For->getBody(); | ||||||
8090 | } else { | ||||||
8091 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8092, __PRETTY_FUNCTION__)) | ||||||
8092 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8092, __PRETTY_FUNCTION__)); | ||||||
8093 | CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); | ||||||
8094 | } | ||||||
8095 | CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( | ||||||
8096 | CurStmt, SemaRef.LangOpts.OpenMP >= 50); | ||||||
8097 | } | ||||||
8098 | for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { | ||||||
8099 | if (checkOpenMPIterationSpace( | ||||||
8100 | DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, | ||||||
8101 | std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, | ||||||
8102 | OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) | ||||||
8103 | return 0; | ||||||
8104 | if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { | ||||||
8105 | // Handle initialization of captured loop iterator variables. | ||||||
8106 | auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); | ||||||
8107 | if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { | ||||||
8108 | Captures[DRE] = DRE; | ||||||
8109 | } | ||||||
8110 | } | ||||||
8111 | // Move on to the next nested for loop, or to the loop body. | ||||||
8112 | // OpenMP [2.8.1, simd construct, Restrictions] | ||||||
8113 | // All loops associated with the construct must be perfectly nested; that | ||||||
8114 | // is, there must be no intervening code nor any OpenMP directive between | ||||||
8115 | // any two loops. | ||||||
8116 | if (auto *For = dyn_cast<ForStmt>(CurStmt)) { | ||||||
8117 | CurStmt = For->getBody(); | ||||||
8118 | } else { | ||||||
8119 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8120, __PRETTY_FUNCTION__)) | ||||||
8120 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8120, __PRETTY_FUNCTION__)); | ||||||
8121 | CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); | ||||||
8122 | } | ||||||
8123 | CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( | ||||||
8124 | CurStmt, SemaRef.LangOpts.OpenMP >= 50); | ||||||
8125 | } | ||||||
8126 | |||||||
8127 | Built.clear(/* size */ NestedLoopCount); | ||||||
8128 | |||||||
8129 | if (SemaRef.CurContext->isDependentContext()) | ||||||
8130 | return NestedLoopCount; | ||||||
8131 | |||||||
8132 | // An example of what is generated for the following code: | ||||||
8133 | // | ||||||
8134 | // #pragma omp simd collapse(2) ordered(2) | ||||||
8135 | // for (i = 0; i < NI; ++i) | ||||||
8136 | // for (k = 0; k < NK; ++k) | ||||||
8137 | // for (j = J0; j < NJ; j+=2) { | ||||||
8138 | // <loop body> | ||||||
8139 | // } | ||||||
8140 | // | ||||||
8141 | // We generate the code below. | ||||||
8142 | // Note: the loop body may be outlined in CodeGen. | ||||||
8143 | // Note: some counters may be C++ classes, operator- is used to find number of | ||||||
8144 | // iterations and operator+= to calculate counter value. | ||||||
8145 | // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 | ||||||
8146 | // or i64 is currently supported). | ||||||
8147 | // | ||||||
8148 | // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) | ||||||
8149 | // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { | ||||||
8150 | // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); | ||||||
8151 | // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; | ||||||
8152 | // // similar updates for vars in clauses (e.g. 'linear') | ||||||
8153 | // <loop body (using local i and j)> | ||||||
8154 | // } | ||||||
8155 | // i = NI; // assign final values of counters | ||||||
8156 | // j = NJ; | ||||||
8157 | // | ||||||
8158 | |||||||
8159 | // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are | ||||||
8160 | // the iteration counts of the collapsed for loops. | ||||||
8161 | // Precondition tests if there is at least one iteration (all conditions are | ||||||
8162 | // true). | ||||||
8163 | auto PreCond = ExprResult(IterSpaces[0].PreCond); | ||||||
8164 | Expr *N0 = IterSpaces[0].NumIterations; | ||||||
8165 | ExprResult LastIteration32 = | ||||||
8166 | widenIterationCount(/*Bits=*/32, | ||||||
8167 | SemaRef | ||||||
8168 | .PerformImplicitConversion( | ||||||
8169 | N0->IgnoreImpCasts(), N0->getType(), | ||||||
8170 | Sema::AA_Converting, /*AllowExplicit=*/true) | ||||||
8171 | .get(), | ||||||
8172 | SemaRef); | ||||||
8173 | ExprResult LastIteration64 = widenIterationCount( | ||||||
8174 | /*Bits=*/64, | ||||||
8175 | SemaRef | ||||||
8176 | .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), | ||||||
8177 | Sema::AA_Converting, | ||||||
8178 | /*AllowExplicit=*/true) | ||||||
8179 | .get(), | ||||||
8180 | SemaRef); | ||||||
8181 | |||||||
8182 | if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) | ||||||
8183 | return NestedLoopCount; | ||||||
8184 | |||||||
8185 | ASTContext &C = SemaRef.Context; | ||||||
8186 | bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; | ||||||
8187 | |||||||
8188 | Scope *CurScope = DSA.getCurScope(); | ||||||
8189 | for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { | ||||||
8190 | if (PreCond.isUsable()) { | ||||||
8191 | PreCond = | ||||||
8192 | SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, | ||||||
8193 | PreCond.get(), IterSpaces[Cnt].PreCond); | ||||||
8194 | } | ||||||
8195 | Expr *N = IterSpaces[Cnt].NumIterations; | ||||||
8196 | SourceLocation Loc = N->getExprLoc(); | ||||||
8197 | AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; | ||||||
8198 | if (LastIteration32.isUsable()) | ||||||
8199 | LastIteration32 = SemaRef.BuildBinOp( | ||||||
8200 | CurScope, Loc, BO_Mul, LastIteration32.get(), | ||||||
8201 | SemaRef | ||||||
8202 | .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), | ||||||
8203 | Sema::AA_Converting, | ||||||
8204 | /*AllowExplicit=*/true) | ||||||
8205 | .get()); | ||||||
8206 | if (LastIteration64.isUsable()) | ||||||
8207 | LastIteration64 = SemaRef.BuildBinOp( | ||||||
8208 | CurScope, Loc, BO_Mul, LastIteration64.get(), | ||||||
8209 | SemaRef | ||||||
8210 | .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), | ||||||
8211 | Sema::AA_Converting, | ||||||
8212 | /*AllowExplicit=*/true) | ||||||
8213 | .get()); | ||||||
8214 | } | ||||||
8215 | |||||||
8216 | // Choose either the 32-bit or 64-bit version. | ||||||
8217 | ExprResult LastIteration = LastIteration64; | ||||||
8218 | if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || | ||||||
8219 | (LastIteration32.isUsable() && | ||||||
8220 | C.getTypeSize(LastIteration32.get()->getType()) == 32 && | ||||||
8221 | (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || | ||||||
8222 | fitsInto( | ||||||
8223 | /*Bits=*/32, | ||||||
8224 | LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), | ||||||
8225 | LastIteration64.get(), SemaRef)))) | ||||||
8226 | LastIteration = LastIteration32; | ||||||
8227 | QualType VType = LastIteration.get()->getType(); | ||||||
8228 | QualType RealVType = VType; | ||||||
8229 | QualType StrideVType = VType; | ||||||
8230 | if (isOpenMPTaskLoopDirective(DKind)) { | ||||||
8231 | VType = | ||||||
8232 | SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); | ||||||
8233 | StrideVType = | ||||||
8234 | SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); | ||||||
8235 | } | ||||||
8236 | |||||||
8237 | if (!LastIteration.isUsable()) | ||||||
8238 | return 0; | ||||||
8239 | |||||||
8240 | // Save the number of iterations. | ||||||
8241 | ExprResult NumIterations = LastIteration; | ||||||
8242 | { | ||||||
8243 | LastIteration = SemaRef.BuildBinOp( | ||||||
8244 | CurScope, LastIteration.get()->getExprLoc(), BO_Sub, | ||||||
8245 | LastIteration.get(), | ||||||
8246 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); | ||||||
8247 | if (!LastIteration.isUsable()) | ||||||
8248 | return 0; | ||||||
8249 | } | ||||||
8250 | |||||||
8251 | // Calculate the last iteration number beforehand instead of doing this on | ||||||
8252 | // each iteration. Do not do this if the number of iterations may be kfold-ed. | ||||||
8253 | bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context); | ||||||
8254 | ExprResult CalcLastIteration; | ||||||
8255 | if (!IsConstant) { | ||||||
8256 | ExprResult SaveRef = | ||||||
8257 | tryBuildCapture(SemaRef, LastIteration.get(), Captures); | ||||||
8258 | LastIteration = SaveRef; | ||||||
8259 | |||||||
8260 | // Prepare SaveRef + 1. | ||||||
8261 | NumIterations = SemaRef.BuildBinOp( | ||||||
8262 | CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), | ||||||
8263 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); | ||||||
8264 | if (!NumIterations.isUsable()) | ||||||
8265 | return 0; | ||||||
8266 | } | ||||||
8267 | |||||||
8268 | SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); | ||||||
8269 | |||||||
8270 | // Build variables passed into runtime, necessary for worksharing directives. | ||||||
8271 | ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; | ||||||
8272 | if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || | ||||||
8273 | isOpenMPDistributeDirective(DKind)) { | ||||||
8274 | // Lower bound variable, initialized with zero. | ||||||
8275 | VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); | ||||||
8276 | LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); | ||||||
8277 | SemaRef.AddInitializerToDecl(LBDecl, | ||||||
8278 | SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), | ||||||
8279 | /*DirectInit*/ false); | ||||||
8280 | |||||||
8281 | // Upper bound variable, initialized with last iteration number. | ||||||
8282 | VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); | ||||||
8283 | UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); | ||||||
8284 | SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), | ||||||
8285 | /*DirectInit*/ false); | ||||||
8286 | |||||||
8287 | // A 32-bit variable-flag where runtime returns 1 for the last iteration. | ||||||
8288 | // This will be used to implement clause 'lastprivate'. | ||||||
8289 | QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); | ||||||
8290 | VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); | ||||||
8291 | IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); | ||||||
8292 | SemaRef.AddInitializerToDecl(ILDecl, | ||||||
8293 | SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), | ||||||
8294 | /*DirectInit*/ false); | ||||||
8295 | |||||||
8296 | // Stride variable returned by runtime (we initialize it to 1 by default). | ||||||
8297 | VarDecl *STDecl = | ||||||
8298 | buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); | ||||||
8299 | ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); | ||||||
8300 | SemaRef.AddInitializerToDecl(STDecl, | ||||||
8301 | SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), | ||||||
8302 | /*DirectInit*/ false); | ||||||
8303 | |||||||
8304 | // Build expression: UB = min(UB, LastIteration) | ||||||
8305 | // It is necessary for CodeGen of directives with static scheduling. | ||||||
8306 | ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, | ||||||
8307 | UB.get(), LastIteration.get()); | ||||||
8308 | ExprResult CondOp = SemaRef.ActOnConditionalOp( | ||||||
8309 | LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), | ||||||
8310 | LastIteration.get(), UB.get()); | ||||||
8311 | EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), | ||||||
8312 | CondOp.get()); | ||||||
8313 | EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); | ||||||
8314 | |||||||
8315 | // If we have a combined directive that combines 'distribute', 'for' or | ||||||
8316 | // 'simd' we need to be able to access the bounds of the schedule of the | ||||||
8317 | // enclosing region. E.g. in 'distribute parallel for' the bounds obtained | ||||||
8318 | // by scheduling 'distribute' have to be passed to the schedule of 'for'. | ||||||
8319 | if (isOpenMPLoopBoundSharingDirective(DKind)) { | ||||||
8320 | // Lower bound variable, initialized with zero. | ||||||
8321 | VarDecl *CombLBDecl = | ||||||
8322 | buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); | ||||||
8323 | CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); | ||||||
8324 | SemaRef.AddInitializerToDecl( | ||||||
8325 | CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), | ||||||
8326 | /*DirectInit*/ false); | ||||||
8327 | |||||||
8328 | // Upper bound variable, initialized with last iteration number. | ||||||
8329 | VarDecl *CombUBDecl = | ||||||
8330 | buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); | ||||||
8331 | CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); | ||||||
8332 | SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), | ||||||
8333 | /*DirectInit*/ false); | ||||||
8334 | |||||||
8335 | ExprResult CombIsUBGreater = SemaRef.BuildBinOp( | ||||||
8336 | CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); | ||||||
8337 | ExprResult CombCondOp = | ||||||
8338 | SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), | ||||||
8339 | LastIteration.get(), CombUB.get()); | ||||||
8340 | CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), | ||||||
8341 | CombCondOp.get()); | ||||||
8342 | CombEUB = | ||||||
8343 | SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); | ||||||
8344 | |||||||
8345 | const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); | ||||||
8346 | // We expect to have at least 2 more parameters than the 'parallel' | ||||||
8347 | // directive does - the lower and upper bounds of the previous schedule. | ||||||
8348 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8349, __PRETTY_FUNCTION__)) | ||||||
8349 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8349, __PRETTY_FUNCTION__)); | ||||||
8350 | |||||||
8351 | // Set the proper type for the bounds given what we learned from the | ||||||
8352 | // enclosed loops. | ||||||
8353 | ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); | ||||||
8354 | ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); | ||||||
8355 | |||||||
8356 | // Previous lower and upper bounds are obtained from the region | ||||||
8357 | // parameters. | ||||||
8358 | PrevLB = | ||||||
8359 | buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); | ||||||
8360 | PrevUB = | ||||||
8361 | buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); | ||||||
8362 | } | ||||||
8363 | } | ||||||
8364 | |||||||
8365 | // Build the iteration variable and its initialization before loop. | ||||||
8366 | ExprResult IV; | ||||||
8367 | ExprResult Init, CombInit; | ||||||
8368 | { | ||||||
8369 | VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); | ||||||
8370 | IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); | ||||||
8371 | Expr *RHS = | ||||||
8372 | (isOpenMPWorksharingDirective(DKind) || | ||||||
8373 | isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) | ||||||
8374 | ? LB.get() | ||||||
8375 | : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); | ||||||
8376 | Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); | ||||||
8377 | Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); | ||||||
8378 | |||||||
8379 | if (isOpenMPLoopBoundSharingDirective(DKind)) { | ||||||
8380 | Expr *CombRHS = | ||||||
8381 | (isOpenMPWorksharingDirective(DKind) || | ||||||
8382 | isOpenMPTaskLoopDirective(DKind) || | ||||||
8383 | isOpenMPDistributeDirective(DKind)) | ||||||
8384 | ? CombLB.get() | ||||||
8385 | : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); | ||||||
8386 | CombInit = | ||||||
8387 | SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); | ||||||
8388 | CombInit = | ||||||
8389 | SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); | ||||||
8390 | } | ||||||
8391 | } | ||||||
8392 | |||||||
8393 | bool UseStrictCompare = | ||||||
8394 | RealVType->hasUnsignedIntegerRepresentation() && | ||||||
8395 | llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { | ||||||
8396 | return LIS.IsStrictCompare; | ||||||
8397 | }); | ||||||
8398 | // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for | ||||||
8399 | // unsigned IV)) for worksharing loops. | ||||||
8400 | SourceLocation CondLoc = AStmt->getBeginLoc(); | ||||||
8401 | Expr *BoundUB = UB.get(); | ||||||
8402 | if (UseStrictCompare) { | ||||||
8403 | BoundUB = | ||||||
8404 | SemaRef | ||||||
8405 | .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, | ||||||
8406 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) | ||||||
8407 | .get(); | ||||||
8408 | BoundUB = | ||||||
8409 | SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); | ||||||
8410 | } | ||||||
8411 | ExprResult Cond = | ||||||
8412 | (isOpenMPWorksharingDirective(DKind) || | ||||||
8413 | isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) | ||||||
8414 | ? SemaRef.BuildBinOp(CurScope, CondLoc, | ||||||
8415 | UseStrictCompare ? BO_LT : BO_LE, IV.get(), | ||||||
8416 | BoundUB) | ||||||
8417 | : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), | ||||||
8418 | NumIterations.get()); | ||||||
8419 | ExprResult CombDistCond; | ||||||
8420 | if (isOpenMPLoopBoundSharingDirective(DKind)) { | ||||||
8421 | CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), | ||||||
8422 | NumIterations.get()); | ||||||
8423 | } | ||||||
8424 | |||||||
8425 | ExprResult CombCond; | ||||||
8426 | if (isOpenMPLoopBoundSharingDirective(DKind)) { | ||||||
8427 | Expr *BoundCombUB = CombUB.get(); | ||||||
8428 | if (UseStrictCompare) { | ||||||
8429 | BoundCombUB = | ||||||
8430 | SemaRef | ||||||
8431 | .BuildBinOp( | ||||||
8432 | CurScope, CondLoc, BO_Add, BoundCombUB, | ||||||
8433 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) | ||||||
8434 | .get(); | ||||||
8435 | BoundCombUB = | ||||||
8436 | SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) | ||||||
8437 | .get(); | ||||||
8438 | } | ||||||
8439 | CombCond = | ||||||
8440 | SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, | ||||||
8441 | IV.get(), BoundCombUB); | ||||||
8442 | } | ||||||
8443 | // Loop increment (IV = IV + 1) | ||||||
8444 | SourceLocation IncLoc = AStmt->getBeginLoc(); | ||||||
8445 | ExprResult Inc = | ||||||
8446 | SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), | ||||||
8447 | SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); | ||||||
8448 | if (!Inc.isUsable()) | ||||||
8449 | return 0; | ||||||
8450 | Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); | ||||||
8451 | Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); | ||||||
8452 | if (!Inc.isUsable()) | ||||||
8453 | return 0; | ||||||
8454 | |||||||
8455 | // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). | ||||||
8456 | // Used for directives with static scheduling. | ||||||
8457 | // In combined construct, add combined version that use CombLB and CombUB | ||||||
8458 | // base variables for the update | ||||||
8459 | ExprResult NextLB, NextUB, CombNextLB, CombNextUB; | ||||||
8460 | if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || | ||||||
8461 | isOpenMPDistributeDirective(DKind)) { | ||||||
8462 | // LB + ST | ||||||
8463 | NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); | ||||||
8464 | if (!NextLB.isUsable()) | ||||||
8465 | return 0; | ||||||
8466 | // LB = LB + ST | ||||||
8467 | NextLB = | ||||||
8468 | SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); | ||||||
8469 | NextLB = | ||||||
8470 | SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); | ||||||
8471 | if (!NextLB.isUsable()) | ||||||
8472 | return 0; | ||||||
8473 | // UB + ST | ||||||
8474 | NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); | ||||||
8475 | if (!NextUB.isUsable()) | ||||||
8476 | return 0; | ||||||
8477 | // UB = UB + ST | ||||||
8478 | NextUB = | ||||||
8479 | SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); | ||||||
8480 | NextUB = | ||||||
8481 | SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); | ||||||
8482 | if (!NextUB.isUsable()) | ||||||
8483 | return 0; | ||||||
8484 | if (isOpenMPLoopBoundSharingDirective(DKind)) { | ||||||
8485 | CombNextLB = | ||||||
8486 | SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); | ||||||
8487 | if (!NextLB.isUsable()) | ||||||
8488 | return 0; | ||||||
8489 | // LB = LB + ST | ||||||
8490 | CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), | ||||||
8491 | CombNextLB.get()); | ||||||
8492 | CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), | ||||||
8493 | /*DiscardedValue*/ false); | ||||||
8494 | if (!CombNextLB.isUsable()) | ||||||
8495 | return 0; | ||||||
8496 | // UB + ST | ||||||
8497 | CombNextUB = | ||||||
8498 | SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); | ||||||
8499 | if (!CombNextUB.isUsable()) | ||||||
8500 | return 0; | ||||||
8501 | // UB = UB + ST | ||||||
8502 | CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), | ||||||
8503 | CombNextUB.get()); | ||||||
8504 | CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), | ||||||
8505 | /*DiscardedValue*/ false); | ||||||
8506 | if (!CombNextUB.isUsable()) | ||||||
8507 | return 0; | ||||||
8508 | } | ||||||
8509 | } | ||||||
8510 | |||||||
8511 | // Create increment expression for distribute loop when combined in a same | ||||||
8512 | // directive with for as IV = IV + ST; ensure upper bound expression based | ||||||
8513 | // on PrevUB instead of NumIterations - used to implement 'for' when found | ||||||
8514 | // in combination with 'distribute', like in 'distribute parallel for' | ||||||
8515 | SourceLocation DistIncLoc = AStmt->getBeginLoc(); | ||||||
8516 | ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; | ||||||
8517 | if (isOpenMPLoopBoundSharingDirective(DKind)) { | ||||||
8518 | DistCond = SemaRef.BuildBinOp( | ||||||
8519 | CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); | ||||||
8520 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8520, __PRETTY_FUNCTION__)); | ||||||
8521 | |||||||
8522 | DistInc = | ||||||
8523 | SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); | ||||||
8524 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8524, __PRETTY_FUNCTION__)); | ||||||
8525 | DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), | ||||||
8526 | DistInc.get()); | ||||||
8527 | DistInc = | ||||||
8528 | SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); | ||||||
8529 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8529, __PRETTY_FUNCTION__)); | ||||||
8530 | |||||||
8531 | // Build expression: UB = min(UB, prevUB) for #for in composite or combined | ||||||
8532 | // construct | ||||||
8533 | SourceLocation DistEUBLoc = AStmt->getBeginLoc(); | ||||||
8534 | ExprResult IsUBGreater = | ||||||
8535 | SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); | ||||||
8536 | ExprResult CondOp = SemaRef.ActOnConditionalOp( | ||||||
8537 | DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); | ||||||
8538 | PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), | ||||||
8539 | CondOp.get()); | ||||||
8540 | PrevEUB = | ||||||
8541 | SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); | ||||||
8542 | |||||||
8543 | // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in | ||||||
8544 | // parallel for is in combination with a distribute directive with | ||||||
8545 | // schedule(static, 1) | ||||||
8546 | Expr *BoundPrevUB = PrevUB.get(); | ||||||
8547 | if (UseStrictCompare) { | ||||||
8548 | BoundPrevUB = | ||||||
8549 | SemaRef | ||||||
8550 | .BuildBinOp( | ||||||
8551 | CurScope, CondLoc, BO_Add, BoundPrevUB, | ||||||
8552 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) | ||||||
8553 | .get(); | ||||||
8554 | BoundPrevUB = | ||||||
8555 | SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) | ||||||
8556 | .get(); | ||||||
8557 | } | ||||||
8558 | ParForInDistCond = | ||||||
8559 | SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, | ||||||
8560 | IV.get(), BoundPrevUB); | ||||||
8561 | } | ||||||
8562 | |||||||
8563 | // Build updates and final values of the loop counters. | ||||||
8564 | bool HasErrors = false; | ||||||
8565 | Built.Counters.resize(NestedLoopCount); | ||||||
8566 | Built.Inits.resize(NestedLoopCount); | ||||||
8567 | Built.Updates.resize(NestedLoopCount); | ||||||
8568 | Built.Finals.resize(NestedLoopCount); | ||||||
8569 | Built.DependentCounters.resize(NestedLoopCount); | ||||||
8570 | Built.DependentInits.resize(NestedLoopCount); | ||||||
8571 | Built.FinalsConditions.resize(NestedLoopCount); | ||||||
8572 | { | ||||||
8573 | // We implement the following algorithm for obtaining the | ||||||
8574 | // original loop iteration variable values based on the | ||||||
8575 | // value of the collapsed loop iteration variable IV. | ||||||
8576 | // | ||||||
8577 | // Let n+1 be the number of collapsed loops in the nest. | ||||||
8578 | // Iteration variables (I0, I1, .... In) | ||||||
8579 | // Iteration counts (N0, N1, ... Nn) | ||||||
8580 | // | ||||||
8581 | // Acc = IV; | ||||||
8582 | // | ||||||
8583 | // To compute Ik for loop k, 0 <= k <= n, generate: | ||||||
8584 | // Prod = N(k+1) * N(k+2) * ... * Nn; | ||||||
8585 | // Ik = Acc / Prod; | ||||||
8586 | // Acc -= Ik * Prod; | ||||||
8587 | // | ||||||
8588 | ExprResult Acc = IV; | ||||||
8589 | for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { | ||||||
8590 | LoopIterationSpace &IS = IterSpaces[Cnt]; | ||||||
8591 | SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); | ||||||
8592 | ExprResult Iter; | ||||||
8593 | |||||||
8594 | // Compute prod | ||||||
8595 | ExprResult Prod = | ||||||
8596 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); | ||||||
8597 | for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) | ||||||
8598 | Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), | ||||||
8599 | IterSpaces[K].NumIterations); | ||||||
8600 | |||||||
8601 | // Iter = Acc / Prod | ||||||
8602 | // If there is at least one more inner loop to avoid | ||||||
8603 | // multiplication by 1. | ||||||
8604 | if (Cnt + 1 < NestedLoopCount) | ||||||
8605 | Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, | ||||||
8606 | Acc.get(), Prod.get()); | ||||||
8607 | else | ||||||
8608 | Iter = Acc; | ||||||
8609 | if (!Iter.isUsable()) { | ||||||
8610 | HasErrors = true; | ||||||
8611 | break; | ||||||
8612 | } | ||||||
8613 | |||||||
8614 | // Update Acc: | ||||||
8615 | // Acc -= Iter * Prod | ||||||
8616 | // Check if there is at least one more inner loop to avoid | ||||||
8617 | // multiplication by 1. | ||||||
8618 | if (Cnt + 1 < NestedLoopCount) | ||||||
8619 | Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, | ||||||
8620 | Iter.get(), Prod.get()); | ||||||
8621 | else | ||||||
8622 | Prod = Iter; | ||||||
8623 | Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, | ||||||
8624 | Acc.get(), Prod.get()); | ||||||
8625 | |||||||
8626 | // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step | ||||||
8627 | auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); | ||||||
8628 | DeclRefExpr *CounterVar = buildDeclRefExpr( | ||||||
8629 | SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), | ||||||
8630 | /*RefersToCapture=*/true); | ||||||
8631 | ExprResult Init = | ||||||
8632 | buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, | ||||||
8633 | IS.CounterInit, IS.IsNonRectangularLB, Captures); | ||||||
8634 | if (!Init.isUsable()) { | ||||||
8635 | HasErrors = true; | ||||||
8636 | break; | ||||||
8637 | } | ||||||
8638 | ExprResult Update = buildCounterUpdate( | ||||||
8639 | SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, | ||||||
8640 | IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); | ||||||
8641 | if (!Update.isUsable()) { | ||||||
8642 | HasErrors = true; | ||||||
8643 | break; | ||||||
8644 | } | ||||||
8645 | |||||||
8646 | // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step | ||||||
8647 | ExprResult Final = | ||||||
8648 | buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, | ||||||
8649 | IS.CounterInit, IS.NumIterations, IS.CounterStep, | ||||||
8650 | IS.Subtract, IS.IsNonRectangularLB, &Captures); | ||||||
8651 | if (!Final.isUsable()) { | ||||||
8652 | HasErrors = true; | ||||||
8653 | break; | ||||||
8654 | } | ||||||
8655 | |||||||
8656 | if (!Update.isUsable() || !Final.isUsable()) { | ||||||
8657 | HasErrors = true; | ||||||
8658 | break; | ||||||
8659 | } | ||||||
8660 | // Save results | ||||||
8661 | Built.Counters[Cnt] = IS.CounterVar; | ||||||
8662 | Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; | ||||||
8663 | Built.Inits[Cnt] = Init.get(); | ||||||
8664 | Built.Updates[Cnt] = Update.get(); | ||||||
8665 | Built.Finals[Cnt] = Final.get(); | ||||||
8666 | Built.DependentCounters[Cnt] = nullptr; | ||||||
8667 | Built.DependentInits[Cnt] = nullptr; | ||||||
8668 | Built.FinalsConditions[Cnt] = nullptr; | ||||||
8669 | if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { | ||||||
8670 | Built.DependentCounters[Cnt] = | ||||||
8671 | Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; | ||||||
8672 | Built.DependentInits[Cnt] = | ||||||
8673 | Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; | ||||||
8674 | Built.FinalsConditions[Cnt] = IS.FinalCondition; | ||||||
8675 | } | ||||||
8676 | } | ||||||
8677 | } | ||||||
8678 | |||||||
8679 | if (HasErrors) | ||||||
8680 | return 0; | ||||||
8681 | |||||||
8682 | // Save results | ||||||
8683 | Built.IterationVarRef = IV.get(); | ||||||
8684 | Built.LastIteration = LastIteration.get(); | ||||||
8685 | Built.NumIterations = NumIterations.get(); | ||||||
8686 | Built.CalcLastIteration = SemaRef | ||||||
8687 | .ActOnFinishFullExpr(CalcLastIteration.get(), | ||||||
8688 | /*DiscardedValue=*/false) | ||||||
8689 | .get(); | ||||||
8690 | Built.PreCond = PreCond.get(); | ||||||
8691 | Built.PreInits = buildPreInits(C, Captures); | ||||||
8692 | Built.Cond = Cond.get(); | ||||||
8693 | Built.Init = Init.get(); | ||||||
8694 | Built.Inc = Inc.get(); | ||||||
8695 | Built.LB = LB.get(); | ||||||
8696 | Built.UB = UB.get(); | ||||||
8697 | Built.IL = IL.get(); | ||||||
8698 | Built.ST = ST.get(); | ||||||
8699 | Built.EUB = EUB.get(); | ||||||
8700 | Built.NLB = NextLB.get(); | ||||||
8701 | Built.NUB = NextUB.get(); | ||||||
8702 | Built.PrevLB = PrevLB.get(); | ||||||
8703 | Built.PrevUB = PrevUB.get(); | ||||||
8704 | Built.DistInc = DistInc.get(); | ||||||
8705 | Built.PrevEUB = PrevEUB.get(); | ||||||
8706 | Built.DistCombinedFields.LB = CombLB.get(); | ||||||
8707 | Built.DistCombinedFields.UB = CombUB.get(); | ||||||
8708 | Built.DistCombinedFields.EUB = CombEUB.get(); | ||||||
8709 | Built.DistCombinedFields.Init = CombInit.get(); | ||||||
8710 | Built.DistCombinedFields.Cond = CombCond.get(); | ||||||
8711 | Built.DistCombinedFields.NLB = CombNextLB.get(); | ||||||
8712 | Built.DistCombinedFields.NUB = CombNextUB.get(); | ||||||
8713 | Built.DistCombinedFields.DistCond = CombDistCond.get(); | ||||||
8714 | Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); | ||||||
8715 | |||||||
8716 | return NestedLoopCount; | ||||||
8717 | } | ||||||
8718 | |||||||
8719 | static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { | ||||||
8720 | auto CollapseClauses = | ||||||
8721 | OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); | ||||||
8722 | if (CollapseClauses.begin() != CollapseClauses.end()) | ||||||
8723 | return (*CollapseClauses.begin())->getNumForLoops(); | ||||||
8724 | return nullptr; | ||||||
8725 | } | ||||||
8726 | |||||||
8727 | static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { | ||||||
8728 | auto OrderedClauses = | ||||||
8729 | OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); | ||||||
8730 | if (OrderedClauses.begin() != OrderedClauses.end()) | ||||||
8731 | return (*OrderedClauses.begin())->getNumForLoops(); | ||||||
8732 | return nullptr; | ||||||
8733 | } | ||||||
8734 | |||||||
8735 | static bool checkSimdlenSafelenSpecified(Sema &S, | ||||||
8736 | const ArrayRef<OMPClause *> Clauses) { | ||||||
8737 | const OMPSafelenClause *Safelen = nullptr; | ||||||
8738 | const OMPSimdlenClause *Simdlen = nullptr; | ||||||
8739 | |||||||
8740 | for (const OMPClause *Clause : Clauses) { | ||||||
8741 | if (Clause->getClauseKind() == OMPC_safelen) | ||||||
8742 | Safelen = cast<OMPSafelenClause>(Clause); | ||||||
8743 | else if (Clause->getClauseKind() == OMPC_simdlen) | ||||||
8744 | Simdlen = cast<OMPSimdlenClause>(Clause); | ||||||
8745 | if (Safelen && Simdlen) | ||||||
8746 | break; | ||||||
8747 | } | ||||||
8748 | |||||||
8749 | if (Simdlen && Safelen) { | ||||||
8750 | const Expr *SimdlenLength = Simdlen->getSimdlen(); | ||||||
8751 | const Expr *SafelenLength = Safelen->getSafelen(); | ||||||
8752 | if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || | ||||||
8753 | SimdlenLength->isInstantiationDependent() || | ||||||
8754 | SimdlenLength->containsUnexpandedParameterPack()) | ||||||
8755 | return false; | ||||||
8756 | if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || | ||||||
8757 | SafelenLength->isInstantiationDependent() || | ||||||
8758 | SafelenLength->containsUnexpandedParameterPack()) | ||||||
8759 | return false; | ||||||
8760 | Expr::EvalResult SimdlenResult, SafelenResult; | ||||||
8761 | SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); | ||||||
8762 | SafelenLength->EvaluateAsInt(SafelenResult, S.Context); | ||||||
8763 | llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); | ||||||
8764 | llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); | ||||||
8765 | // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] | ||||||
8766 | // If both simdlen and safelen clauses are specified, the value of the | ||||||
8767 | // simdlen parameter must be less than or equal to the value of the safelen | ||||||
8768 | // parameter. | ||||||
8769 | if (SimdlenRes > SafelenRes) { | ||||||
8770 | S.Diag(SimdlenLength->getExprLoc(), | ||||||
8771 | diag::err_omp_wrong_simdlen_safelen_values) | ||||||
8772 | << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); | ||||||
8773 | return true; | ||||||
8774 | } | ||||||
8775 | } | ||||||
8776 | return false; | ||||||
8777 | } | ||||||
8778 | |||||||
8779 | StmtResult | ||||||
8780 | Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, | ||||||
8781 | SourceLocation StartLoc, SourceLocation EndLoc, | ||||||
8782 | VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||
8783 | if (!AStmt) | ||||||
8784 | return StmtError(); | ||||||
8785 | |||||||
8786 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8786, __PRETTY_FUNCTION__)); | ||||||
8787 | OMPLoopDirective::HelperExprs B; | ||||||
8788 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||||
8789 | // define the nested loops number. | ||||||
8790 | unsigned NestedLoopCount = checkOpenMPLoop( | ||||||
8791 | OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), | ||||||
8792 | AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VarsWithImplicitDSA, B); | ||||||
8793 | if (NestedLoopCount == 0) | ||||||
8794 | return StmtError(); | ||||||
8795 | |||||||
8796 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8797, __PRETTY_FUNCTION__)) | ||||||
8797 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8797, __PRETTY_FUNCTION__)); | ||||||
8798 | |||||||
8799 | if (!CurContext->isDependentContext()) { | ||||||
8800 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||
8801 | for (OMPClause *C : Clauses) { | ||||||
8802 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||
8803 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||
8804 | B.NumIterations, *this, CurScope, | ||||||
8805 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||
8806 | return StmtError(); | ||||||
8807 | } | ||||||
8808 | } | ||||||
8809 | |||||||
8810 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||
8811 | return StmtError(); | ||||||
8812 | |||||||
8813 | setFunctionHasBranchProtectedScope(); | ||||||
8814 | return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, | ||||||
8815 | Clauses, AStmt, B); | ||||||
8816 | } | ||||||
8817 | |||||||
8818 | StmtResult | ||||||
8819 | Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, | ||||||
8820 | SourceLocation StartLoc, SourceLocation EndLoc, | ||||||
8821 | VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||
8822 | if (!AStmt) | ||||||
8823 | return StmtError(); | ||||||
8824 | |||||||
8825 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8825, __PRETTY_FUNCTION__)); | ||||||
8826 | OMPLoopDirective::HelperExprs B; | ||||||
8827 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||||
8828 | // define the nested loops number. | ||||||
8829 | unsigned NestedLoopCount = checkOpenMPLoop( | ||||||
8830 | OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), | ||||||
8831 | AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VarsWithImplicitDSA, B); | ||||||
8832 | if (NestedLoopCount == 0) | ||||||
8833 | return StmtError(); | ||||||
8834 | |||||||
8835 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8836, __PRETTY_FUNCTION__)) | ||||||
8836 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8836, __PRETTY_FUNCTION__)); | ||||||
8837 | |||||||
8838 | if (!CurContext->isDependentContext()) { | ||||||
8839 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||
8840 | for (OMPClause *C : Clauses) { | ||||||
8841 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||
8842 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||
8843 | B.NumIterations, *this, CurScope, | ||||||
8844 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||
8845 | return StmtError(); | ||||||
8846 | } | ||||||
8847 | } | ||||||
8848 | |||||||
8849 | setFunctionHasBranchProtectedScope(); | ||||||
8850 | return OMPForDirective::Create( | ||||||
8851 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, | ||||||
8852 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||
8853 | } | ||||||
8854 | |||||||
8855 | StmtResult Sema::ActOnOpenMPForSimdDirective( | ||||||
8856 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||
8857 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||
8858 | if (!AStmt) | ||||||
8859 | return StmtError(); | ||||||
8860 | |||||||
8861 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8861, __PRETTY_FUNCTION__)); | ||||||
8862 | OMPLoopDirective::HelperExprs B; | ||||||
8863 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||||
8864 | // define the nested loops number. | ||||||
8865 | unsigned NestedLoopCount = | ||||||
8866 | checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), | ||||||
8867 | getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||
8868 | VarsWithImplicitDSA, B); | ||||||
8869 | if (NestedLoopCount == 0) | ||||||
8870 | return StmtError(); | ||||||
8871 | |||||||
8872 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8873, __PRETTY_FUNCTION__)) | ||||||
8873 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8873, __PRETTY_FUNCTION__)); | ||||||
8874 | |||||||
8875 | if (!CurContext->isDependentContext()) { | ||||||
8876 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||
8877 | for (OMPClause *C : Clauses) { | ||||||
8878 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||
8879 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||
8880 | B.NumIterations, *this, CurScope, | ||||||
8881 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||
8882 | return StmtError(); | ||||||
8883 | } | ||||||
8884 | } | ||||||
8885 | |||||||
8886 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||
8887 | return StmtError(); | ||||||
8888 | |||||||
8889 | setFunctionHasBranchProtectedScope(); | ||||||
8890 | return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, | ||||||
8891 | Clauses, AStmt, B); | ||||||
8892 | } | ||||||
8893 | |||||||
8894 | StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, | ||||||
8895 | Stmt *AStmt, | ||||||
8896 | SourceLocation StartLoc, | ||||||
8897 | SourceLocation EndLoc) { | ||||||
8898 | if (!AStmt) | ||||||
8899 | return StmtError(); | ||||||
8900 | |||||||
8901 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8901, __PRETTY_FUNCTION__)); | ||||||
8902 | auto BaseStmt = AStmt; | ||||||
8903 | while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) | ||||||
8904 | BaseStmt = CS->getCapturedStmt(); | ||||||
8905 | if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { | ||||||
8906 | auto S = C->children(); | ||||||
8907 | if (S.begin() == S.end()) | ||||||
8908 | return StmtError(); | ||||||
8909 | // All associated statements must be '#pragma omp section' except for | ||||||
8910 | // the first one. | ||||||
8911 | for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { | ||||||
8912 | if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { | ||||||
8913 | if (SectionStmt) | ||||||
8914 | Diag(SectionStmt->getBeginLoc(), | ||||||
8915 | diag::err_omp_sections_substmt_not_section); | ||||||
8916 | return StmtError(); | ||||||
8917 | } | ||||||
8918 | cast<OMPSectionDirective>(SectionStmt) | ||||||
8919 | ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||
8920 | } | ||||||
8921 | } else { | ||||||
8922 | Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); | ||||||
8923 | return StmtError(); | ||||||
8924 | } | ||||||
8925 | |||||||
8926 | setFunctionHasBranchProtectedScope(); | ||||||
8927 | |||||||
8928 | return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, | ||||||
8929 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), | ||||||
8930 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||
8931 | } | ||||||
8932 | |||||||
8933 | StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, | ||||||
8934 | SourceLocation StartLoc, | ||||||
8935 | SourceLocation EndLoc) { | ||||||
8936 | if (!AStmt) | ||||||
8937 | return StmtError(); | ||||||
8938 | |||||||
8939 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8939, __PRETTY_FUNCTION__)); | ||||||
8940 | |||||||
8941 | setFunctionHasBranchProtectedScope(); | ||||||
8942 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentCancelRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||
8943 | |||||||
8944 | return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, | ||||||
8945 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||
8946 | } | ||||||
8947 | |||||||
8948 | StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, | ||||||
8949 | Stmt *AStmt, | ||||||
8950 | SourceLocation StartLoc, | ||||||
8951 | SourceLocation EndLoc) { | ||||||
8952 | if (!AStmt) | ||||||
8953 | return StmtError(); | ||||||
8954 | |||||||
8955 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8955, __PRETTY_FUNCTION__)); | ||||||
8956 | |||||||
8957 | setFunctionHasBranchProtectedScope(); | ||||||
8958 | |||||||
8959 | // OpenMP [2.7.3, single Construct, Restrictions] | ||||||
8960 | // The copyprivate clause must not be used with the nowait clause. | ||||||
8961 | const OMPClause *Nowait = nullptr; | ||||||
8962 | const OMPClause *Copyprivate = nullptr; | ||||||
8963 | for (const OMPClause *Clause : Clauses) { | ||||||
8964 | if (Clause->getClauseKind() == OMPC_nowait) | ||||||
8965 | Nowait = Clause; | ||||||
8966 | else if (Clause->getClauseKind() == OMPC_copyprivate) | ||||||
8967 | Copyprivate = Clause; | ||||||
8968 | if (Copyprivate && Nowait) { | ||||||
8969 | Diag(Copyprivate->getBeginLoc(), | ||||||
8970 | diag::err_omp_single_copyprivate_with_nowait); | ||||||
8971 | Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); | ||||||
8972 | return StmtError(); | ||||||
8973 | } | ||||||
8974 | } | ||||||
8975 | |||||||
8976 | return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); | ||||||
8977 | } | ||||||
8978 | |||||||
8979 | StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, | ||||||
8980 | SourceLocation StartLoc, | ||||||
8981 | SourceLocation EndLoc) { | ||||||
8982 | if (!AStmt) | ||||||
8983 | return StmtError(); | ||||||
8984 | |||||||
8985 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8985, __PRETTY_FUNCTION__)); | ||||||
8986 | |||||||
8987 | setFunctionHasBranchProtectedScope(); | ||||||
8988 | |||||||
8989 | return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); | ||||||
8990 | } | ||||||
8991 | |||||||
8992 | StmtResult Sema::ActOnOpenMPCriticalDirective( | ||||||
8993 | const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, | ||||||
8994 | Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { | ||||||
8995 | if (!AStmt) | ||||||
8996 | return StmtError(); | ||||||
8997 | |||||||
8998 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8998, __PRETTY_FUNCTION__)); | ||||||
8999 | |||||||
9000 | bool ErrorFound = false; | ||||||
9001 | llvm::APSInt Hint; | ||||||
9002 | SourceLocation HintLoc; | ||||||
9003 | bool DependentHint = false; | ||||||
9004 | for (const OMPClause *C : Clauses) { | ||||||
9005 | if (C->getClauseKind() == OMPC_hint) { | ||||||
9006 | if (!DirName.getName()) { | ||||||
9007 | Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); | ||||||
9008 | ErrorFound = true; | ||||||
9009 | } | ||||||
9010 | Expr *E = cast<OMPHintClause>(C)->getHint(); | ||||||
9011 | if (E->isTypeDependent() || E->isValueDependent() || | ||||||
9012 | E->isInstantiationDependent()) { | ||||||
9013 | DependentHint = true; | ||||||
9014 | } else { | ||||||
9015 | Hint = E->EvaluateKnownConstInt(Context); | ||||||
9016 | HintLoc = C->getBeginLoc(); | ||||||
9017 | } | ||||||
9018 | } | ||||||
9019 | } | ||||||
9020 | if (ErrorFound) | ||||||
9021 | return StmtError(); | ||||||
9022 | const auto Pair = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCriticalWithHint(DirName); | ||||||
9023 | if (Pair.first && DirName.getName() && !DependentHint) { | ||||||
9024 | if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { | ||||||
9025 | Diag(StartLoc, diag::err_omp_critical_with_hint); | ||||||
9026 | if (HintLoc.isValid()) | ||||||
9027 | Diag(HintLoc, diag::note_omp_critical_hint_here) | ||||||
9028 | << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); | ||||||
9029 | else | ||||||
9030 | Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; | ||||||
9031 | if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { | ||||||
9032 | Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) | ||||||
9033 | << 1 | ||||||
9034 | << C->getHint()->EvaluateKnownConstInt(Context).toString( | ||||||
9035 | /*Radix=*/10, /*Signed=*/false); | ||||||
9036 | } else { | ||||||
9037 | Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; | ||||||
9038 | } | ||||||
9039 | } | ||||||
9040 | } | ||||||
9041 | |||||||
9042 | setFunctionHasBranchProtectedScope(); | ||||||
9043 | |||||||
9044 | auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, | ||||||
9045 | Clauses, AStmt); | ||||||
9046 | if (!Pair.first && DirName.getName() && !DependentHint) | ||||||
9047 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addCriticalWithHint(Dir, Hint); | ||||||
9048 | return Dir; | ||||||
9049 | } | ||||||
9050 | |||||||
9051 | StmtResult Sema::ActOnOpenMPParallelForDirective( | ||||||
9052 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||
9053 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||
9054 | if (!AStmt) | ||||||
9055 | return StmtError(); | ||||||
9056 | |||||||
9057 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
9058 | // 1.2.2 OpenMP Language Terminology | ||||||
9059 | // Structured block - An executable statement with a single entry at the | ||||||
9060 | // top and a single exit at the bottom. | ||||||
9061 | // The point of exit cannot be a branch out of the structured block. | ||||||
9062 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
9063 | CS->getCapturedDecl()->setNothrow(); | ||||||
9064 | |||||||
9065 | OMPLoopDirective::HelperExprs B; | ||||||
9066 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||||
9067 | // define the nested loops number. | ||||||
9068 | unsigned NestedLoopCount = | ||||||
9069 | checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), | ||||||
9070 | getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||
9071 | VarsWithImplicitDSA, B); | ||||||
9072 | if (NestedLoopCount == 0) | ||||||
9073 | return StmtError(); | ||||||
9074 | |||||||
9075 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 9076, __PRETTY_FUNCTION__)) | ||||||
9076 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 9076, __PRETTY_FUNCTION__)); | ||||||
9077 | |||||||
9078 | if (!CurContext->isDependentContext()) { | ||||||
9079 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||
9080 | for (OMPClause *C : Clauses) { | ||||||
9081 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||
9082 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||
9083 | B.NumIterations, *this, CurScope, | ||||||
9084 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||
9085 | return StmtError(); | ||||||
9086 | } | ||||||
9087 | } | ||||||
9088 | |||||||
9089 | setFunctionHasBranchProtectedScope(); | ||||||
9090 | return OMPParallelForDirective::Create( | ||||||
9091 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, | ||||||
9092 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||
9093 | } | ||||||
9094 | |||||||
9095 | StmtResult Sema::ActOnOpenMPParallelForSimdDirective( | ||||||
9096 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||
9097 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||
9098 | if (!AStmt) | ||||||
9099 | return StmtError(); | ||||||
9100 | |||||||
9101 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
9102 | // 1.2.2 OpenMP Language Terminology | ||||||
9103 | // Structured block - An executable statement with a single entry at the | ||||||
9104 | // top and a single exit at the bottom. | ||||||
9105 | // The point of exit cannot be a branch out of the structured block. | ||||||
9106 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
9107 | CS->getCapturedDecl()->setNothrow(); | ||||||
9108 | |||||||
9109 | OMPLoopDirective::HelperExprs B; | ||||||
9110 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||||
9111 | // define the nested loops number. | ||||||
9112 | unsigned NestedLoopCount = | ||||||
9113 | checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), | ||||||
9114 | getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||
9115 | VarsWithImplicitDSA, B); | ||||||
9116 | if (NestedLoopCount == 0) | ||||||
9117 | return StmtError(); | ||||||
9118 | |||||||
9119 | if (!CurContext->isDependentContext()) { | ||||||
9120 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||
9121 | for (OMPClause *C : Clauses) { | ||||||
9122 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||
9123 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||
9124 | B.NumIterations, *this, CurScope, | ||||||
9125 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||
9126 | return StmtError(); | ||||||
9127 | } | ||||||
9128 | } | ||||||
9129 | |||||||
9130 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||
9131 | return StmtError(); | ||||||
9132 | |||||||
9133 | setFunctionHasBranchProtectedScope(); | ||||||
9134 | return OMPParallelForSimdDirective::Create( | ||||||
9135 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||||
9136 | } | ||||||
9137 | |||||||
9138 | StmtResult | ||||||
9139 | Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, | ||||||
9140 | Stmt *AStmt, SourceLocation StartLoc, | ||||||
9141 | SourceLocation EndLoc) { | ||||||
9142 | if (!AStmt) | ||||||
9143 | return StmtError(); | ||||||
9144 | |||||||
9145 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 9145, __PRETTY_FUNCTION__)); | ||||||
9146 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
9147 | // 1.2.2 OpenMP Language Terminology | ||||||
9148 | // Structured block - An executable statement with a single entry at the | ||||||
9149 | // top and a single exit at the bottom. | ||||||
9150 | // The point of exit cannot be a branch out of the structured block. | ||||||
9151 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
9152 | CS->getCapturedDecl()->setNothrow(); | ||||||
9153 | |||||||
9154 | setFunctionHasBranchProtectedScope(); | ||||||
9155 | |||||||
9156 | return OMPParallelMasterDirective::Create( | ||||||
9157 | Context, StartLoc, EndLoc, Clauses, AStmt, | ||||||
9158 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef()); | ||||||
9159 | } | ||||||
9160 | |||||||
9161 | StmtResult | ||||||
9162 | Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, | ||||||
9163 | Stmt *AStmt, SourceLocation StartLoc, | ||||||
9164 | SourceLocation EndLoc) { | ||||||
9165 | if (!AStmt) | ||||||
9166 | return StmtError(); | ||||||
9167 | |||||||
9168 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 9168, __PRETTY_FUNCTION__)); | ||||||
9169 | auto BaseStmt = AStmt; | ||||||
9170 | while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) | ||||||
9171 | BaseStmt = CS->getCapturedStmt(); | ||||||
9172 | if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { | ||||||
9173 | auto S = C->children(); | ||||||
9174 | if (S.begin() == S.end()) | ||||||
9175 | return StmtError(); | ||||||
9176 | // All associated statements must be '#pragma omp section' except for | ||||||
9177 | // the first one. | ||||||
9178 | for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { | ||||||
9179 | if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { | ||||||
9180 | if (SectionStmt) | ||||||
9181 | Diag(SectionStmt->getBeginLoc(), | ||||||
9182 | diag::err_omp_parallel_sections_substmt_not_section); | ||||||
9183 | return StmtError(); | ||||||
9184 | } | ||||||
9185 | cast<OMPSectionDirective>(SectionStmt) | ||||||
9186 | ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||
9187 | } | ||||||
9188 | } else { | ||||||
9189 | Diag(AStmt->getBeginLoc(), | ||||||
9190 | diag::err_omp_parallel_sections_not_compound_stmt); | ||||||
9191 | return StmtError(); | ||||||
9192 | } | ||||||
9193 | |||||||
9194 | setFunctionHasBranchProtectedScope(); | ||||||
9195 | |||||||
9196 | return OMPParallelSectionsDirective::Create( | ||||||
9197 | Context, StartLoc, EndLoc, Clauses, AStmt, | ||||||
9198 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||
9199 | } | ||||||
9200 | |||||||
9201 | /// detach and mergeable clauses are mutially exclusive, check for it. | ||||||
9202 | static bool checkDetachMergeableClauses(Sema &S, | ||||||
9203 | ArrayRef<OMPClause *> Clauses) { | ||||||
9204 | const OMPClause *PrevClause = nullptr; | ||||||
9205 | bool ErrorFound = false; | ||||||
9206 | for (const OMPClause *C : Clauses) { | ||||||
9207 | if (C->getClauseKind() == OMPC_detach || | ||||||
9208 | C->getClauseKind() == OMPC_mergeable) { | ||||||
9209 | if (!PrevClause) { | ||||||
9210 | PrevClause = C; | ||||||
9211 | } else if (PrevClause->getClauseKind() != C->getClauseKind()) { | ||||||
9212 | S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) | ||||||
9213 | << getOpenMPClauseName(C->getClauseKind()) | ||||||
9214 | << getOpenMPClauseName(PrevClause->getClauseKind()); | ||||||
9215 | S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) | ||||||
9216 | << getOpenMPClauseName(PrevClause->getClauseKind()); | ||||||
9217 | ErrorFound = true; | ||||||
9218 | } | ||||||
9219 | } | ||||||
9220 | } | ||||||
9221 | return ErrorFound; | ||||||
9222 | } | ||||||
9223 | |||||||
9224 | StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, | ||||||
9225 | Stmt *AStmt, SourceLocation StartLoc, | ||||||
9226 | SourceLocation EndLoc) { | ||||||
9227 | if (!AStmt) | ||||||
9228 | return StmtError(); | ||||||
9229 | |||||||
9230 | // OpenMP 5.0, 2.10.1 task Construct | ||||||
9231 | // If a detach clause appears on the directive, then a mergeable clause cannot | ||||||
9232 | // appear on the same directive. | ||||||
9233 | if (checkDetachMergeableClauses(*this, Clauses)) | ||||||
9234 | return StmtError(); | ||||||
9235 | |||||||
9236 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
9237 | // 1.2.2 OpenMP Language Terminology | ||||||
9238 | // Structured block - An executable statement with a single entry at the | ||||||
9239 | // top and a single exit at the bottom. | ||||||
9240 | // The point of exit cannot be a branch out of the structured block. | ||||||
9241 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
9242 | CS->getCapturedDecl()->setNothrow(); | ||||||
9243 | |||||||
9244 | setFunctionHasBranchProtectedScope(); | ||||||
9245 | |||||||
9246 | return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, | ||||||
9247 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||
9248 | } | ||||||
9249 | |||||||
9250 | StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, | ||||||
9251 | SourceLocation EndLoc) { | ||||||
9252 | return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); | ||||||
9253 | } | ||||||
9254 | |||||||
9255 | StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, | ||||||
9256 | SourceLocation EndLoc) { | ||||||
9257 | return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); | ||||||
9258 | } | ||||||
9259 | |||||||
9260 | StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, | ||||||
9261 | SourceLocation EndLoc) { | ||||||
9262 | return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); | ||||||
9263 | } | ||||||
9264 | |||||||
9265 | StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, | ||||||
9266 | Stmt *AStmt, | ||||||
9267 | SourceLocation StartLoc, | ||||||
9268 | SourceLocation EndLoc) { | ||||||
9269 | if (!AStmt) | ||||||
9270 | return StmtError(); | ||||||
9271 | |||||||
9272 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 9272, __PRETTY_FUNCTION__)); | ||||||
9273 | |||||||
9274 | setFunctionHasBranchProtectedScope(); | ||||||
9275 | |||||||
9276 | return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, | ||||||
9277 | AStmt, | ||||||
9278 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef()); | ||||||
9279 | } | ||||||
9280 | |||||||
9281 | StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, | ||||||
9282 | SourceLocation StartLoc, | ||||||
9283 | SourceLocation EndLoc) { | ||||||
9284 | OMPFlushClause *FC = nullptr; | ||||||
9285 | OMPClause *OrderClause = nullptr; | ||||||
9286 | for (OMPClause *C : Clauses) { | ||||||
9287 | if (C->getClauseKind() == OMPC_flush) | ||||||
9288 | FC = cast<OMPFlushClause>(C); | ||||||
9289 | else | ||||||
9290 | OrderClause = C; | ||||||
9291 | } | ||||||
9292 | OpenMPClauseKind MemOrderKind = OMPC_unknown; | ||||||
9293 | SourceLocation MemOrderLoc; | ||||||
9294 | for (const OMPClause *C : Clauses) { | ||||||
9295 | if (C->getClauseKind() == OMPC_acq_rel || | ||||||
9296 | C->getClauseKind() == OMPC_acquire || | ||||||
9297 | C->getClauseKind() == OMPC_release) { | ||||||
9298 | if (MemOrderKind != OMPC_unknown) { | ||||||
9299 | Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) | ||||||
9300 | << getOpenMPDirectiveName(OMPD_flush) << 1 | ||||||
9301 | << SourceRange(C->getBeginLoc(), C->getEndLoc()); | ||||||
9302 | Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) | ||||||
9303 | << getOpenMPClauseName(MemOrderKind); | ||||||
9304 | } else { | ||||||
9305 | MemOrderKind = C->getClauseKind(); | ||||||
9306 | MemOrderLoc = C->getBeginLoc(); | ||||||
9307 | } | ||||||
9308 | } | ||||||
9309 | } | ||||||
9310 | if (FC && OrderClause) { | ||||||
9311 | Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) | ||||||
9312 | << getOpenMPClauseName(OrderClause->getClauseKind()); | ||||||
9313 | Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) | ||||||
9314 | << getOpenMPClauseName(OrderClause->getClauseKind()); | ||||||
9315 | return StmtError(); | ||||||
9316 | } | ||||||
9317 | return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); | ||||||
9318 | } | ||||||
9319 | |||||||
9320 | StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, | ||||||
9321 | SourceLocation StartLoc, | ||||||
9322 | SourceLocation EndLoc) { | ||||||
9323 | if (Clauses.empty()) { | ||||||
9324 | Diag(StartLoc, diag::err_omp_depobj_expected); | ||||||
9325 | return StmtError(); | ||||||
9326 | } else if (Clauses[0]->getClauseKind() != OMPC_depobj) { | ||||||
9327 | Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected); | ||||||
9328 | return StmtError(); | ||||||
9329 | } | ||||||
9330 | // Only depobj expression and another single clause is allowed. | ||||||
9331 | if (Clauses.size() > 2) { | ||||||
9332 | Diag(Clauses[2]->getBeginLoc(), | ||||||
9333 | diag::err_omp_depobj_single_clause_expected); | ||||||
9334 | return StmtError(); | ||||||
9335 | } else if (Clauses.size() < 1) { | ||||||
9336 | Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected); | ||||||
9337 | return StmtError(); | ||||||
9338 | } | ||||||
9339 | return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses); | ||||||
9340 | } | ||||||
9341 | |||||||
9342 | StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, | ||||||
9343 | SourceLocation StartLoc, | ||||||
9344 | SourceLocation EndLoc) { | ||||||
9345 | // Check that exactly one clause is specified. | ||||||
9346 | if (Clauses.size() != 1) { | ||||||
9347 | Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(), | ||||||
9348 | diag::err_omp_scan_single_clause_expected); | ||||||
9349 | return StmtError(); | ||||||
9350 | } | ||||||
9351 | // Check that scan directive is used in the scopeof the OpenMP loop body. | ||||||
9352 | if (Scope *S = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurScope()) { | ||||||
9353 | Scope *ParentS = S->getParent(); | ||||||
9354 | if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() || | ||||||
9355 | !ParentS->getBreakParent()->isOpenMPLoopScope()) | ||||||
9356 | return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive) | ||||||
9357 | << getOpenMPDirectiveName(OMPD_scan) << 5); | ||||||
9358 | } | ||||||
9359 | // Check that only one instance of scan directives is used in the same outer | ||||||
9360 | // region. | ||||||
9361 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->doesParentHasScanDirective()) { | ||||||
9362 | Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan"; | ||||||
9363 | Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentScanDirectiveLoc(), | ||||||
9364 | diag::note_omp_previous_directive) | ||||||
9365 | << "scan"; | ||||||
9366 | return StmtError(); | ||||||
9367 | } | ||||||
9368 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentHasScanDirective(StartLoc); | ||||||
9369 | return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses); | ||||||
9370 | } | ||||||
9371 | |||||||
9372 | StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, | ||||||
9373 | Stmt *AStmt, | ||||||
9374 | SourceLocation StartLoc, | ||||||
9375 | SourceLocation EndLoc) { | ||||||
9376 | const OMPClause *DependFound = nullptr; | ||||||
9377 | const OMPClause *DependSourceClause = nullptr; | ||||||
9378 | const OMPClause *DependSinkClause = nullptr; | ||||||
9379 | bool ErrorFound = false; | ||||||
9380 | const OMPThreadsClause *TC = nullptr; | ||||||
9381 | const OMPSIMDClause *SC = nullptr; | ||||||
9382 | for (const OMPClause *C : Clauses) { | ||||||
9383 | if (auto *DC = dyn_cast<OMPDependClause>(C)) { | ||||||
9384 | DependFound = C; | ||||||
9385 | if (DC->getDependencyKind() == OMPC_DEPEND_source) { | ||||||
9386 | if (DependSourceClause) { | ||||||
9387 | Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) | ||||||
9388 | << getOpenMPDirectiveName(OMPD_ordered) | ||||||
9389 | << getOpenMPClauseName(OMPC_depend) << 2; | ||||||
9390 | ErrorFound = true; | ||||||
9391 | } else { | ||||||
9392 | DependSourceClause = C; | ||||||
9393 | } | ||||||
9394 | if (DependSinkClause) { | ||||||
9395 | Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) | ||||||
9396 | << 0; | ||||||
9397 | ErrorFound = true; | ||||||
9398 | } | ||||||
9399 | } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { | ||||||
9400 | if (DependSourceClause) { | ||||||
9401 | Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) | ||||||
9402 | << 1; | ||||||
9403 | ErrorFound = true; | ||||||
9404 | } | ||||||
9405 | DependSinkClause = C; | ||||||
9406 | } | ||||||
9407 | } else if (C->getClauseKind() == OMPC_threads) { | ||||||
9408 | TC = cast<OMPThreadsClause>(C); | ||||||
9409 | } else if (C->getClauseKind() == OMPC_simd) { | ||||||
9410 | SC = cast<OMPSIMDClause>(C); | ||||||
9411 | } | ||||||
9412 | } | ||||||
9413 | if (!ErrorFound && !SC && | ||||||
9414 | isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentDirective())) { | ||||||
9415 | // OpenMP [2.8.1,simd Construct, Restrictions] | ||||||
9416 | // An ordered construct with the simd clause is the only OpenMP construct | ||||||
9417 | // that can appear in the simd region. | ||||||
9418 | Diag(StartLoc, diag::err_omp_prohibited_region_simd) | ||||||
9419 | << (LangOpts.OpenMP >= 50 ? 1 : 0); | ||||||
9420 | ErrorFound = true; | ||||||
9421 | } else if (DependFound && (TC || SC)) { | ||||||
9422 | Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) | ||||||
9423 | << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); | ||||||
9424 | ErrorFound = true; | ||||||
9425 | } else if (DependFound && !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentOrderedRegionParam().first) { | ||||||
9426 | Diag(DependFound->getBeginLoc(), | ||||||
9427 | diag::err_omp_ordered_directive_without_param); | ||||||
9428 | ErrorFound = true; | ||||||
9429 | } else if (TC || Clauses.empty()) { | ||||||
9430 | if (const Expr *Param = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentOrderedRegionParam().first) { | ||||||
9431 | SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; | ||||||
9432 | Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) | ||||||
9433 | << (TC != nullptr); | ||||||
9434 | Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; | ||||||
9435 | ErrorFound = true; | ||||||
9436 | } | ||||||
9437 | } | ||||||
9438 | if ((!AStmt && !DependFound) || ErrorFound) | ||||||
9439 | return StmtError(); | ||||||
9440 | |||||||
9441 | // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions. | ||||||
9442 | // During execution of an iteration of a worksharing-loop or a loop nest | ||||||
9443 | // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread | ||||||
9444 | // must not execute more than one ordered region corresponding to an ordered | ||||||
9445 | // construct without a depend clause. | ||||||
9446 | if (!DependFound) { | ||||||
9447 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->doesParentHasOrderedDirective()) { | ||||||
9448 | Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered"; | ||||||
9449 | Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentOrderedDirectiveLoc(), | ||||||
9450 | diag::note_omp_previous_directive) | ||||||
9451 | << "ordered"; | ||||||
9452 | return StmtError(); | ||||||
9453 | } | ||||||
9454 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentHasOrderedDirective(StartLoc); | ||||||
9455 | } | ||||||
9456 | |||||||
9457 | if (AStmt) { | ||||||
9458 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 9458, __PRETTY_FUNCTION__)); | ||||||
9459 | |||||||
9460 | setFunctionHasBranchProtectedScope(); | ||||||
9461 | } | ||||||
9462 | |||||||
9463 | return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); | ||||||
9464 | } | ||||||
9465 | |||||||
9466 | namespace { | ||||||
9467 | /// Helper class for checking expression in 'omp atomic [update]' | ||||||
9468 | /// construct. | ||||||
9469 | class OpenMPAtomicUpdateChecker { | ||||||
9470 | /// Error results for atomic update expressions. | ||||||
9471 | enum ExprAnalysisErrorCode { | ||||||
9472 | /// A statement is not an expression statement. | ||||||
9473 | NotAnExpression, | ||||||
9474 | /// Expression is not builtin binary or unary operation. | ||||||
9475 | NotABinaryOrUnaryExpression, | ||||||
9476 | /// Unary operation is not post-/pre- increment/decrement operation. | ||||||
9477 | NotAnUnaryIncDecExpression, | ||||||
9478 | /// An expression is not of scalar type. | ||||||
9479 | NotAScalarType, | ||||||
9480 | /// A binary operation is not an assignment operation. | ||||||
9481 | NotAnAssignmentOp, | ||||||
9482 | /// RHS part of the binary operation is not a binary expression. | ||||||
9483 | NotABinaryExpression, | ||||||
9484 | /// RHS part is not additive/multiplicative/shift/biwise binary | ||||||
9485 | /// expression. | ||||||
9486 | NotABinaryOperator, | ||||||
9487 | /// RHS binary operation does not have reference to the updated LHS | ||||||
9488 | /// part. | ||||||
9489 | NotAnUpdateExpression, | ||||||
9490 | /// No errors is found. | ||||||
9491 | NoError | ||||||
9492 | }; | ||||||
9493 | /// Reference to Sema. | ||||||
9494 | Sema &SemaRef; | ||||||
9495 | /// A location for note diagnostics (when error is found). | ||||||
9496 | SourceLocation NoteLoc; | ||||||
9497 | /// 'x' lvalue part of the source atomic expression. | ||||||
9498 | Expr *X; | ||||||
9499 | /// 'expr' rvalue part of the source atomic expression. | ||||||
9500 | Expr *E; | ||||||
9501 | /// Helper expression of the form | ||||||
9502 | /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or | ||||||
9503 | /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. | ||||||
9504 | Expr *UpdateExpr; | ||||||
9505 | /// Is 'x' a LHS in a RHS part of full update expression. It is | ||||||
9506 | /// important for non-associative operations. | ||||||
9507 | bool IsXLHSInRHSPart; | ||||||
9508 | BinaryOperatorKind Op; | ||||||
9509 | SourceLocation OpLoc; | ||||||
9510 | /// true if the source expression is a postfix unary operation, false | ||||||
9511 | /// if it is a prefix unary operation. | ||||||
9512 | bool IsPostfixUpdate; | ||||||
9513 | |||||||
9514 | public: | ||||||
9515 | OpenMPAtomicUpdateChecker(Sema &SemaRef) | ||||||
9516 | : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), | ||||||
9517 | IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} | ||||||
9518 | /// Check specified statement that it is suitable for 'atomic update' | ||||||
9519 | /// constructs and extract 'x', 'expr' and Operation from the original | ||||||
9520 | /// expression. If DiagId and NoteId == 0, then only check is performed | ||||||
9521 | /// without error notification. | ||||||
9522 | /// \param DiagId Diagnostic which should be emitted if error is found. | ||||||
9523 | /// \param NoteId Diagnostic note for the main error message. | ||||||
9524 | /// \return true if statement is not an update expression, false otherwise. | ||||||
9525 | bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); | ||||||
9526 | /// Return the 'x' lvalue part of the source atomic expression. | ||||||
9527 | Expr *getX() const { return X; } | ||||||
9528 | /// Return the 'expr' rvalue part of the source atomic expression. | ||||||
9529 | Expr *getExpr() const { return E; } | ||||||
9530 | /// Return the update expression used in calculation of the updated | ||||||
9531 | /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or | ||||||
9532 | /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. | ||||||
9533 | Expr *getUpdateExpr() const { return UpdateExpr; } | ||||||
9534 | /// Return true if 'x' is LHS in RHS part of full update expression, | ||||||
9535 | /// false otherwise. | ||||||
9536 | bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } | ||||||
9537 | |||||||
9538 | /// true if the source expression is a postfix unary operation, false | ||||||
9539 | /// if it is a prefix unary operation. | ||||||
9540 | bool isPostfixUpdate() const { return IsPostfixUpdate; } | ||||||
9541 | |||||||
9542 | private: | ||||||
9543 | bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, | ||||||
9544 | unsigned NoteId = 0); | ||||||
9545 | }; | ||||||
9546 | } // namespace | ||||||
9547 | |||||||
9548 | bool OpenMPAtomicUpdateChecker::checkBinaryOperation( | ||||||
9549 | BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { | ||||||
9550 | ExprAnalysisErrorCode ErrorFound = NoError; | ||||||
9551 | SourceLocation ErrorLoc, NoteLoc; | ||||||
9552 | SourceRange ErrorRange, NoteRange; | ||||||
9553 | // Allowed constructs are: | ||||||
9554 | // x = x binop expr; | ||||||
9555 | // x = expr binop x; | ||||||
9556 | if (AtomicBinOp->getOpcode() == BO_Assign) { | ||||||
9557 | X = AtomicBinOp->getLHS(); | ||||||
9558 | if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( | ||||||
9559 | AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { | ||||||
9560 | if (AtomicInnerBinOp->isMultiplicativeOp() || | ||||||
9561 | AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || | ||||||
9562 | AtomicInnerBinOp->isBitwiseOp()) { | ||||||
9563 | Op = AtomicInnerBinOp->getOpcode(); | ||||||
9564 | OpLoc = AtomicInnerBinOp->getOperatorLoc(); | ||||||
9565 | Expr *LHS = AtomicInnerBinOp->getLHS(); | ||||||
9566 | Expr *RHS = AtomicInnerBinOp->getRHS(); | ||||||
9567 | llvm::FoldingSetNodeID XId, LHSId, RHSId; | ||||||
9568 | X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), | ||||||
9569 | /*Canonical=*/true); | ||||||
9570 | LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), | ||||||
9571 | /*Canonical=*/true); | ||||||
9572 | RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), | ||||||
9573 | /*Canonical=*/true); | ||||||
9574 | if (XId == LHSId) { | ||||||
9575 | E = RHS; | ||||||
9576 | IsXLHSInRHSPart = true; | ||||||
9577 | } else if (XId == RHSId) { | ||||||
9578 | E = LHS; | ||||||
9579 | IsXLHSInRHSPart = false; | ||||||
9580 | } else { | ||||||
9581 | ErrorLoc = AtomicInnerBinOp->getExprLoc(); | ||||||
9582 | ErrorRange = AtomicInnerBinOp->getSourceRange(); | ||||||
9583 | NoteLoc = X->getExprLoc(); | ||||||
9584 | NoteRange = X->getSourceRange(); | ||||||
9585 | ErrorFound = NotAnUpdateExpression; | ||||||
9586 | } | ||||||
9587 | } else { | ||||||
9588 | ErrorLoc = AtomicInnerBinOp->getExprLoc(); | ||||||
9589 | ErrorRange = AtomicInnerBinOp->getSourceRange(); | ||||||
9590 | NoteLoc = AtomicInnerBinOp->getOperatorLoc(); | ||||||
9591 | NoteRange = SourceRange(NoteLoc, NoteLoc); | ||||||
9592 | ErrorFound = NotABinaryOperator; | ||||||
9593 | } | ||||||
9594 | } else { | ||||||
9595 | NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); | ||||||
9596 | NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); | ||||||
9597 | ErrorFound = NotABinaryExpression; | ||||||
9598 | } | ||||||
9599 | } else { | ||||||
9600 | ErrorLoc = AtomicBinOp->getExprLoc(); | ||||||
9601 | ErrorRange = AtomicBinOp->getSourceRange(); | ||||||
9602 | NoteLoc = AtomicBinOp->getOperatorLoc(); | ||||||
9603 | NoteRange = SourceRange(NoteLoc, NoteLoc); | ||||||
9604 | ErrorFound = NotAnAssignmentOp; | ||||||
9605 | } | ||||||
9606 | if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { | ||||||
9607 | SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; | ||||||
9608 | SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; | ||||||
9609 | return true; | ||||||
9610 | } | ||||||
9611 | if (SemaRef.CurContext->isDependentContext()) | ||||||
9612 | E = X = UpdateExpr = nullptr; | ||||||
9613 | return ErrorFound != NoError; | ||||||
9614 | } | ||||||
9615 | |||||||
9616 | bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, | ||||||
9617 | unsigned NoteId) { | ||||||
9618 | ExprAnalysisErrorCode ErrorFound = NoError; | ||||||
9619 | SourceLocation ErrorLoc, NoteLoc; | ||||||
9620 | SourceRange ErrorRange, NoteRange; | ||||||
9621 | // Allowed constructs are: | ||||||
9622 | // x++; | ||||||
9623 | // x--; | ||||||
9624 | // ++x; | ||||||
9625 | // --x; | ||||||
9626 | // x binop= expr; | ||||||
9627 | // x = x binop expr; | ||||||
9628 | // x = expr binop x; | ||||||
9629 | if (auto *AtomicBody = dyn_cast<Expr>(S)) { | ||||||
9630 | AtomicBody = AtomicBody->IgnoreParenImpCasts(); | ||||||
9631 | if (AtomicBody->getType()->isScalarType() || | ||||||
9632 | AtomicBody->isInstantiationDependent()) { | ||||||
9633 | if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( | ||||||
9634 | AtomicBody->IgnoreParenImpCasts())) { | ||||||
9635 | // Check for Compound Assignment Operation | ||||||
9636 | Op = BinaryOperator::getOpForCompoundAssignment( | ||||||
9637 | AtomicCompAssignOp->getOpcode()); | ||||||
9638 | OpLoc = AtomicCompAssignOp->getOperatorLoc(); | ||||||
9639 | E = AtomicCompAssignOp->getRHS(); | ||||||
9640 | X = AtomicCompAssignOp->getLHS()->IgnoreParens(); | ||||||
9641 | IsXLHSInRHSPart = true; | ||||||
9642 | } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( | ||||||
9643 | AtomicBody->IgnoreParenImpCasts())) { | ||||||
9644 | // Check for Binary Operation | ||||||
9645 | if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) | ||||||
9646 | return true; | ||||||
9647 | } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( | ||||||
9648 | AtomicBody->IgnoreParenImpCasts())) { | ||||||
9649 | // Check for Unary Operation | ||||||
9650 | if (AtomicUnaryOp->isIncrementDecrementOp()) { | ||||||
9651 | IsPostfixUpdate = AtomicUnaryOp->isPostfix(); | ||||||
9652 | Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; | ||||||
9653 | OpLoc = AtomicUnaryOp->getOperatorLoc(); | ||||||
9654 | X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); | ||||||
9655 | E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); | ||||||
9656 | IsXLHSInRHSPart = true; | ||||||
9657 | } else { | ||||||
9658 | ErrorFound = NotAnUnaryIncDecExpression; | ||||||
9659 | ErrorLoc = AtomicUnaryOp->getExprLoc(); | ||||||
9660 | ErrorRange = AtomicUnaryOp->getSourceRange(); | ||||||
9661 | NoteLoc = AtomicUnaryOp->getOperatorLoc(); | ||||||
9662 | NoteRange = SourceRange(NoteLoc, NoteLoc); | ||||||
9663 | } | ||||||
9664 | } else if (!AtomicBody->isInstantiationDependent()) { | ||||||
9665 | ErrorFound = NotABinaryOrUnaryExpression; | ||||||
9666 | NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); | ||||||
9667 | NoteRange = ErrorRange = AtomicBody->getSourceRange(); | ||||||
9668 | } | ||||||
9669 | } else { | ||||||
9670 | ErrorFound = NotAScalarType; | ||||||
9671 | NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); | ||||||
9672 | NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); | ||||||
9673 | } | ||||||
9674 | } else { | ||||||
9675 | ErrorFound = NotAnExpression; | ||||||
9676 | NoteLoc = ErrorLoc = S->getBeginLoc(); | ||||||
9677 | NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); | ||||||
9678 | } | ||||||
9679 | if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { | ||||||
9680 | SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; | ||||||
9681 | SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; | ||||||
9682 | return true; | ||||||
9683 | } | ||||||
9684 | if (SemaRef.CurContext->isDependentContext()) | ||||||
9685 | E = X = UpdateExpr = nullptr; | ||||||
9686 | if (ErrorFound == NoError && E && X) { | ||||||
9687 | // Build an update expression of form 'OpaqueValueExpr(x) binop | ||||||
9688 | // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop | ||||||
9689 | // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. | ||||||
9690 | auto *OVEX = new (SemaRef.getASTContext()) | ||||||
9691 | OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); | ||||||
9692 | auto *OVEExpr = new (SemaRef.getASTContext()) | ||||||
9693 | OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); | ||||||
9694 | ExprResult Update = | ||||||
9695 | SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, | ||||||
9696 | IsXLHSInRHSPart ? OVEExpr : OVEX); | ||||||
9697 | if (Update.isInvalid()) | ||||||
9698 | return true; | ||||||
9699 | Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), | ||||||
9700 | Sema::AA_Casting); | ||||||
9701 | if (Update.isInvalid()) | ||||||
9702 | return true; | ||||||
9703 | UpdateExpr = Update.get(); | ||||||
9704 | } | ||||||
9705 | return ErrorFound != NoError; | ||||||
9706 | } | ||||||
9707 | |||||||
9708 | StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, | ||||||
9709 | Stmt *AStmt, | ||||||
9710 | SourceLocation StartLoc, | ||||||
9711 | SourceLocation EndLoc) { | ||||||
9712 | // Register location of the first atomic directive. | ||||||
9713 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addAtomicDirectiveLoc(StartLoc); | ||||||
9714 | if (!AStmt) | ||||||
9715 | return StmtError(); | ||||||
9716 | |||||||
9717 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
9718 | // 1.2.2 OpenMP Language Terminology | ||||||
9719 | // Structured block - An executable statement with a single entry at the | ||||||
9720 | // top and a single exit at the bottom. | ||||||
9721 | // The point of exit cannot be a branch out of the structured block. | ||||||
9722 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
9723 | OpenMPClauseKind AtomicKind = OMPC_unknown; | ||||||
9724 | SourceLocation AtomicKindLoc; | ||||||
9725 | OpenMPClauseKind MemOrderKind = OMPC_unknown; | ||||||
9726 | SourceLocation MemOrderLoc; | ||||||
9727 | for (const OMPClause *C : Clauses) { | ||||||
9728 | if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || | ||||||
9729 | C->getClauseKind() == OMPC_update || | ||||||
9730 | C->getClauseKind() == OMPC_capture) { | ||||||
9731 | if (AtomicKind != OMPC_unknown) { | ||||||
9732 | Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) | ||||||
9733 | << SourceRange(C->getBeginLoc(), C->getEndLoc()); | ||||||
9734 | Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) | ||||||
9735 | << getOpenMPClauseName(AtomicKind); | ||||||
9736 | } else { | ||||||
9737 | AtomicKind = C->getClauseKind(); | ||||||
9738 | AtomicKindLoc = C->getBeginLoc(); | ||||||
9739 | } | ||||||
9740 | } | ||||||
9741 | if (C->getClauseKind() == OMPC_seq_cst || | ||||||
9742 | C->getClauseKind() == OMPC_acq_rel || | ||||||
9743 | C->getClauseKind() == OMPC_acquire || | ||||||
9744 | C->getClauseKind() == OMPC_release || | ||||||
9745 | C->getClauseKind() == OMPC_relaxed) { | ||||||
9746 | if (MemOrderKind != OMPC_unknown) { | ||||||
9747 | Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) | ||||||
9748 | << getOpenMPDirectiveName(OMPD_atomic) << 0 | ||||||
9749 | << SourceRange(C->getBeginLoc(), C->getEndLoc()); | ||||||
9750 | Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) | ||||||
9751 | << getOpenMPClauseName(MemOrderKind); | ||||||
9752 | } else { | ||||||
9753 | MemOrderKind = C->getClauseKind(); | ||||||
9754 | MemOrderLoc = C->getBeginLoc(); | ||||||
9755 | } | ||||||
9756 | } | ||||||
9757 | } | ||||||
9758 | // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions | ||||||
9759 | // If atomic-clause is read then memory-order-clause must not be acq_rel or | ||||||
9760 | // release. | ||||||
9761 | // If atomic-clause is write then memory-order-clause must not be acq_rel or | ||||||
9762 | // acquire. | ||||||
9763 | // If atomic-clause is update or not present then memory-order-clause must not | ||||||
9764 | // be acq_rel or acquire. | ||||||
9765 | if ((AtomicKind == OMPC_read && | ||||||
9766 | (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || | ||||||
9767 | ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || | ||||||
9768 | AtomicKind == OMPC_unknown) && | ||||||
9769 | (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { | ||||||
9770 | SourceLocation Loc = AtomicKindLoc; | ||||||
9771 | if (AtomicKind == OMPC_unknown) | ||||||
9772 | Loc = StartLoc; | ||||||
9773 | Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) | ||||||
9774 | << getOpenMPClauseName(AtomicKind) | ||||||
9775 | << (AtomicKind == OMPC_unknown ? 1 : 0) | ||||||
9776 | << getOpenMPClauseName(MemOrderKind); | ||||||
9777 | Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) | ||||||
9778 | << getOpenMPClauseName(MemOrderKind); | ||||||
9779 | } | ||||||
9780 | |||||||
9781 | Stmt *Body = CS->getCapturedStmt(); | ||||||
9782 | if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) | ||||||
9783 | Body = EWC->getSubExpr(); | ||||||
9784 | |||||||
9785 | Expr *X = nullptr; | ||||||
9786 | Expr *V = nullptr; | ||||||
9787 | Expr *E = nullptr; | ||||||
9788 | Expr *UE = nullptr; | ||||||
9789 | bool IsXLHSInRHSPart = false; | ||||||
9790 | bool IsPostfixUpdate = false; | ||||||
9791 | // OpenMP [2.12.6, atomic Construct] | ||||||
9792 | // In the next expressions: | ||||||
9793 | // * x and v (as applicable) are both l-value expressions with scalar type. | ||||||
9794 | // * During the execution of an atomic region, multiple syntactic | ||||||
9795 | // occurrences of x must designate the same storage location. | ||||||
9796 | // * Neither of v and expr (as applicable) may access the storage location | ||||||
9797 | // designated by x. | ||||||
9798 | // * Neither of x and expr (as applicable) may access the storage location | ||||||
9799 | // designated by v. | ||||||
9800 | // * expr is an expression with scalar type. | ||||||
9801 | // * binop is one of +, *, -, /, &, ^, |, <<, or >>. | ||||||
9802 | // * binop, binop=, ++, and -- are not overloaded operators. | ||||||
9803 | // * The expression x binop expr must be numerically equivalent to x binop | ||||||
9804 | // (expr). This requirement is satisfied if the operators in expr have | ||||||
9805 | // precedence greater than binop, or by using parentheses around expr or | ||||||
9806 | // subexpressions of expr. | ||||||
9807 | // * The expression expr binop x must be numerically equivalent to (expr) | ||||||
9808 | // binop x. This requirement is satisfied if the operators in expr have | ||||||
9809 | // precedence equal to or greater than binop, or by using parentheses around | ||||||
9810 | // expr or subexpressions of expr. | ||||||
9811 | // * For forms that allow multiple occurrences of x, the number of times | ||||||
9812 | // that x is evaluated is unspecified. | ||||||
9813 | if (AtomicKind == OMPC_read) { | ||||||
9814 | enum { | ||||||
9815 | NotAnExpression, | ||||||
9816 | NotAnAssignmentOp, | ||||||
9817 | NotAScalarType, | ||||||
9818 | NotAnLValue, | ||||||
9819 | NoError | ||||||
9820 | } ErrorFound = NoError; | ||||||
9821 | SourceLocation ErrorLoc, NoteLoc; | ||||||
9822 | SourceRange ErrorRange, NoteRange; | ||||||
9823 | // If clause is read: | ||||||
9824 | // v = x; | ||||||
9825 | if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { | ||||||
9826 | const auto *AtomicBinOp = | ||||||
9827 | dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); | ||||||
9828 | if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { | ||||||
9829 | X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); | ||||||
9830 | V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); | ||||||
9831 | if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && | ||||||
9832 | (V->isInstantiationDependent() || V->getType()->isScalarType())) { | ||||||
9833 | if (!X->isLValue() || !V->isLValue()) { | ||||||
9834 | const Expr *NotLValueExpr = X->isLValue() ? V : X; | ||||||
9835 | ErrorFound = NotAnLValue; | ||||||
9836 | ErrorLoc = AtomicBinOp->getExprLoc(); | ||||||
9837 | ErrorRange = AtomicBinOp->getSourceRange(); | ||||||
9838 | NoteLoc = NotLValueExpr->getExprLoc(); | ||||||
9839 | NoteRange = NotLValueExpr->getSourceRange(); | ||||||
9840 | } | ||||||
9841 | } else if (!X->isInstantiationDependent() || | ||||||
9842 | !V->isInstantiationDependent()) { | ||||||
9843 | const Expr *NotScalarExpr = | ||||||
9844 | (X->isInstantiationDependent() || X->getType()->isScalarType()) | ||||||
9845 | ? V | ||||||
9846 | : X; | ||||||
9847 | ErrorFound = NotAScalarType; | ||||||
9848 | ErrorLoc = AtomicBinOp->getExprLoc(); | ||||||
9849 | ErrorRange = AtomicBinOp->getSourceRange(); | ||||||
9850 | NoteLoc = NotScalarExpr->getExprLoc(); | ||||||
9851 | NoteRange = NotScalarExpr->getSourceRange(); | ||||||
9852 | } | ||||||
9853 | } else if (!AtomicBody->isInstantiationDependent()) { | ||||||
9854 | ErrorFound = NotAnAssignmentOp; | ||||||
9855 | ErrorLoc = AtomicBody->getExprLoc(); | ||||||
9856 | ErrorRange = AtomicBody->getSourceRange(); | ||||||
9857 | NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() | ||||||
9858 | : AtomicBody->getExprLoc(); | ||||||
9859 | NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() | ||||||
9860 | : AtomicBody->getSourceRange(); | ||||||
9861 | } | ||||||
9862 | } else { | ||||||
9863 | ErrorFound = NotAnExpression; | ||||||
9864 | NoteLoc = ErrorLoc = Body->getBeginLoc(); | ||||||
9865 | NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); | ||||||
9866 | } | ||||||
9867 | if (ErrorFound != NoError) { | ||||||
9868 | Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) | ||||||
9869 | << ErrorRange; | ||||||
9870 | Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound | ||||||
9871 | << NoteRange; | ||||||
9872 | return StmtError(); | ||||||
9873 | } | ||||||
9874 | if (CurContext->isDependentContext()) | ||||||
9875 | V = X = nullptr; | ||||||
9876 | } else if (AtomicKind == OMPC_write) { | ||||||
9877 | enum { | ||||||
9878 | NotAnExpression, | ||||||
9879 | NotAnAssignmentOp, | ||||||
9880 | NotAScalarType, | ||||||
9881 | NotAnLValue, | ||||||
9882 | NoError | ||||||
9883 | } ErrorFound = NoError; | ||||||
9884 | SourceLocation ErrorLoc, NoteLoc; | ||||||
9885 | SourceRange ErrorRange, NoteRange; | ||||||
9886 | // If clause is write: | ||||||
9887 | // x = expr; | ||||||
9888 | if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { | ||||||
9889 | const auto *AtomicBinOp = | ||||||
9890 | dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); | ||||||
9891 | if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { | ||||||
9892 | X = AtomicBinOp->getLHS(); | ||||||
9893 | E = AtomicBinOp->getRHS(); | ||||||
9894 | if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && | ||||||
9895 | (E->isInstantiationDependent() || E->getType()->isScalarType())) { | ||||||
9896 | if (!X->isLValue()) { | ||||||
9897 | ErrorFound = NotAnLValue; | ||||||
9898 | ErrorLoc = AtomicBinOp->getExprLoc(); | ||||||
9899 | ErrorRange = AtomicBinOp->getSourceRange(); | ||||||
9900 | NoteLoc = X->getExprLoc(); | ||||||
9901 | NoteRange = X->getSourceRange(); | ||||||
9902 | } | ||||||
9903 | } else if (!X->isInstantiationDependent() || | ||||||
9904 | !E->isInstantiationDependent()) { | ||||||
9905 | const Expr *NotScalarExpr = | ||||||
9906 | (X->isInstantiationDependent() || X->getType()->isScalarType()) | ||||||
9907 | ? E | ||||||
9908 | : X; | ||||||
9909 | ErrorFound = NotAScalarType; | ||||||
9910 | ErrorLoc = AtomicBinOp->getExprLoc(); | ||||||
9911 | ErrorRange = AtomicBinOp->getSourceRange(); | ||||||
9912 | NoteLoc = NotScalarExpr->getExprLoc(); | ||||||
9913 | NoteRange = NotScalarExpr->getSourceRange(); | ||||||
9914 | } | ||||||
9915 | } else if (!AtomicBody->isInstantiationDependent()) { | ||||||
9916 | ErrorFound = NotAnAssignmentOp; | ||||||
9917 | ErrorLoc = AtomicBody->getExprLoc(); | ||||||
9918 | ErrorRange = AtomicBody->getSourceRange(); | ||||||
9919 | NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() | ||||||
9920 | : AtomicBody->getExprLoc(); | ||||||
9921 | NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() | ||||||
9922 | : AtomicBody->getSourceRange(); | ||||||
9923 | } | ||||||
9924 | } else { | ||||||
9925 | ErrorFound = NotAnExpression; | ||||||
9926 | NoteLoc = ErrorLoc = Body->getBeginLoc(); | ||||||
9927 | NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); | ||||||
9928 | } | ||||||
9929 | if (ErrorFound != NoError) { | ||||||
9930 | Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) | ||||||
9931 | << ErrorRange; | ||||||
9932 | Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound | ||||||
9933 | << NoteRange; | ||||||
9934 | return StmtError(); | ||||||
9935 | } | ||||||
9936 | if (CurContext->isDependentContext()) | ||||||
9937 | E = X = nullptr; | ||||||
9938 | } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { | ||||||
9939 | // If clause is update: | ||||||
9940 | // x++; | ||||||
9941 | // x--; | ||||||
9942 | // ++x; | ||||||
9943 | // --x; | ||||||
9944 | // x binop= expr; | ||||||
9945 | // x = x binop expr; | ||||||
9946 | // x = expr binop x; | ||||||
9947 | OpenMPAtomicUpdateChecker Checker(*this); | ||||||
9948 | if (Checker.checkStatement( | ||||||
9949 | Body, (AtomicKind == OMPC_update) | ||||||
9950 | ? diag::err_omp_atomic_update_not_expression_statement | ||||||
9951 | : diag::err_omp_atomic_not_expression_statement, | ||||||
9952 | diag::note_omp_atomic_update)) | ||||||
9953 | return StmtError(); | ||||||
9954 | if (!CurContext->isDependentContext()) { | ||||||
9955 | E = Checker.getExpr(); | ||||||
9956 | X = Checker.getX(); | ||||||
9957 | UE = Checker.getUpdateExpr(); | ||||||
9958 | IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); | ||||||
9959 | } | ||||||
9960 | } else if (AtomicKind == OMPC_capture) { | ||||||
9961 | enum { | ||||||
9962 | NotAnAssignmentOp, | ||||||
9963 | NotACompoundStatement, | ||||||
9964 | NotTwoSubstatements, | ||||||
9965 | NotASpecificExpression, | ||||||
9966 | NoError | ||||||
9967 | } ErrorFound = NoError; | ||||||
9968 | SourceLocation ErrorLoc, NoteLoc; | ||||||
9969 | SourceRange ErrorRange, NoteRange; | ||||||
9970 | if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { | ||||||
9971 | // If clause is a capture: | ||||||
9972 | // v = x++; | ||||||
9973 | // v = x--; | ||||||
9974 | // v = ++x; | ||||||
9975 | // v = --x; | ||||||
9976 | // v = x binop= expr; | ||||||
9977 | // v = x = x binop expr; | ||||||
9978 | // v = x = expr binop x; | ||||||
9979 | const auto *AtomicBinOp = | ||||||
9980 | dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); | ||||||
9981 | if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { | ||||||
9982 | V = AtomicBinOp->getLHS(); | ||||||
9983 | Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); | ||||||
9984 | OpenMPAtomicUpdateChecker Checker(*this); | ||||||
9985 | if (Checker.checkStatement( | ||||||
9986 | Body, diag::err_omp_atomic_capture_not_expression_statement, | ||||||
9987 | diag::note_omp_atomic_update)) | ||||||
9988 | return StmtError(); | ||||||
9989 | E = Checker.getExpr(); | ||||||
9990 | X = Checker.getX(); | ||||||
9991 | UE = Checker.getUpdateExpr(); | ||||||
9992 | IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); | ||||||
9993 | IsPostfixUpdate = Checker.isPostfixUpdate(); | ||||||
9994 | } else if (!AtomicBody->isInstantiationDependent()) { | ||||||
9995 | ErrorLoc = AtomicBody->getExprLoc(); | ||||||
9996 | ErrorRange = AtomicBody->getSourceRange(); | ||||||
9997 | NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() | ||||||
9998 | : AtomicBody->getExprLoc(); | ||||||
9999 | NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() | ||||||
10000 | : AtomicBody->getSourceRange(); | ||||||
10001 | ErrorFound = NotAnAssignmentOp; | ||||||
10002 | } | ||||||
10003 | if (ErrorFound != NoError) { | ||||||
10004 | Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) | ||||||
10005 | << ErrorRange; | ||||||
10006 | Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; | ||||||
10007 | return StmtError(); | ||||||
10008 | } | ||||||
10009 | if (CurContext->isDependentContext()) | ||||||
10010 | UE = V = E = X = nullptr; | ||||||
10011 | } else { | ||||||
10012 | // If clause is a capture: | ||||||
10013 | // { v = x; x = expr; } | ||||||
10014 | // { v = x; x++; } | ||||||
10015 | // { v = x; x--; } | ||||||
10016 | // { v = x; ++x; } | ||||||
10017 | // { v = x; --x; } | ||||||
10018 | // { v = x; x binop= expr; } | ||||||
10019 | // { v = x; x = x binop expr; } | ||||||
10020 | // { v = x; x = expr binop x; } | ||||||
10021 | // { x++; v = x; } | ||||||
10022 | // { x--; v = x; } | ||||||
10023 | // { ++x; v = x; } | ||||||
10024 | // { --x; v = x; } | ||||||
10025 | // { x binop= expr; v = x; } | ||||||
10026 | // { x = x binop expr; v = x; } | ||||||
10027 | // { x = expr binop x; v = x; } | ||||||
10028 | if (auto *CS = dyn_cast<CompoundStmt>(Body)) { | ||||||
10029 | // Check that this is { expr1; expr2; } | ||||||
10030 | if (CS->size() == 2) { | ||||||
10031 | Stmt *First = CS->body_front(); | ||||||
10032 | Stmt *Second = CS->body_back(); | ||||||
10033 | if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) | ||||||
10034 | First = EWC->getSubExpr()->IgnoreParenImpCasts(); | ||||||
10035 | if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) | ||||||
10036 | Second = EWC->getSubExpr()->IgnoreParenImpCasts(); | ||||||
10037 | // Need to find what subexpression is 'v' and what is 'x'. | ||||||
10038 | OpenMPAtomicUpdateChecker Checker(*this); | ||||||
10039 | bool IsUpdateExprFound = !Checker.checkStatement(Second); | ||||||
10040 | BinaryOperator *BinOp = nullptr; | ||||||
10041 | if (IsUpdateExprFound) { | ||||||
10042 | BinOp = dyn_cast<BinaryOperator>(First); | ||||||
10043 | IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; | ||||||
10044 | } | ||||||
10045 | if (IsUpdateExprFound && !CurContext->isDependentContext()) { | ||||||
10046 | // { v = x; x++; } | ||||||
10047 | // { v = x; x--; } | ||||||
10048 | // { v = x; ++x; } | ||||||
10049 | // { v = x; --x; } | ||||||
10050 | // { v = x; x binop= expr; } | ||||||
10051 | // { v = x; x = x binop expr; } | ||||||
10052 | // { v = x; x = expr binop x; } | ||||||
10053 | // Check that the first expression has form v = x. | ||||||
10054 | Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); | ||||||
10055 | llvm::FoldingSetNodeID XId, PossibleXId; | ||||||
10056 | Checker.getX()->Profile(XId, Context, /*Canonical=*/true); | ||||||
10057 | PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); | ||||||
10058 | IsUpdateExprFound = XId == PossibleXId; | ||||||
10059 | if (IsUpdateExprFound) { | ||||||
10060 | V = BinOp->getLHS(); | ||||||
10061 | X = Checker.getX(); | ||||||
10062 | E = Checker.getExpr(); | ||||||
10063 | UE = Checker.getUpdateExpr(); | ||||||
10064 | IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); | ||||||
10065 | IsPostfixUpdate = true; | ||||||
10066 | } | ||||||
10067 | } | ||||||
10068 | if (!IsUpdateExprFound) { | ||||||
10069 | IsUpdateExprFound = !Checker.checkStatement(First); | ||||||
10070 | BinOp = nullptr; | ||||||
10071 | if (IsUpdateExprFound) { | ||||||
10072 | BinOp = dyn_cast<BinaryOperator>(Second); | ||||||
10073 | IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; | ||||||
10074 | } | ||||||
10075 | if (IsUpdateExprFound && !CurContext->isDependentContext()) { | ||||||
10076 | // { x++; v = x; } | ||||||
10077 | // { x--; v = x; } | ||||||
10078 | // { ++x; v = x; } | ||||||
10079 | // { --x; v = x; } | ||||||
10080 | // { x binop= expr; v = x; } | ||||||
10081 | // { x = x binop expr; v = x; } | ||||||
10082 | // { x = expr binop x; v = x; } | ||||||
10083 | // Check that the second expression has form v = x. | ||||||
10084 | Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); | ||||||
10085 | llvm::FoldingSetNodeID XId, PossibleXId; | ||||||
10086 | Checker.getX()->Profile(XId, Context, /*Canonical=*/true); | ||||||
10087 | PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); | ||||||
10088 | IsUpdateExprFound = XId == PossibleXId; | ||||||
10089 | if (IsUpdateExprFound) { | ||||||
10090 | V = BinOp->getLHS(); | ||||||
10091 | X = Checker.getX(); | ||||||
10092 | E = Checker.getExpr(); | ||||||
10093 | UE = Checker.getUpdateExpr(); | ||||||
10094 | IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); | ||||||
10095 | IsPostfixUpdate = false; | ||||||
10096 | } | ||||||
10097 | } | ||||||
10098 | } | ||||||
10099 | if (!IsUpdateExprFound) { | ||||||
10100 | // { v = x; x = expr; } | ||||||
10101 | auto *FirstExpr = dyn_cast<Expr>(First); | ||||||
10102 | auto *SecondExpr = dyn_cast<Expr>(Second); | ||||||
10103 | if (!FirstExpr || !SecondExpr || | ||||||
10104 | !(FirstExpr->isInstantiationDependent() || | ||||||
10105 | SecondExpr->isInstantiationDependent())) { | ||||||
10106 | auto *FirstBinOp = dyn_cast<BinaryOperator>(First); | ||||||
10107 | if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { | ||||||
10108 | ErrorFound = NotAnAssignmentOp; | ||||||
10109 | NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() | ||||||
10110 | : First->getBeginLoc(); | ||||||
10111 | NoteRange = ErrorRange = FirstBinOp | ||||||
10112 | ? FirstBinOp->getSourceRange() | ||||||
10113 | : SourceRange(ErrorLoc, ErrorLoc); | ||||||
10114 | } else { | ||||||
10115 | auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); | ||||||
10116 | if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { | ||||||
10117 | ErrorFound = NotAnAssignmentOp; | ||||||
10118 | NoteLoc = ErrorLoc = SecondBinOp | ||||||
10119 | ? SecondBinOp->getOperatorLoc() | ||||||
10120 | : Second->getBeginLoc(); | ||||||
10121 | NoteRange = ErrorRange = | ||||||
10122 | SecondBinOp ? SecondBinOp->getSourceRange() | ||||||
10123 | : SourceRange(ErrorLoc, ErrorLoc); | ||||||
10124 | } else { | ||||||
10125 | Expr *PossibleXRHSInFirst = | ||||||
10126 | FirstBinOp->getRHS()->IgnoreParenImpCasts(); | ||||||
10127 | Expr *PossibleXLHSInSecond = | ||||||
10128 | SecondBinOp->getLHS()->IgnoreParenImpCasts(); | ||||||
10129 | llvm::FoldingSetNodeID X1Id, X2Id; | ||||||
10130 | PossibleXRHSInFirst->Profile(X1Id, Context, | ||||||
10131 | /*Canonical=*/true); | ||||||
10132 | PossibleXLHSInSecond->Profile(X2Id, Context, | ||||||
10133 | /*Canonical=*/true); | ||||||
10134 | IsUpdateExprFound = X1Id == X2Id; | ||||||
10135 | if (IsUpdateExprFound) { | ||||||
10136 | V = FirstBinOp->getLHS(); | ||||||
10137 | X = SecondBinOp->getLHS(); | ||||||
10138 | E = SecondBinOp->getRHS(); | ||||||
10139 | UE = nullptr; | ||||||
10140 | IsXLHSInRHSPart = false; | ||||||
10141 | IsPostfixUpdate = true; | ||||||
10142 | } else { | ||||||
10143 | ErrorFound = NotASpecificExpression; | ||||||
10144 | ErrorLoc = FirstBinOp->getExprLoc(); | ||||||
10145 | ErrorRange = FirstBinOp->getSourceRange(); | ||||||
10146 | NoteLoc = SecondBinOp->getLHS()->getExprLoc(); | ||||||
10147 | NoteRange = SecondBinOp->getRHS()->getSourceRange(); | ||||||
10148 | } | ||||||
10149 | } | ||||||
10150 | } | ||||||
10151 | } | ||||||
10152 | } | ||||||
10153 | } else { | ||||||
10154 | NoteLoc = ErrorLoc = Body->getBeginLoc(); | ||||||
10155 | NoteRange = ErrorRange = | ||||||
10156 | SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); | ||||||
10157 | ErrorFound = NotTwoSubstatements; | ||||||
10158 | } | ||||||
10159 | } else { | ||||||
10160 | NoteLoc = ErrorLoc = Body->getBeginLoc(); | ||||||
10161 | NoteRange = ErrorRange = | ||||||
10162 | SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); | ||||||
10163 | ErrorFound = NotACompoundStatement; | ||||||
10164 | } | ||||||
10165 | if (ErrorFound != NoError) { | ||||||
10166 | Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) | ||||||
10167 | << ErrorRange; | ||||||
10168 | Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; | ||||||
10169 | return StmtError(); | ||||||
10170 | } | ||||||
10171 | if (CurContext->isDependentContext()) | ||||||
10172 | UE = V = E = X = nullptr; | ||||||
10173 | } | ||||||
10174 | } | ||||||
10175 | |||||||
10176 | setFunctionHasBranchProtectedScope(); | ||||||
10177 | |||||||
10178 | return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, | ||||||
10179 | X, V, E, UE, IsXLHSInRHSPart, | ||||||
10180 | IsPostfixUpdate); | ||||||
10181 | } | ||||||
10182 | |||||||
10183 | StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, | ||||||
10184 | Stmt *AStmt, | ||||||
10185 | SourceLocation StartLoc, | ||||||
10186 | SourceLocation EndLoc) { | ||||||
10187 | if (!AStmt) | ||||||
10188 | return StmtError(); | ||||||
10189 | |||||||
10190 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
10191 | // 1.2.2 OpenMP Language Terminology | ||||||
10192 | // Structured block - An executable statement with a single entry at the | ||||||
10193 | // top and a single exit at the bottom. | ||||||
10194 | // The point of exit cannot be a branch out of the structured block. | ||||||
10195 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
10196 | CS->getCapturedDecl()->setNothrow(); | ||||||
10197 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); | ||||||
10198 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||
10199 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||
10200 | // 1.2.2 OpenMP Language Terminology | ||||||
10201 | // Structured block - An executable statement with a single entry at the | ||||||
10202 | // top and a single exit at the bottom. | ||||||
10203 | // The point of exit cannot be a branch out of the structured block. | ||||||
10204 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
10205 | CS->getCapturedDecl()->setNothrow(); | ||||||
10206 | } | ||||||
10207 | |||||||
10208 | // OpenMP [2.16, Nesting of Regions] | ||||||
10209 | // If specified, a teams construct must be contained within a target | ||||||
10210 | // construct. That target construct must contain no statements or directives | ||||||
10211 | // outside of the teams construct. | ||||||
10212 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasInnerTeamsRegion()) { | ||||||
10213 | const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); | ||||||
10214 | bool OMPTeamsFound = true; | ||||||
10215 | if (const auto *CS = dyn_cast<CompoundStmt>(S)) { | ||||||
10216 | auto I = CS->body_begin(); | ||||||
10217 | while (I != CS->body_end()) { | ||||||
10218 | const auto *OED = dyn_cast<OMPExecutableDirective>(*I); | ||||||
10219 | if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || | ||||||
10220 | OMPTeamsFound) { | ||||||
10221 | |||||||
10222 | OMPTeamsFound = false; | ||||||
10223 | break; | ||||||
10224 | } | ||||||
10225 | ++I; | ||||||
10226 | } | ||||||
10227 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10227, __PRETTY_FUNCTION__)); | ||||||
10228 | S = *I; | ||||||
10229 | } else { | ||||||
10230 | const auto *OED = dyn_cast<OMPExecutableDirective>(S); | ||||||
10231 | OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); | ||||||
10232 | } | ||||||
10233 | if (!OMPTeamsFound) { | ||||||
10234 | Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); | ||||||
10235 | Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getInnerTeamsRegionLoc(), | ||||||
10236 | diag::note_omp_nested_teams_construct_here); | ||||||
10237 | Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) | ||||||
10238 | << isa<OMPExecutableDirective>(S); | ||||||
10239 | return StmtError(); | ||||||
10240 | } | ||||||
10241 | } | ||||||
10242 | |||||||
10243 | setFunctionHasBranchProtectedScope(); | ||||||
10244 | |||||||
10245 | return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); | ||||||
10246 | } | ||||||
10247 | |||||||
10248 | StmtResult | ||||||
10249 | Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, | ||||||
10250 | Stmt *AStmt, SourceLocation StartLoc, | ||||||
10251 | SourceLocation EndLoc) { | ||||||
10252 | if (!AStmt) | ||||||
10253 | return StmtError(); | ||||||
10254 | |||||||
10255 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
10256 | // 1.2.2 OpenMP Language Terminology | ||||||
10257 | // Structured block - An executable statement with a single entry at the | ||||||
10258 | // top and a single exit at the bottom. | ||||||
10259 | // The point of exit cannot be a branch out of the structured block. | ||||||
10260 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
10261 | CS->getCapturedDecl()->setNothrow(); | ||||||
10262 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); | ||||||
10263 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||
10264 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||
10265 | // 1.2.2 OpenMP Language Terminology | ||||||
10266 | // Structured block - An executable statement with a single entry at the | ||||||
10267 | // top and a single exit at the bottom. | ||||||
10268 | // The point of exit cannot be a branch out of the structured block. | ||||||
10269 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
10270 | CS->getCapturedDecl()->setNothrow(); | ||||||
10271 | } | ||||||
10272 | |||||||
10273 | setFunctionHasBranchProtectedScope(); | ||||||
10274 | |||||||
10275 | return OMPTargetParallelDirective::Create( | ||||||
10276 | Context, StartLoc, EndLoc, Clauses, AStmt, | ||||||
10277 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||
10278 | } | ||||||
10279 | |||||||
10280 | StmtResult Sema::ActOnOpenMPTargetParallelForDirective( | ||||||
10281 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||
10282 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||
10283 | if (!AStmt) | ||||||
10284 | return StmtError(); | ||||||
10285 | |||||||
10286 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
10287 | // 1.2.2 OpenMP Language Terminology | ||||||
10288 | // Structured block - An executable statement with a single entry at the | ||||||
10289 | // top and a single exit at the bottom. | ||||||
10290 | // The point of exit cannot be a branch out of the structured block. | ||||||
10291 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
10292 | CS->getCapturedDecl()->setNothrow(); | ||||||
10293 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); | ||||||
10294 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||
10295 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||
10296 | // 1.2.2 OpenMP Language Terminology | ||||||
10297 | // Structured block - An executable statement with a single entry at the | ||||||
10298 | // top and a single exit at the bottom. | ||||||
10299 | // The point of exit cannot be a branch out of the structured block. | ||||||
10300 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
10301 | CS->getCapturedDecl()->setNothrow(); | ||||||
10302 | } | ||||||
10303 | |||||||
10304 | OMPLoopDirective::HelperExprs B; | ||||||
10305 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||||
10306 | // define the nested loops number. | ||||||
10307 | unsigned NestedLoopCount = | ||||||
10308 | checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), | ||||||
10309 | getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||
10310 | VarsWithImplicitDSA, B); | ||||||
10311 | if (NestedLoopCount == 0) | ||||||
10312 | return StmtError(); | ||||||
10313 | |||||||
10314 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10315, __PRETTY_FUNCTION__)) | ||||||
10315 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10315, __PRETTY_FUNCTION__)); | ||||||
10316 | |||||||
10317 | if (!CurContext->isDependentContext()) { | ||||||
10318 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||
10319 | for (OMPClause *C : Clauses) { | ||||||
10320 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||
10321 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||
10322 | B.NumIterations, *this, CurScope, | ||||||
10323 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||
10324 | return StmtError(); | ||||||
10325 | } | ||||||
10326 | } | ||||||
10327 | |||||||
10328 | setFunctionHasBranchProtectedScope(); | ||||||
10329 | return OMPTargetParallelForDirective::Create( | ||||||
10330 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, | ||||||
10331 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||
10332 | } | ||||||
10333 | |||||||
10334 | /// Check for existence of a map clause in the list of clauses. | ||||||
10335 | static bool hasClauses(ArrayRef<OMPClause *> Clauses, | ||||||
10336 | const OpenMPClauseKind K) { | ||||||
10337 | return llvm::any_of( | ||||||
10338 | Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); | ||||||
10339 | } | ||||||
10340 | |||||||
10341 | template <typename... Params> | ||||||
10342 | static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, | ||||||
10343 | const Params... ClauseTypes) { | ||||||
10344 | return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); | ||||||
10345 | } | ||||||
10346 | |||||||
10347 | StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, | ||||||
10348 | Stmt *AStmt, | ||||||
10349 | SourceLocation StartLoc, | ||||||
10350 | SourceLocation EndLoc) { | ||||||
10351 | if (!AStmt) | ||||||
10352 | return StmtError(); | ||||||
10353 | |||||||
10354 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10354, __PRETTY_FUNCTION__)); | ||||||
10355 | |||||||
10356 | // OpenMP [2.12.2, target data Construct, Restrictions] | ||||||
10357 | // At least one map, use_device_addr or use_device_ptr clause must appear on | ||||||
10358 | // the directive. | ||||||
10359 | if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) && | ||||||
10360 | (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) { | ||||||
10361 | StringRef Expected; | ||||||
10362 | if (LangOpts.OpenMP < 50) | ||||||
10363 | Expected = "'map' or 'use_device_ptr'"; | ||||||
10364 | else | ||||||
10365 | Expected = "'map', 'use_device_ptr', or 'use_device_addr'"; | ||||||
10366 | Diag(StartLoc, diag::err_omp_no_clause_for_directive) | ||||||
10367 | << Expected << getOpenMPDirectiveName(OMPD_target_data); | ||||||
10368 | return StmtError(); | ||||||
10369 | } | ||||||
10370 | |||||||
10371 | setFunctionHasBranchProtectedScope(); | ||||||
10372 | |||||||
10373 | return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, | ||||||
10374 | AStmt); | ||||||
10375 | } | ||||||
10376 | |||||||
10377 | StmtResult | ||||||
10378 | Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, | ||||||
10379 | SourceLocation StartLoc, | ||||||
10380 | SourceLocation EndLoc, Stmt *AStmt) { | ||||||
10381 | if (!AStmt) | ||||||
10382 | return StmtError(); | ||||||
10383 | |||||||
10384 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
10385 | // 1.2.2 OpenMP Language Terminology | ||||||
10386 | // Structured block - An executable statement with a single entry at the | ||||||
10387 | // top and a single exit at the bottom. | ||||||
10388 | // The point of exit cannot be a branch out of the structured block. | ||||||
10389 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
10390 | CS->getCapturedDecl()->setNothrow(); | ||||||
10391 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); | ||||||
10392 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||
10393 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||
10394 | // 1.2.2 OpenMP Language Terminology | ||||||
10395 | // Structured block - An executable statement with a single entry at the | ||||||
10396 | // top and a single exit at the bottom. | ||||||
10397 | // The point of exit cannot be a branch out of the structured block. | ||||||
10398 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
10399 | CS->getCapturedDecl()->setNothrow(); | ||||||
10400 | } | ||||||
10401 | |||||||
10402 | // OpenMP [2.10.2, Restrictions, p. 99] | ||||||
10403 | // At least one map clause must appear on the directive. | ||||||
10404 | if (!hasClauses(Clauses, OMPC_map)) { | ||||||
10405 | Diag(StartLoc, diag::err_omp_no_clause_for_directive) | ||||||
10406 | << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); | ||||||
10407 | return StmtError(); | ||||||
10408 | } | ||||||
10409 | |||||||
10410 | return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, | ||||||
10411 | AStmt); | ||||||
10412 | } | ||||||
10413 | |||||||
10414 | StmtResult | ||||||
10415 | Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, | ||||||
10416 | SourceLocation StartLoc, | ||||||
10417 | SourceLocation EndLoc, Stmt *AStmt) { | ||||||
10418 | if (!AStmt) | ||||||
10419 | return StmtError(); | ||||||
10420 | |||||||
10421 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
10422 | // 1.2.2 OpenMP Language Terminology | ||||||
10423 | // Structured block - An executable statement with a single entry at the | ||||||
10424 | // top and a single exit at the bottom. | ||||||
10425 | // The point of exit cannot be a branch out of the structured block. | ||||||
10426 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
10427 | CS->getCapturedDecl()->setNothrow(); | ||||||
10428 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); | ||||||
10429 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||
10430 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||
10431 | // 1.2.2 OpenMP Language Terminology | ||||||
10432 | // Structured block - An executable statement with a single entry at the | ||||||
10433 | // top and a single exit at the bottom. | ||||||
10434 | // The point of exit cannot be a branch out of the structured block. | ||||||
10435 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
10436 | CS->getCapturedDecl()->setNothrow(); | ||||||
10437 | } | ||||||
10438 | |||||||
10439 | // OpenMP [2.10.3, Restrictions, p. 102] | ||||||
10440 | // At least one map clause must appear on the directive. | ||||||
10441 | if (!hasClauses(Clauses, OMPC_map)) { | ||||||
10442 | Diag(StartLoc, diag::err_omp_no_clause_for_directive) | ||||||
10443 | << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); | ||||||
10444 | return StmtError(); | ||||||
10445 | } | ||||||
10446 | |||||||
10447 | return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, | ||||||
10448 | AStmt); | ||||||
10449 | } | ||||||
10450 | |||||||
10451 | StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, | ||||||
10452 | SourceLocation StartLoc, | ||||||
10453 | SourceLocation EndLoc, | ||||||
10454 | Stmt *AStmt) { | ||||||
10455 | if (!AStmt) | ||||||
10456 | return StmtError(); | ||||||
10457 | |||||||
10458 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
10459 | // 1.2.2 OpenMP Language Terminology | ||||||
10460 | // Structured block - An executable statement with a single entry at the | ||||||
10461 | // top and a single exit at the bottom. | ||||||
10462 | // The point of exit cannot be a branch out of the structured block. | ||||||
10463 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
10464 | CS->getCapturedDecl()->setNothrow(); | ||||||
10465 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); | ||||||
10466 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||
10467 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||
10468 | // 1.2.2 OpenMP Language Terminology | ||||||
10469 | // Structured block - An executable statement with a single entry at the | ||||||
10470 | // top and a single exit at the bottom. | ||||||
10471 | // The point of exit cannot be a branch out of the structured block. | ||||||
10472 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
10473 | CS->getCapturedDecl()->setNothrow(); | ||||||
10474 | } | ||||||
10475 | |||||||
10476 | if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { | ||||||
10477 | Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); | ||||||
10478 | return StmtError(); | ||||||
10479 | } | ||||||
10480 | return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, | ||||||
10481 | AStmt); | ||||||
10482 | } | ||||||
10483 | |||||||
10484 | StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, | ||||||
10485 | Stmt *AStmt, SourceLocation StartLoc, | ||||||
10486 | SourceLocation EndLoc) { | ||||||
10487 | if (!AStmt) | ||||||
10488 | return StmtError(); | ||||||
10489 | |||||||
10490 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
10491 | // 1.2.2 OpenMP Language Terminology | ||||||
10492 | // Structured block - An executable statement with a single entry at the | ||||||
10493 | // top and a single exit at the bottom. | ||||||
10494 | // The point of exit cannot be a branch out of the structured block. | ||||||
10495 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
10496 | CS->getCapturedDecl()->setNothrow(); | ||||||
10497 | |||||||
10498 | setFunctionHasBranchProtectedScope(); | ||||||
10499 | |||||||
10500 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentTeamsRegionLoc(StartLoc); | ||||||
10501 | |||||||
10502 | return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); | ||||||
10503 | } | ||||||
10504 | |||||||
10505 | StmtResult | ||||||
10506 | Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, | ||||||
10507 | SourceLocation EndLoc, | ||||||
10508 | OpenMPDirectiveKind CancelRegion) { | ||||||
10509 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isParentNowaitRegion()) { | ||||||
10510 | Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; | ||||||
10511 | return StmtError(); | ||||||
10512 | } | ||||||
10513 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isParentOrderedRegion()) { | ||||||
10514 | Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; | ||||||
10515 | return StmtError(); | ||||||
10516 | } | ||||||
10517 | return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, | ||||||
10518 | CancelRegion); | ||||||
10519 | } | ||||||
10520 | |||||||
10521 | StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, | ||||||
10522 | SourceLocation StartLoc, | ||||||
10523 | SourceLocation EndLoc, | ||||||
10524 | OpenMPDirectiveKind CancelRegion) { | ||||||
10525 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isParentNowaitRegion()) { | ||||||
10526 | Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; | ||||||
10527 | return StmtError(); | ||||||
10528 | } | ||||||
10529 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isParentOrderedRegion()) { | ||||||
10530 | Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; | ||||||
10531 | return StmtError(); | ||||||
10532 | } | ||||||
10533 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentCancelRegion(/*Cancel=*/true); | ||||||
10534 | return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, | ||||||
10535 | CancelRegion); | ||||||
10536 | } | ||||||
10537 | |||||||
10538 | static bool checkGrainsizeNumTasksClauses(Sema &S, | ||||||
10539 | ArrayRef<OMPClause *> Clauses) { | ||||||
10540 | const OMPClause *PrevClause = nullptr; | ||||||
10541 | bool ErrorFound = false; | ||||||
10542 | for (const OMPClause *C : Clauses) { | ||||||
10543 | if (C->getClauseKind() == OMPC_grainsize || | ||||||
10544 | C->getClauseKind() == OMPC_num_tasks) { | ||||||
10545 | if (!PrevClause) | ||||||
10546 | PrevClause = C; | ||||||
10547 | else if (PrevClause->getClauseKind() != C->getClauseKind()) { | ||||||
10548 | S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) | ||||||
10549 | << getOpenMPClauseName(C->getClauseKind()) | ||||||
10550 | << getOpenMPClauseName(PrevClause->getClauseKind()); | ||||||
10551 | S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) | ||||||
10552 | << getOpenMPClauseName(PrevClause->getClauseKind()); | ||||||
10553 | ErrorFound = true; | ||||||
10554 | } | ||||||
10555 | } | ||||||
10556 | } | ||||||
10557 | return ErrorFound; | ||||||
10558 | } | ||||||
10559 | |||||||
10560 | static bool checkReductionClauseWithNogroup(Sema &S, | ||||||
10561 | ArrayRef<OMPClause *> Clauses) { | ||||||
10562 | const OMPClause *ReductionClause = nullptr; | ||||||
10563 | const OMPClause *NogroupClause = nullptr; | ||||||
10564 | for (const OMPClause *C : Clauses) { | ||||||
10565 | if (C->getClauseKind() == OMPC_reduction) { | ||||||
10566 | ReductionClause = C; | ||||||
10567 | if (NogroupClause) | ||||||
10568 | break; | ||||||
10569 | continue; | ||||||
10570 | } | ||||||
10571 | if (C->getClauseKind() == OMPC_nogroup) { | ||||||
10572 | NogroupClause = C; | ||||||
10573 | if (ReductionClause) | ||||||
10574 | break; | ||||||
10575 | continue; | ||||||
10576 | } | ||||||
10577 | } | ||||||
10578 | if (ReductionClause && NogroupClause) { | ||||||
10579 | S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) | ||||||
10580 | << SourceRange(NogroupClause->getBeginLoc(), | ||||||
10581 | NogroupClause->getEndLoc()); | ||||||
10582 | return true; | ||||||
10583 | } | ||||||
10584 | return false; | ||||||
10585 | } | ||||||
10586 | |||||||
10587 | StmtResult Sema::ActOnOpenMPTaskLoopDirective( | ||||||
10588 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||
10589 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||
10590 | if (!AStmt) | ||||||
10591 | return StmtError(); | ||||||
10592 | |||||||
10593 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10593, __PRETTY_FUNCTION__)); | ||||||
10594 | OMPLoopDirective::HelperExprs B; | ||||||
10595 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||||
10596 | // define the nested loops number. | ||||||
10597 | unsigned NestedLoopCount = | ||||||
10598 | checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), | ||||||
10599 | /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||
10600 | VarsWithImplicitDSA, B); | ||||||
10601 | if (NestedLoopCount == 0) | ||||||
10602 | return StmtError(); | ||||||
10603 | |||||||
10604 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10605, __PRETTY_FUNCTION__)) | ||||||
10605 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10605, __PRETTY_FUNCTION__)); | ||||||
10606 | |||||||
10607 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] | ||||||
10608 | // The grainsize clause and num_tasks clause are mutually exclusive and may | ||||||
10609 | // not appear on the same taskloop directive. | ||||||
10610 | if (checkGrainsizeNumTasksClauses(*this, Clauses)) | ||||||
10611 | return StmtError(); | ||||||
10612 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] | ||||||
10613 | // If a reduction clause is present on the taskloop directive, the nogroup | ||||||
10614 | // clause must not be specified. | ||||||
10615 | if (checkReductionClauseWithNogroup(*this, Clauses)) | ||||||
10616 | return StmtError(); | ||||||
10617 | |||||||
10618 | setFunctionHasBranchProtectedScope(); | ||||||
10619 | return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, | ||||||
10620 | NestedLoopCount, Clauses, AStmt, B, | ||||||
10621 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||
10622 | } | ||||||
10623 | |||||||
10624 | StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( | ||||||
10625 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||
10626 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||
10627 | if (!AStmt) | ||||||
10628 | return StmtError(); | ||||||
10629 | |||||||
10630 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10630, __PRETTY_FUNCTION__)); | ||||||
10631 | OMPLoopDirective::HelperExprs B; | ||||||
10632 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||||
10633 | // define the nested loops number. | ||||||
10634 | unsigned NestedLoopCount = | ||||||
10635 | checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), | ||||||
10636 | /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||
10637 | VarsWithImplicitDSA, B); | ||||||
10638 | if (NestedLoopCount == 0) | ||||||
10639 | return StmtError(); | ||||||
10640 | |||||||
10641 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10642, __PRETTY_FUNCTION__)) | ||||||
10642 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10642, __PRETTY_FUNCTION__)); | ||||||
10643 | |||||||
10644 | if (!CurContext->isDependentContext()) { | ||||||
10645 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||
10646 | for (OMPClause *C : Clauses) { | ||||||
10647 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||
10648 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||
10649 | B.NumIterations, *this, CurScope, | ||||||
10650 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||
10651 | return StmtError(); | ||||||
10652 | } | ||||||
10653 | } | ||||||
10654 | |||||||
10655 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] | ||||||
10656 | // The grainsize clause and num_tasks clause are mutually exclusive and may | ||||||
10657 | // not appear on the same taskloop directive. | ||||||
10658 | if (checkGrainsizeNumTasksClauses(*this, Clauses)) | ||||||
10659 | return StmtError(); | ||||||
10660 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] | ||||||
10661 | // If a reduction clause is present on the taskloop directive, the nogroup | ||||||
10662 | // clause must not be specified. | ||||||
10663 | if (checkReductionClauseWithNogroup(*this, Clauses)) | ||||||
10664 | return StmtError(); | ||||||
10665 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||
10666 | return StmtError(); | ||||||
10667 | |||||||
10668 | setFunctionHasBranchProtectedScope(); | ||||||
10669 | return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, | ||||||
10670 | NestedLoopCount, Clauses, AStmt, B); | ||||||
10671 | } | ||||||
10672 | |||||||
10673 | StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( | ||||||
10674 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||
10675 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||
10676 | if (!AStmt) | ||||||
10677 | return StmtError(); | ||||||
10678 | |||||||
10679 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10679, __PRETTY_FUNCTION__)); | ||||||
10680 | OMPLoopDirective::HelperExprs B; | ||||||
10681 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||||
10682 | // define the nested loops number. | ||||||
10683 | unsigned NestedLoopCount = | ||||||
10684 | checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), | ||||||
10685 | /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||
10686 | VarsWithImplicitDSA, B); | ||||||
10687 | if (NestedLoopCount == 0) | ||||||
10688 | return StmtError(); | ||||||
10689 | |||||||
10690 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10691, __PRETTY_FUNCTION__)) | ||||||
10691 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10691, __PRETTY_FUNCTION__)); | ||||||
10692 | |||||||
10693 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] | ||||||
10694 | // The grainsize clause and num_tasks clause are mutually exclusive and may | ||||||
10695 | // not appear on the same taskloop directive. | ||||||
10696 | if (checkGrainsizeNumTasksClauses(*this, Clauses)) | ||||||
10697 | return StmtError(); | ||||||
10698 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] | ||||||
10699 | // If a reduction clause is present on the taskloop directive, the nogroup | ||||||
10700 | // clause must not be specified. | ||||||
10701 | if (checkReductionClauseWithNogroup(*this, Clauses)) | ||||||
10702 | return StmtError(); | ||||||
10703 | |||||||
10704 | setFunctionHasBranchProtectedScope(); | ||||||
10705 | return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, | ||||||
10706 | NestedLoopCount, Clauses, AStmt, B, | ||||||
10707 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||
10708 | } | ||||||
10709 | |||||||
10710 | StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( | ||||||
10711 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||
10712 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||
10713 | if (!AStmt) | ||||||
10714 | return StmtError(); | ||||||
10715 | |||||||
10716 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10716, __PRETTY_FUNCTION__)); | ||||||
10717 | OMPLoopDirective::HelperExprs B; | ||||||
10718 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||||
10719 | // define the nested loops number. | ||||||
10720 | unsigned NestedLoopCount = | ||||||
10721 | checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), | ||||||
10722 | /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||
10723 | VarsWithImplicitDSA, B); | ||||||
10724 | if (NestedLoopCount == 0) | ||||||
10725 | return StmtError(); | ||||||
10726 | |||||||
10727 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10728, __PRETTY_FUNCTION__)) | ||||||
10728 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10728, __PRETTY_FUNCTION__)); | ||||||
10729 | |||||||
10730 | if (!CurContext->isDependentContext()) { | ||||||
10731 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||
10732 | for (OMPClause *C : Clauses) { | ||||||
10733 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||
10734 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||
10735 | B.NumIterations, *this, CurScope, | ||||||
10736 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||
10737 | return StmtError(); | ||||||
10738 | } | ||||||
10739 | } | ||||||
10740 | |||||||
10741 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] | ||||||
10742 | // The grainsize clause and num_tasks clause are mutually exclusive and may | ||||||
10743 | // not appear on the same taskloop directive. | ||||||
10744 | if (checkGrainsizeNumTasksClauses(*this, Clauses)) | ||||||
10745 | return StmtError(); | ||||||
10746 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] | ||||||
10747 | // If a reduction clause is present on the taskloop directive, the nogroup | ||||||
10748 | // clause must not be specified. | ||||||
10749 | if (checkReductionClauseWithNogroup(*this, Clauses)) | ||||||
10750 | return StmtError(); | ||||||
10751 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||
10752 | return StmtError(); | ||||||
10753 | |||||||
10754 | setFunctionHasBranchProtectedScope(); | ||||||
10755 | return OMPMasterTaskLoopSimdDirective::Create( | ||||||
10756 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||||
10757 | } | ||||||
10758 | |||||||
10759 | StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( | ||||||
10760 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||
10761 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||
10762 | if (!AStmt) | ||||||
10763 | return StmtError(); | ||||||
10764 | |||||||
10765 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10765, __PRETTY_FUNCTION__)); | ||||||
10766 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
10767 | // 1.2.2 OpenMP Language Terminology | ||||||
10768 | // Structured block - An executable statement with a single entry at the | ||||||
10769 | // top and a single exit at the bottom. | ||||||
10770 | // The point of exit cannot be a branch out of the structured block. | ||||||
10771 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
10772 | CS->getCapturedDecl()->setNothrow(); | ||||||
10773 | for (int ThisCaptureLevel = | ||||||
10774 | getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); | ||||||
10775 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||
10776 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||
10777 | // 1.2.2 OpenMP Language Terminology | ||||||
10778 | // Structured block - An executable statement with a single entry at the | ||||||
10779 | // top and a single exit at the bottom. | ||||||
10780 | // The point of exit cannot be a branch out of the structured block. | ||||||
10781 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
10782 | CS->getCapturedDecl()->setNothrow(); | ||||||
10783 | } | ||||||
10784 | |||||||
10785 | OMPLoopDirective::HelperExprs B; | ||||||
10786 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||||
10787 | // define the nested loops number. | ||||||
10788 | unsigned NestedLoopCount = checkOpenMPLoop( | ||||||
10789 | OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), | ||||||
10790 | /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||
10791 | VarsWithImplicitDSA, B); | ||||||
10792 | if (NestedLoopCount == 0) | ||||||
10793 | return StmtError(); | ||||||
10794 | |||||||
10795 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10796, __PRETTY_FUNCTION__)) | ||||||
10796 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10796, __PRETTY_FUNCTION__)); | ||||||
10797 | |||||||
10798 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] | ||||||
10799 | // The grainsize clause and num_tasks clause are mutually exclusive and may | ||||||
10800 | // not appear on the same taskloop directive. | ||||||
10801 | if (checkGrainsizeNumTasksClauses(*this, Clauses)) | ||||||
10802 | return StmtError(); | ||||||
10803 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] | ||||||
10804 | // If a reduction clause is present on the taskloop directive, the nogroup | ||||||
10805 | // clause must not be specified. | ||||||
10806 | if (checkReductionClauseWithNogroup(*this, Clauses)) | ||||||
10807 | return StmtError(); | ||||||
10808 | |||||||
10809 | setFunctionHasBranchProtectedScope(); | ||||||
10810 | return OMPParallelMasterTaskLoopDirective::Create( | ||||||
10811 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, | ||||||
10812 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||
10813 | } | ||||||
10814 | |||||||
10815 | StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( | ||||||
10816 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||
10817 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||
10818 | if (!AStmt) | ||||||
10819 | return StmtError(); | ||||||
10820 | |||||||
10821 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10821, __PRETTY_FUNCTION__)); | ||||||
10822 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
10823 | // 1.2.2 OpenMP Language Terminology | ||||||
10824 | // Structured block - An executable statement with a single entry at the | ||||||
10825 | // top and a single exit at the bottom. | ||||||
10826 | // The point of exit cannot be a branch out of the structured block. | ||||||
10827 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
10828 | CS->getCapturedDecl()->setNothrow(); | ||||||
10829 | for (int ThisCaptureLevel = | ||||||
10830 | getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); | ||||||
10831 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||
10832 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||
10833 | // 1.2.2 OpenMP Language Terminology | ||||||
10834 | // Structured block - An executable statement with a single entry at the | ||||||
10835 | // top and a single exit at the bottom. | ||||||
10836 | // The point of exit cannot be a branch out of the structured block. | ||||||
10837 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
10838 | CS->getCapturedDecl()->setNothrow(); | ||||||
10839 | } | ||||||
10840 | |||||||
10841 | OMPLoopDirective::HelperExprs B; | ||||||
10842 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||||
10843 | // define the nested loops number. | ||||||
10844 | unsigned NestedLoopCount = checkOpenMPLoop( | ||||||
10845 | OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), | ||||||
10846 | /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||
10847 | VarsWithImplicitDSA, B); | ||||||
10848 | if (NestedLoopCount == 0) | ||||||
10849 | return StmtError(); | ||||||
10850 | |||||||
10851 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10852, __PRETTY_FUNCTION__)) | ||||||
10852 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10852, __PRETTY_FUNCTION__)); | ||||||
10853 | |||||||
10854 | if (!CurContext->isDependentContext()) { | ||||||
10855 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||
10856 | for (OMPClause *C : Clauses) { | ||||||
10857 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||
10858 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||
10859 | B.NumIterations, *this, CurScope, | ||||||
10860 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||
10861 | return StmtError(); | ||||||
10862 | } | ||||||
10863 | } | ||||||
10864 | |||||||
10865 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] | ||||||
10866 | // The grainsize clause and num_tasks clause are mutually exclusive and may | ||||||
10867 | // not appear on the same taskloop directive. | ||||||
10868 | if (checkGrainsizeNumTasksClauses(*this, Clauses)) | ||||||
10869 | return StmtError(); | ||||||
10870 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] | ||||||
10871 | // If a reduction clause is present on the taskloop directive, the nogroup | ||||||
10872 | // clause must not be specified. | ||||||
10873 | if (checkReductionClauseWithNogroup(*this, Clauses)) | ||||||
10874 | return StmtError(); | ||||||
10875 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||
10876 | return StmtError(); | ||||||
10877 | |||||||
10878 | setFunctionHasBranchProtectedScope(); | ||||||
10879 | return OMPParallelMasterTaskLoopSimdDirective::Create( | ||||||
10880 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||||
10881 | } | ||||||
10882 | |||||||
10883 | StmtResult Sema::ActOnOpenMPDistributeDirective( | ||||||
10884 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||
10885 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||
10886 | if (!AStmt) | ||||||
10887 | return StmtError(); | ||||||
10888 | |||||||
10889 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10889, __PRETTY_FUNCTION__)); | ||||||
10890 | OMPLoopDirective::HelperExprs B; | ||||||
10891 | // In presence of clause 'collapse' with number of loops, it will | ||||||
10892 | // define the nested loops number. | ||||||
10893 | unsigned NestedLoopCount = | ||||||
10894 | checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), | ||||||
10895 | nullptr /*ordered not a clause on distribute*/, AStmt, | ||||||
10896 | *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VarsWithImplicitDSA, B); | ||||||
10897 | if (NestedLoopCount == 0) | ||||||
10898 | return StmtError(); | ||||||
10899 | |||||||
10900 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10901, __PRETTY_FUNCTION__)) | ||||||
10901 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10901, __PRETTY_FUNCTION__)); | ||||||
10902 | |||||||
10903 | setFunctionHasBranchProtectedScope(); | ||||||
10904 | return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, | ||||||
10905 | NestedLoopCount, Clauses, AStmt, B); | ||||||
10906 | } | ||||||
10907 | |||||||
10908 | StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( | ||||||
10909 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||
10910 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||
10911 | if (!AStmt) | ||||||
10912 | return StmtError(); | ||||||
10913 | |||||||
10914 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
10915 | // 1.2.2 OpenMP Language Terminology | ||||||
10916 | // Structured block - An executable statement with a single entry at the | ||||||
10917 | // top and a single exit at the bottom. | ||||||
10918 | // The point of exit cannot be a branch out of the structured block. | ||||||
10919 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
10920 | CS->getCapturedDecl()->setNothrow(); | ||||||
10921 | for (int ThisCaptureLevel = | ||||||
10922 | getOpenMPCaptureLevels(OMPD_distribute_parallel_for); | ||||||
10923 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||
10924 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||
10925 | // 1.2.2 OpenMP Language Terminology | ||||||
10926 | // Structured block - An executable statement with a single entry at the | ||||||
10927 | // top and a single exit at the bottom. | ||||||
10928 | // The point of exit cannot be a branch out of the structured block. | ||||||
10929 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
10930 | CS->getCapturedDecl()->setNothrow(); | ||||||
10931 | } | ||||||
10932 | |||||||
10933 | OMPLoopDirective::HelperExprs B; | ||||||
10934 | // In presence of clause 'collapse' with number of loops, it will | ||||||
10935 | // define the nested loops number. | ||||||
10936 | unsigned NestedLoopCount = checkOpenMPLoop( | ||||||
10937 | OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), | ||||||
10938 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||
10939 | VarsWithImplicitDSA, B); | ||||||
10940 | if (NestedLoopCount == 0) | ||||||
10941 | return StmtError(); | ||||||
10942 | |||||||
10943 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10944, __PRETTY_FUNCTION__)) | ||||||
10944 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10944, __PRETTY_FUNCTION__)); | ||||||
10945 | |||||||
10946 | setFunctionHasBranchProtectedScope(); | ||||||
10947 | return OMPDistributeParallelForDirective::Create( | ||||||
10948 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, | ||||||
10949 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||
10950 | } | ||||||
10951 | |||||||
10952 | StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( | ||||||
10953 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||
10954 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||
10955 | if (!AStmt) | ||||||
10956 | return StmtError(); | ||||||
10957 | |||||||
10958 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
10959 | // 1.2.2 OpenMP Language Terminology | ||||||
10960 | // Structured block - An executable statement with a single entry at the | ||||||
10961 | // top and a single exit at the bottom. | ||||||
10962 | // The point of exit cannot be a branch out of the structured block. | ||||||
10963 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
10964 | CS->getCapturedDecl()->setNothrow(); | ||||||
10965 | for (int ThisCaptureLevel = | ||||||
10966 | getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); | ||||||
10967 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||
10968 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||
10969 | // 1.2.2 OpenMP Language Terminology | ||||||
10970 | // Structured block - An executable statement with a single entry at the | ||||||
10971 | // top and a single exit at the bottom. | ||||||
10972 | // The point of exit cannot be a branch out of the structured block. | ||||||
10973 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
10974 | CS->getCapturedDecl()->setNothrow(); | ||||||
10975 | } | ||||||
10976 | |||||||
10977 | OMPLoopDirective::HelperExprs B; | ||||||
10978 | // In presence of clause 'collapse' with number of loops, it will | ||||||
10979 | // define the nested loops number. | ||||||
10980 | unsigned NestedLoopCount = checkOpenMPLoop( | ||||||
10981 | OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), | ||||||
10982 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||
10983 | VarsWithImplicitDSA, B); | ||||||
10984 | if (NestedLoopCount == 0) | ||||||
10985 | return StmtError(); | ||||||
10986 | |||||||
10987 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10988, __PRETTY_FUNCTION__)) | ||||||
10988 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10988, __PRETTY_FUNCTION__)); | ||||||
10989 | |||||||
10990 | if (!CurContext->isDependentContext()) { | ||||||
10991 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||
10992 | for (OMPClause *C : Clauses) { | ||||||
10993 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||
10994 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||
10995 | B.NumIterations, *this, CurScope, | ||||||
10996 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||
10997 | return StmtError(); | ||||||
10998 | } | ||||||
10999 | } | ||||||
11000 | |||||||
11001 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||
11002 | return StmtError(); | ||||||
11003 | |||||||
11004 | setFunctionHasBranchProtectedScope(); | ||||||
11005 | return OMPDistributeParallelForSimdDirective::Create( | ||||||
11006 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||||
11007 | } | ||||||
11008 | |||||||
11009 | StmtResult Sema::ActOnOpenMPDistributeSimdDirective( | ||||||
11010 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||
11011 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||
11012 | if (!AStmt) | ||||||
11013 | return StmtError(); | ||||||
11014 | |||||||
11015 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
11016 | // 1.2.2 OpenMP Language Terminology | ||||||
11017 | // Structured block - An executable statement with a single entry at the | ||||||
11018 | // top and a single exit at the bottom. | ||||||
11019 | // The point of exit cannot be a branch out of the structured block. | ||||||
11020 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
11021 | CS->getCapturedDecl()->setNothrow(); | ||||||
11022 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); | ||||||
11023 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||
11024 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||
11025 | // 1.2.2 OpenMP Language Terminology | ||||||
11026 | // Structured block - An executable statement with a single entry at the | ||||||
11027 | // top and a single exit at the bottom. | ||||||
11028 | // The point of exit cannot be a branch out of the structured block. | ||||||
11029 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
11030 | CS->getCapturedDecl()->setNothrow(); | ||||||
11031 | } | ||||||
11032 | |||||||
11033 | OMPLoopDirective::HelperExprs B; | ||||||
11034 | // In presence of clause 'collapse' with number of loops, it will | ||||||
11035 | // define the nested loops number. | ||||||
11036 | unsigned NestedLoopCount = | ||||||
11037 | checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), | ||||||
11038 | nullptr /*ordered not a clause on distribute*/, CS, *this, | ||||||
11039 | *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VarsWithImplicitDSA, B); | ||||||
11040 | if (NestedLoopCount == 0) | ||||||
11041 | return StmtError(); | ||||||
11042 | |||||||
11043 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11044, __PRETTY_FUNCTION__)) | ||||||
11044 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11044, __PRETTY_FUNCTION__)); | ||||||
11045 | |||||||
11046 | if (!CurContext->isDependentContext()) { | ||||||
11047 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||
11048 | for (OMPClause *C : Clauses) { | ||||||
11049 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||
11050 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||
11051 | B.NumIterations, *this, CurScope, | ||||||
11052 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||
11053 | return StmtError(); | ||||||
11054 | } | ||||||
11055 | } | ||||||
11056 | |||||||
11057 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||
11058 | return StmtError(); | ||||||
11059 | |||||||
11060 | setFunctionHasBranchProtectedScope(); | ||||||
11061 | return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, | ||||||
11062 | NestedLoopCount, Clauses, AStmt, B); | ||||||
11063 | } | ||||||
11064 | |||||||
11065 | StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( | ||||||
11066 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||
11067 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||
11068 | if (!AStmt) | ||||||
11069 | return StmtError(); | ||||||
11070 | |||||||
11071 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
11072 | // 1.2.2 OpenMP Language Terminology | ||||||
11073 | // Structured block - An executable statement with a single entry at the | ||||||
11074 | // top and a single exit at the bottom. | ||||||
11075 | // The point of exit cannot be a branch out of the structured block. | ||||||
11076 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
11077 | CS->getCapturedDecl()->setNothrow(); | ||||||
11078 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); | ||||||
11079 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||
11080 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||
11081 | // 1.2.2 OpenMP Language Terminology | ||||||
11082 | // Structured block - An executable statement with a single entry at the | ||||||
11083 | // top and a single exit at the bottom. | ||||||
11084 | // The point of exit cannot be a branch out of the structured block. | ||||||
11085 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
11086 | CS->getCapturedDecl()->setNothrow(); | ||||||
11087 | } | ||||||
11088 | |||||||
11089 | OMPLoopDirective::HelperExprs B; | ||||||
11090 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||||
11091 | // define the nested loops number. | ||||||
11092 | unsigned NestedLoopCount = checkOpenMPLoop( | ||||||
11093 | OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), | ||||||
11094 | getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||
11095 | VarsWithImplicitDSA, B); | ||||||
11096 | if (NestedLoopCount == 0) | ||||||
11097 | return StmtError(); | ||||||
11098 | |||||||
11099 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11100, __PRETTY_FUNCTION__)) | ||||||
11100 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11100, __PRETTY_FUNCTION__)); | ||||||
11101 | |||||||
11102 | if (!CurContext->isDependentContext()) { | ||||||
11103 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||
11104 | for (OMPClause *C : Clauses) { | ||||||
11105 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||
11106 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||
11107 | B.NumIterations, *this, CurScope, | ||||||
11108 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||
11109 | return StmtError(); | ||||||
11110 | } | ||||||
11111 | } | ||||||
11112 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||
11113 | return StmtError(); | ||||||
11114 | |||||||
11115 | setFunctionHasBranchProtectedScope(); | ||||||
11116 | return OMPTargetParallelForSimdDirective::Create( | ||||||
11117 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||||
11118 | } | ||||||
11119 | |||||||
11120 | StmtResult Sema::ActOnOpenMPTargetSimdDirective( | ||||||
11121 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||
11122 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||
11123 | if (!AStmt) | ||||||
11124 | return StmtError(); | ||||||
11125 | |||||||
11126 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
11127 | // 1.2.2 OpenMP Language Terminology | ||||||
11128 | // Structured block - An executable statement with a single entry at the | ||||||
11129 | // top and a single exit at the bottom. | ||||||
11130 | // The point of exit cannot be a branch out of the structured block. | ||||||
11131 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
11132 | CS->getCapturedDecl()->setNothrow(); | ||||||
11133 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); | ||||||
11134 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||
11135 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||
11136 | // 1.2.2 OpenMP Language Terminology | ||||||
11137 | // Structured block - An executable statement with a single entry at the | ||||||
11138 | // top and a single exit at the bottom. | ||||||
11139 | // The point of exit cannot be a branch out of the structured block. | ||||||
11140 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
11141 | CS->getCapturedDecl()->setNothrow(); | ||||||
11142 | } | ||||||
11143 | |||||||
11144 | OMPLoopDirective::HelperExprs B; | ||||||
11145 | // In presence of clause 'collapse' with number of loops, it will define the | ||||||
11146 | // nested loops number. | ||||||
11147 | unsigned NestedLoopCount = | ||||||
11148 | checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), | ||||||
11149 | getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||
11150 | VarsWithImplicitDSA, B); | ||||||
11151 | if (NestedLoopCount == 0) | ||||||
11152 | return StmtError(); | ||||||
11153 | |||||||
11154 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11155, __PRETTY_FUNCTION__)) | ||||||
11155 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11155, __PRETTY_FUNCTION__)); | ||||||
11156 | |||||||
11157 | if (!CurContext->isDependentContext()) { | ||||||
11158 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||
11159 | for (OMPClause *C : Clauses) { | ||||||
11160 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||
11161 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||
11162 | B.NumIterations, *this, CurScope, | ||||||
11163 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||
11164 | return StmtError(); | ||||||
11165 | } | ||||||
11166 | } | ||||||
11167 | |||||||
11168 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||
11169 | return StmtError(); | ||||||
11170 | |||||||
11171 | setFunctionHasBranchProtectedScope(); | ||||||
11172 | return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, | ||||||
11173 | NestedLoopCount, Clauses, AStmt, B); | ||||||
11174 | } | ||||||
11175 | |||||||
11176 | StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( | ||||||
11177 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||
11178 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||
11179 | if (!AStmt) | ||||||
11180 | return StmtError(); | ||||||
11181 | |||||||
11182 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
11183 | // 1.2.2 OpenMP Language Terminology | ||||||
11184 | // Structured block - An executable statement with a single entry at the | ||||||
11185 | // top and a single exit at the bottom. | ||||||
11186 | // The point of exit cannot be a branch out of the structured block. | ||||||
11187 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
11188 | CS->getCapturedDecl()->setNothrow(); | ||||||
11189 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); | ||||||
11190 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||
11191 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||
11192 | // 1.2.2 OpenMP Language Terminology | ||||||
11193 | // Structured block - An executable statement with a single entry at the | ||||||
11194 | // top and a single exit at the bottom. | ||||||
11195 | // The point of exit cannot be a branch out of the structured block. | ||||||
11196 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
11197 | CS->getCapturedDecl()->setNothrow(); | ||||||
11198 | } | ||||||
11199 | |||||||
11200 | OMPLoopDirective::HelperExprs B; | ||||||
11201 | // In presence of clause 'collapse' with number of loops, it will | ||||||
11202 | // define the nested loops number. | ||||||
11203 | unsigned NestedLoopCount = | ||||||
11204 | checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), | ||||||
11205 | nullptr /*ordered not a clause on distribute*/, CS, *this, | ||||||
11206 | *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VarsWithImplicitDSA, B); | ||||||
11207 | if (NestedLoopCount == 0) | ||||||
11208 | return StmtError(); | ||||||
11209 | |||||||
11210 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11211, __PRETTY_FUNCTION__)) | ||||||
11211 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11211, __PRETTY_FUNCTION__)); | ||||||
11212 | |||||||
11213 | setFunctionHasBranchProtectedScope(); | ||||||
11214 | |||||||
11215 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentTeamsRegionLoc(StartLoc); | ||||||
11216 | |||||||
11217 | return OMPTeamsDistributeDirective::Create( | ||||||
11218 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||||
11219 | } | ||||||
11220 | |||||||
11221 | StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( | ||||||
11222 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||
11223 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||
11224 | if (!AStmt) | ||||||
11225 | return StmtError(); | ||||||
11226 | |||||||
11227 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
11228 | // 1.2.2 OpenMP Language Terminology | ||||||
11229 | // Structured block - An executable statement with a single entry at the | ||||||
11230 | // top and a single exit at the bottom. | ||||||
11231 | // The point of exit cannot be a branch out of the structured block. | ||||||
11232 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
11233 | CS->getCapturedDecl()->setNothrow(); | ||||||
11234 | for (int ThisCaptureLevel = | ||||||
11235 | getOpenMPCaptureLevels(OMPD_teams_distribute_simd); | ||||||
11236 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||
11237 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||
11238 | // 1.2.2 OpenMP Language Terminology | ||||||
11239 | // Structured block - An executable statement with a single entry at the | ||||||
11240 | // top and a single exit at the bottom. | ||||||
11241 | // The point of exit cannot be a branch out of the structured block. | ||||||
11242 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
11243 | CS->getCapturedDecl()->setNothrow(); | ||||||
11244 | } | ||||||
11245 | |||||||
11246 | OMPLoopDirective::HelperExprs B; | ||||||
11247 | // In presence of clause 'collapse' with number of loops, it will | ||||||
11248 | // define the nested loops number. | ||||||
11249 | unsigned NestedLoopCount = checkOpenMPLoop( | ||||||
11250 | OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), | ||||||
11251 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||
11252 | VarsWithImplicitDSA, B); | ||||||
11253 | |||||||
11254 | if (NestedLoopCount == 0) | ||||||
11255 | return StmtError(); | ||||||
11256 | |||||||
11257 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11258, __PRETTY_FUNCTION__)) | ||||||
11258 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11258, __PRETTY_FUNCTION__)); | ||||||
11259 | |||||||
11260 | if (!CurContext->isDependentContext()) { | ||||||
11261 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||
11262 | for (OMPClause *C : Clauses) { | ||||||
11263 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||
11264 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||
11265 | B.NumIterations, *this, CurScope, | ||||||
11266 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||
11267 | return StmtError(); | ||||||
11268 | } | ||||||
11269 | } | ||||||
11270 | |||||||
11271 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||
11272 | return StmtError(); | ||||||
11273 | |||||||
11274 | setFunctionHasBranchProtectedScope(); | ||||||
11275 | |||||||
11276 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentTeamsRegionLoc(StartLoc); | ||||||
11277 | |||||||
11278 | return OMPTeamsDistributeSimdDirective::Create( | ||||||
11279 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||||
11280 | } | ||||||
11281 | |||||||
11282 | StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( | ||||||
11283 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||
11284 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||
11285 | if (!AStmt) | ||||||
11286 | return StmtError(); | ||||||
11287 | |||||||
11288 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
11289 | // 1.2.2 OpenMP Language Terminology | ||||||
11290 | // Structured block - An executable statement with a single entry at the | ||||||
11291 | // top and a single exit at the bottom. | ||||||
11292 | // The point of exit cannot be a branch out of the structured block. | ||||||
11293 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
11294 | CS->getCapturedDecl()->setNothrow(); | ||||||
11295 | |||||||
11296 | for (int ThisCaptureLevel = | ||||||
11297 | getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); | ||||||
11298 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||
11299 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||
11300 | // 1.2.2 OpenMP Language Terminology | ||||||
11301 | // Structured block - An executable statement with a single entry at the | ||||||
11302 | // top and a single exit at the bottom. | ||||||
11303 | // The point of exit cannot be a branch out of the structured block. | ||||||
11304 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
11305 | CS->getCapturedDecl()->setNothrow(); | ||||||
11306 | } | ||||||
11307 | |||||||
11308 | OMPLoopDirective::HelperExprs B; | ||||||
11309 | // In presence of clause 'collapse' with number of loops, it will | ||||||
11310 | // define the nested loops number. | ||||||
11311 | unsigned NestedLoopCount = checkOpenMPLoop( | ||||||
11312 | OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), | ||||||
11313 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||
11314 | VarsWithImplicitDSA, B); | ||||||
11315 | |||||||
11316 | if (NestedLoopCount == 0) | ||||||
11317 | return StmtError(); | ||||||
11318 | |||||||
11319 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11320, __PRETTY_FUNCTION__)) | ||||||
11320 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11320, __PRETTY_FUNCTION__)); | ||||||
11321 | |||||||
11322 | if (!CurContext->isDependentContext()) { | ||||||
11323 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||
11324 | for (OMPClause *C : Clauses) { | ||||||
11325 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||
11326 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||
11327 | B.NumIterations, *this, CurScope, | ||||||
11328 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||
11329 | return StmtError(); | ||||||
11330 | } | ||||||
11331 | } | ||||||
11332 | |||||||
11333 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||
11334 | return StmtError(); | ||||||
11335 | |||||||
11336 | setFunctionHasBranchProtectedScope(); | ||||||
11337 | |||||||
11338 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentTeamsRegionLoc(StartLoc); | ||||||
11339 | |||||||
11340 | return OMPTeamsDistributeParallelForSimdDirective::Create( | ||||||
11341 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||||
11342 | } | ||||||
11343 | |||||||
11344 | StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( | ||||||
11345 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||
11346 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||
11347 | if (!AStmt) | ||||||
11348 | return StmtError(); | ||||||
11349 | |||||||
11350 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
11351 | // 1.2.2 OpenMP Language Terminology | ||||||
11352 | // Structured block - An executable statement with a single entry at the | ||||||
11353 | // top and a single exit at the bottom. | ||||||
11354 | // The point of exit cannot be a branch out of the structured block. | ||||||
11355 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
11356 | CS->getCapturedDecl()->setNothrow(); | ||||||
11357 | |||||||
11358 | for (int ThisCaptureLevel = | ||||||
11359 | getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); | ||||||
11360 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||
11361 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||
11362 | // 1.2.2 OpenMP Language Terminology | ||||||
11363 | // Structured block - An executable statement with a single entry at the | ||||||
11364 | // top and a single exit at the bottom. | ||||||
11365 | // The point of exit cannot be a branch out of the structured block. | ||||||
11366 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
11367 | CS->getCapturedDecl()->setNothrow(); | ||||||
11368 | } | ||||||
11369 | |||||||
11370 | OMPLoopDirective::HelperExprs B; | ||||||
11371 | // In presence of clause 'collapse' with number of loops, it will | ||||||
11372 | // define the nested loops number. | ||||||
11373 | unsigned NestedLoopCount = checkOpenMPLoop( | ||||||
11374 | OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), | ||||||
11375 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||
11376 | VarsWithImplicitDSA, B); | ||||||
11377 | |||||||
11378 | if (NestedLoopCount == 0) | ||||||
11379 | return StmtError(); | ||||||
11380 | |||||||
11381 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11382, __PRETTY_FUNCTION__)) | ||||||
11382 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11382, __PRETTY_FUNCTION__)); | ||||||
11383 | |||||||
11384 | setFunctionHasBranchProtectedScope(); | ||||||
11385 | |||||||
11386 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentTeamsRegionLoc(StartLoc); | ||||||
11387 | |||||||
11388 | return OMPTeamsDistributeParallelForDirective::Create( | ||||||
11389 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, | ||||||
11390 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||
11391 | } | ||||||
11392 | |||||||
11393 | StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, | ||||||
11394 | Stmt *AStmt, | ||||||
11395 | SourceLocation StartLoc, | ||||||
11396 | SourceLocation EndLoc) { | ||||||
11397 | if (!AStmt) | ||||||
11398 | return StmtError(); | ||||||
11399 | |||||||
11400 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
11401 | // 1.2.2 OpenMP Language Terminology | ||||||
11402 | // Structured block - An executable statement with a single entry at the | ||||||
11403 | // top and a single exit at the bottom. | ||||||
11404 | // The point of exit cannot be a branch out of the structured block. | ||||||
11405 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
11406 | CS->getCapturedDecl()->setNothrow(); | ||||||
11407 | |||||||
11408 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); | ||||||
11409 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||
11410 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||
11411 | // 1.2.2 OpenMP Language Terminology | ||||||
11412 | // Structured block - An executable statement with a single entry at the | ||||||
11413 | // top and a single exit at the bottom. | ||||||
11414 | // The point of exit cannot be a branch out of the structured block. | ||||||
11415 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
11416 | CS->getCapturedDecl()->setNothrow(); | ||||||
11417 | } | ||||||
11418 | setFunctionHasBranchProtectedScope(); | ||||||
11419 | |||||||
11420 | return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, | ||||||
11421 | AStmt); | ||||||
11422 | } | ||||||
11423 | |||||||
11424 | StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( | ||||||
11425 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||
11426 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||
11427 | if (!AStmt) | ||||||
11428 | return StmtError(); | ||||||
11429 | |||||||
11430 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
11431 | // 1.2.2 OpenMP Language Terminology | ||||||
11432 | // Structured block - An executable statement with a single entry at the | ||||||
11433 | // top and a single exit at the bottom. | ||||||
11434 | // The point of exit cannot be a branch out of the structured block. | ||||||
11435 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
11436 | CS->getCapturedDecl()->setNothrow(); | ||||||
11437 | for (int ThisCaptureLevel = | ||||||
11438 | getOpenMPCaptureLevels(OMPD_target_teams_distribute); | ||||||
11439 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||
11440 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||
11441 | // 1.2.2 OpenMP Language Terminology | ||||||
11442 | // Structured block - An executable statement with a single entry at the | ||||||
11443 | // top and a single exit at the bottom. | ||||||
11444 | // The point of exit cannot be a branch out of the structured block. | ||||||
11445 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
11446 | CS->getCapturedDecl()->setNothrow(); | ||||||
11447 | } | ||||||
11448 | |||||||
11449 | OMPLoopDirective::HelperExprs B; | ||||||
11450 | // In presence of clause 'collapse' with number of loops, it will | ||||||
11451 | // define the nested loops number. | ||||||
11452 | unsigned NestedLoopCount = checkOpenMPLoop( | ||||||
11453 | OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), | ||||||
11454 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||
11455 | VarsWithImplicitDSA, B); | ||||||
11456 | if (NestedLoopCount == 0) | ||||||
11457 | return StmtError(); | ||||||
11458 | |||||||
11459 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11460, __PRETTY_FUNCTION__)) | ||||||
11460 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11460, __PRETTY_FUNCTION__)); | ||||||
11461 | |||||||
11462 | setFunctionHasBranchProtectedScope(); | ||||||
11463 | return OMPTargetTeamsDistributeDirective::Create( | ||||||
11464 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||||
11465 | } | ||||||
11466 | |||||||
11467 | StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( | ||||||
11468 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||
11469 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||
11470 | if (!AStmt) | ||||||
11471 | return StmtError(); | ||||||
11472 | |||||||
11473 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
11474 | // 1.2.2 OpenMP Language Terminology | ||||||
11475 | // Structured block - An executable statement with a single entry at the | ||||||
11476 | // top and a single exit at the bottom. | ||||||
11477 | // The point of exit cannot be a branch out of the structured block. | ||||||
11478 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
11479 | CS->getCapturedDecl()->setNothrow(); | ||||||
11480 | for (int ThisCaptureLevel = | ||||||
11481 | getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); | ||||||
11482 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||
11483 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||
11484 | // 1.2.2 OpenMP Language Terminology | ||||||
11485 | // Structured block - An executable statement with a single entry at the | ||||||
11486 | // top and a single exit at the bottom. | ||||||
11487 | // The point of exit cannot be a branch out of the structured block. | ||||||
11488 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
11489 | CS->getCapturedDecl()->setNothrow(); | ||||||
11490 | } | ||||||
11491 | |||||||
11492 | OMPLoopDirective::HelperExprs B; | ||||||
11493 | // In presence of clause 'collapse' with number of loops, it will | ||||||
11494 | // define the nested loops number. | ||||||
11495 | unsigned NestedLoopCount = checkOpenMPLoop( | ||||||
11496 | OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), | ||||||
11497 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||
11498 | VarsWithImplicitDSA, B); | ||||||
11499 | if (NestedLoopCount == 0) | ||||||
11500 | return StmtError(); | ||||||
11501 | |||||||
11502 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11503, __PRETTY_FUNCTION__)) | ||||||
11503 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11503, __PRETTY_FUNCTION__)); | ||||||
11504 | |||||||
11505 | if (!CurContext->isDependentContext()) { | ||||||
11506 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||
11507 | for (OMPClause *C : Clauses) { | ||||||
11508 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||
11509 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||
11510 | B.NumIterations, *this, CurScope, | ||||||
11511 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||
11512 | return StmtError(); | ||||||
11513 | } | ||||||
11514 | } | ||||||
11515 | |||||||
11516 | setFunctionHasBranchProtectedScope(); | ||||||
11517 | return OMPTargetTeamsDistributeParallelForDirective::Create( | ||||||
11518 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, | ||||||
11519 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); | ||||||
11520 | } | ||||||
11521 | |||||||
11522 | StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( | ||||||
11523 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||||
11524 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { | ||||||
11525 | if (!AStmt) | ||||||
11526 | return StmtError(); | ||||||
11527 | |||||||
11528 | auto *CS = cast<CapturedStmt>(AStmt); | ||||||
11529 | // 1.2.2 OpenMP Language Terminology | ||||||
11530 | // Structured block - An executable statement with a single entry at the | ||||||
11531 | // top and a single exit at the bottom. | ||||||
11532 | // The point of exit cannot be a branch out of the structured block. | ||||||
11533 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
11534 | CS->getCapturedDecl()->setNothrow(); | ||||||
11535 | for (int ThisCaptureLevel = getOpenMPCaptureLevels( | ||||||
11536 | OMPD_target_teams_distribute_parallel_for_simd); | ||||||
11537 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||||
11538 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||||
11539 | // 1.2.2 OpenMP Language Terminology | ||||||
11540 | // Structured block - An executable statement with a single entry at the | ||||||
11541 | // top and a single exit at the bottom. | ||||||
11542 | // The point of exit cannot be a branch out of the structured block. | ||||||
11543 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||||
11544 | CS->getCapturedDecl()->setNothrow(); | ||||||
11545 | } | ||||||
11546 | |||||||
11547 | OMPLoopDirective::HelperExprs B; | ||||||
11548 | // In presence of clause 'collapse' with number of loops, it will | ||||||
11549 | // define the nested loops number. | ||||||
11550 | unsigned NestedLoopCount = | ||||||
11551 | checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, | ||||||
11552 | getCollapseNumberExpr(Clauses), | ||||||
11553 | nullptr /*ordered not a clause on distribute*/, CS, *this, | ||||||
11554 | *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VarsWithImplicitDSA, B); | ||||||
11555 | if (NestedLoopCount == 0) | ||||||
11556 | return StmtError(); | ||||||
11557 | |||||||
11558 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11560, __PRETTY_FUNCTION__)) | ||||||
11559 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11560, __PRETTY_FUNCTION__)) | ||||||
11560 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11560, __PRETTY_FUNCTION__)); | ||||||
11561 | |||||||
11562 | if (!CurContext->isDependentContext()) { | ||||||
11563 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||
11564 | for (OMPClause *C : Clauses) { | ||||||
11565 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||
11566 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||
11567 | B.NumIterations, *this, CurScope, | ||||||
11568 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||
11569 | return StmtError(); | ||||||
11570 | } | ||||||
11571 | } | ||||||
11572 | |||||||
11573 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||
11574 | return StmtError(); | ||||||
11575 | |||||||
11576 | setFunctionHasBranchProtectedScope(); | ||||||
11577 | return OMPTargetTeamsDistributeParallelForSimdDirective::Create( | ||||||
11578 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||||
11579 | } | ||||||
11580 | |||||||
11581 | StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( | ||||||
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 = | ||||||
11595 | getOpenMPCaptureLevels(OMPD_target_teams_distribute_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 = checkOpenMPLoop( | ||||||
11610 | OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), | ||||||
11611 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||
11612 | VarsWithImplicitDSA, B); | ||||||
11613 | if (NestedLoopCount == 0) | ||||||
11614 | return StmtError(); | ||||||
11615 | |||||||
11616 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11617, __PRETTY_FUNCTION__)) | ||||||
11617 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11617, __PRETTY_FUNCTION__)); | ||||||
11618 | |||||||
11619 | if (!CurContext->isDependentContext()) { | ||||||
11620 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||||
11621 | for (OMPClause *C : Clauses) { | ||||||
11622 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||||
11623 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||||
11624 | B.NumIterations, *this, CurScope, | ||||||
11625 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||
11626 | return StmtError(); | ||||||
11627 | } | ||||||
11628 | } | ||||||
11629 | |||||||
11630 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||||
11631 | return StmtError(); | ||||||
11632 | |||||||
11633 | setFunctionHasBranchProtectedScope(); | ||||||
11634 | return OMPTargetTeamsDistributeSimdDirective::Create( | ||||||
11635 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||||
11636 | } | ||||||
11637 | |||||||
11638 | OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, | ||||||
11639 | SourceLocation StartLoc, | ||||||
11640 | SourceLocation LParenLoc, | ||||||
11641 | SourceLocation EndLoc) { | ||||||
11642 | OMPClause *Res = nullptr; | ||||||
11643 | switch (Kind) { | ||||||
11644 | case OMPC_final: | ||||||
11645 | Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||
11646 | break; | ||||||
11647 | case OMPC_num_threads: | ||||||
11648 | Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||
11649 | break; | ||||||
11650 | case OMPC_safelen: | ||||||
11651 | Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||
11652 | break; | ||||||
11653 | case OMPC_simdlen: | ||||||
11654 | Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||
11655 | break; | ||||||
11656 | case OMPC_allocator: | ||||||
11657 | Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||
11658 | break; | ||||||
11659 | case OMPC_collapse: | ||||||
11660 | Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||
11661 | break; | ||||||
11662 | case OMPC_ordered: | ||||||
11663 | Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); | ||||||
11664 | break; | ||||||
11665 | case OMPC_num_teams: | ||||||
11666 | Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||
11667 | break; | ||||||
11668 | case OMPC_thread_limit: | ||||||
11669 | Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||
11670 | break; | ||||||
11671 | case OMPC_priority: | ||||||
11672 | Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||
11673 | break; | ||||||
11674 | case OMPC_grainsize: | ||||||
11675 | Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||
11676 | break; | ||||||
11677 | case OMPC_num_tasks: | ||||||
11678 | Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||
11679 | break; | ||||||
11680 | case OMPC_hint: | ||||||
11681 | Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||
11682 | break; | ||||||
11683 | case OMPC_depobj: | ||||||
11684 | Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||
11685 | break; | ||||||
11686 | case OMPC_detach: | ||||||
11687 | Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||||
11688 | break; | ||||||
11689 | case OMPC_device: | ||||||
11690 | case OMPC_if: | ||||||
11691 | case OMPC_default: | ||||||
11692 | case OMPC_proc_bind: | ||||||
11693 | case OMPC_schedule: | ||||||
11694 | case OMPC_private: | ||||||
11695 | case OMPC_firstprivate: | ||||||
11696 | case OMPC_lastprivate: | ||||||
11697 | case OMPC_shared: | ||||||
11698 | case OMPC_reduction: | ||||||
11699 | case OMPC_task_reduction: | ||||||
11700 | case OMPC_in_reduction: | ||||||
11701 | case OMPC_linear: | ||||||
11702 | case OMPC_aligned: | ||||||
11703 | case OMPC_copyin: | ||||||
11704 | case OMPC_copyprivate: | ||||||
11705 | case OMPC_nowait: | ||||||
11706 | case OMPC_untied: | ||||||
11707 | case OMPC_mergeable: | ||||||
11708 | case OMPC_threadprivate: | ||||||
11709 | case OMPC_allocate: | ||||||
11710 | case OMPC_flush: | ||||||
11711 | case OMPC_read: | ||||||
11712 | case OMPC_write: | ||||||
11713 | case OMPC_update: | ||||||
11714 | case OMPC_capture: | ||||||
11715 | case OMPC_seq_cst: | ||||||
11716 | case OMPC_acq_rel: | ||||||
11717 | case OMPC_acquire: | ||||||
11718 | case OMPC_release: | ||||||
11719 | case OMPC_relaxed: | ||||||
11720 | case OMPC_depend: | ||||||
11721 | case OMPC_threads: | ||||||
11722 | case OMPC_simd: | ||||||
11723 | case OMPC_map: | ||||||
11724 | case OMPC_nogroup: | ||||||
11725 | case OMPC_dist_schedule: | ||||||
11726 | case OMPC_defaultmap: | ||||||
11727 | case OMPC_unknown: | ||||||
11728 | case OMPC_uniform: | ||||||
11729 | case OMPC_to: | ||||||
11730 | case OMPC_from: | ||||||
11731 | case OMPC_use_device_ptr: | ||||||
11732 | case OMPC_use_device_addr: | ||||||
11733 | case OMPC_is_device_ptr: | ||||||
11734 | case OMPC_unified_address: | ||||||
11735 | case OMPC_unified_shared_memory: | ||||||
11736 | case OMPC_reverse_offload: | ||||||
11737 | case OMPC_dynamic_allocators: | ||||||
11738 | case OMPC_atomic_default_mem_order: | ||||||
11739 | case OMPC_device_type: | ||||||
11740 | case OMPC_match: | ||||||
11741 | case OMPC_nontemporal: | ||||||
11742 | case OMPC_order: | ||||||
11743 | case OMPC_destroy: | ||||||
11744 | case OMPC_inclusive: | ||||||
11745 | case OMPC_exclusive: | ||||||
11746 | case OMPC_uses_allocators: | ||||||
11747 | case OMPC_affinity: | ||||||
11748 | default: | ||||||
11749 | llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11749); | ||||||
11750 | } | ||||||
11751 | return Res; | ||||||
11752 | } | ||||||
11753 | |||||||
11754 | // An OpenMP directive such as 'target parallel' has two captured regions: | ||||||
11755 | // for the 'target' and 'parallel' respectively. This function returns | ||||||
11756 | // the region in which to capture expressions associated with a clause. | ||||||
11757 | // A return value of OMPD_unknown signifies that the expression should not | ||||||
11758 | // be captured. | ||||||
11759 | static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( | ||||||
11760 | OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, | ||||||
11761 | OpenMPDirectiveKind NameModifier = OMPD_unknown) { | ||||||
11762 | OpenMPDirectiveKind CaptureRegion = OMPD_unknown; | ||||||
11763 | switch (CKind) { | ||||||
11764 | case OMPC_if: | ||||||
11765 | switch (DKind) { | ||||||
11766 | case OMPD_target_parallel_for_simd: | ||||||
11767 | if (OpenMPVersion >= 50 && | ||||||
11768 | (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { | ||||||
11769 | CaptureRegion = OMPD_parallel; | ||||||
11770 | break; | ||||||
11771 | } | ||||||
11772 | LLVM_FALLTHROUGH[[gnu::fallthrough]]; | ||||||
11773 | case OMPD_target_parallel: | ||||||
11774 | case OMPD_target_parallel_for: | ||||||
11775 | // If this clause applies to the nested 'parallel' region, capture within | ||||||
11776 | // the 'target' region, otherwise do not capture. | ||||||
11777 | if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) | ||||||
11778 | CaptureRegion = OMPD_target; | ||||||
11779 | break; | ||||||
11780 | case OMPD_target_teams_distribute_parallel_for_simd: | ||||||
11781 | if (OpenMPVersion >= 50 && | ||||||
11782 | (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { | ||||||
11783 | CaptureRegion = OMPD_parallel; | ||||||
11784 | break; | ||||||
11785 | } | ||||||
11786 | LLVM_FALLTHROUGH[[gnu::fallthrough]]; | ||||||
11787 | case OMPD_target_teams_distribute_parallel_for: | ||||||
11788 | // If this clause applies to the nested 'parallel' region, capture within | ||||||
11789 | // the 'teams' region, otherwise do not capture. | ||||||
11790 | if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) | ||||||
11791 | CaptureRegion = OMPD_teams; | ||||||
11792 | break; | ||||||
11793 | case OMPD_teams_distribute_parallel_for_simd: | ||||||
11794 | if (OpenMPVersion >= 50 && | ||||||
11795 | (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { | ||||||
11796 | CaptureRegion = OMPD_parallel; | ||||||
11797 | break; | ||||||
11798 | } | ||||||
11799 | LLVM_FALLTHROUGH[[gnu::fallthrough]]; | ||||||
11800 | case OMPD_teams_distribute_parallel_for: | ||||||
11801 | CaptureRegion = OMPD_teams; | ||||||
11802 | break; | ||||||
11803 | case OMPD_target_update: | ||||||
11804 | case OMPD_target_enter_data: | ||||||
11805 | case OMPD_target_exit_data: | ||||||
11806 | CaptureRegion = OMPD_task; | ||||||
11807 | break; | ||||||
11808 | case OMPD_parallel_master_taskloop: | ||||||
11809 | if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) | ||||||
11810 | CaptureRegion = OMPD_parallel; | ||||||
11811 | break; | ||||||
11812 | case OMPD_parallel_master_taskloop_simd: | ||||||
11813 | if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || | ||||||
11814 | NameModifier == OMPD_taskloop) { | ||||||
11815 | CaptureRegion = OMPD_parallel; | ||||||
11816 | break; | ||||||
11817 | } | ||||||
11818 | if (OpenMPVersion <= 45) | ||||||
11819 | break; | ||||||
11820 | if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) | ||||||
11821 | CaptureRegion = OMPD_taskloop; | ||||||
11822 | break; | ||||||
11823 | case OMPD_parallel_for_simd: | ||||||
11824 | if (OpenMPVersion <= 45) | ||||||
11825 | break; | ||||||
11826 | if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) | ||||||
11827 | CaptureRegion = OMPD_parallel; | ||||||
11828 | break; | ||||||
11829 | case OMPD_taskloop_simd: | ||||||
11830 | case OMPD_master_taskloop_simd: | ||||||
11831 | if (OpenMPVersion <= 45) | ||||||
11832 | break; | ||||||
11833 | if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) | ||||||
11834 | CaptureRegion = OMPD_taskloop; | ||||||
11835 | break; | ||||||
11836 | case OMPD_distribute_parallel_for_simd: | ||||||
11837 | if (OpenMPVersion <= 45) | ||||||
11838 | break; | ||||||
11839 | if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) | ||||||
11840 | CaptureRegion = OMPD_parallel; | ||||||
11841 | break; | ||||||
11842 | case OMPD_target_simd: | ||||||
11843 | if (OpenMPVersion >= 50 && | ||||||
11844 | (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) | ||||||
11845 | CaptureRegion = OMPD_target; | ||||||
11846 | break; | ||||||
11847 | case OMPD_teams_distribute_simd: | ||||||
11848 | case OMPD_target_teams_distribute_simd: | ||||||
11849 | if (OpenMPVersion >= 50 && | ||||||
11850 | (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) | ||||||
11851 | CaptureRegion = OMPD_teams; | ||||||
11852 | break; | ||||||
11853 | case OMPD_cancel: | ||||||
11854 | case OMPD_parallel: | ||||||
11855 | case OMPD_parallel_master: | ||||||
11856 | case OMPD_parallel_sections: | ||||||
11857 | case OMPD_parallel_for: | ||||||
11858 | case OMPD_target: | ||||||
11859 | case OMPD_target_teams: | ||||||
11860 | case OMPD_target_teams_distribute: | ||||||
11861 | case OMPD_distribute_parallel_for: | ||||||
11862 | case OMPD_task: | ||||||
11863 | case OMPD_taskloop: | ||||||
11864 | case OMPD_master_taskloop: | ||||||
11865 | case OMPD_target_data: | ||||||
11866 | case OMPD_simd: | ||||||
11867 | case OMPD_for_simd: | ||||||
11868 | case OMPD_distribute_simd: | ||||||
11869 | // Do not capture if-clause expressions. | ||||||
11870 | break; | ||||||
11871 | case OMPD_threadprivate: | ||||||
11872 | case OMPD_allocate: | ||||||
11873 | case OMPD_taskyield: | ||||||
11874 | case OMPD_barrier: | ||||||
11875 | case OMPD_taskwait: | ||||||
11876 | case OMPD_cancellation_point: | ||||||
11877 | case OMPD_flush: | ||||||
11878 | case OMPD_depobj: | ||||||
11879 | case OMPD_scan: | ||||||
11880 | case OMPD_declare_reduction: | ||||||
11881 | case OMPD_declare_mapper: | ||||||
11882 | case OMPD_declare_simd: | ||||||
11883 | case OMPD_declare_variant: | ||||||
11884 | case OMPD_begin_declare_variant: | ||||||
11885 | case OMPD_end_declare_variant: | ||||||
11886 | case OMPD_declare_target: | ||||||
11887 | case OMPD_end_declare_target: | ||||||
11888 | case OMPD_teams: | ||||||
11889 | case OMPD_for: | ||||||
11890 | case OMPD_sections: | ||||||
11891 | case OMPD_section: | ||||||
11892 | case OMPD_single: | ||||||
11893 | case OMPD_master: | ||||||
11894 | case OMPD_critical: | ||||||
11895 | case OMPD_taskgroup: | ||||||
11896 | case OMPD_distribute: | ||||||
11897 | case OMPD_ordered: | ||||||
11898 | case OMPD_atomic: | ||||||
11899 | case OMPD_teams_distribute: | ||||||
11900 | case OMPD_requires: | ||||||
11901 | llvm_unreachable("Unexpected OpenMP directive with if-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with if-clause" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11901); | ||||||
11902 | case OMPD_unknown: | ||||||
11903 | default: | ||||||
11904 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11904); | ||||||
11905 | } | ||||||
11906 | break; | ||||||
11907 | case OMPC_num_threads: | ||||||
11908 | switch (DKind) { | ||||||
11909 | case OMPD_target_parallel: | ||||||
11910 | case OMPD_target_parallel_for: | ||||||
11911 | case OMPD_target_parallel_for_simd: | ||||||
11912 | CaptureRegion = OMPD_target; | ||||||
11913 | break; | ||||||
11914 | case OMPD_teams_distribute_parallel_for: | ||||||
11915 | case OMPD_teams_distribute_parallel_for_simd: | ||||||
11916 | case OMPD_target_teams_distribute_parallel_for: | ||||||
11917 | case OMPD_target_teams_distribute_parallel_for_simd: | ||||||
11918 | CaptureRegion = OMPD_teams; | ||||||
11919 | break; | ||||||
11920 | case OMPD_parallel: | ||||||
11921 | case OMPD_parallel_master: | ||||||
11922 | case OMPD_parallel_sections: | ||||||
11923 | case OMPD_parallel_for: | ||||||
11924 | case OMPD_parallel_for_simd: | ||||||
11925 | case OMPD_distribute_parallel_for: | ||||||
11926 | case OMPD_distribute_parallel_for_simd: | ||||||
11927 | case OMPD_parallel_master_taskloop: | ||||||
11928 | case OMPD_parallel_master_taskloop_simd: | ||||||
11929 | // Do not capture num_threads-clause expressions. | ||||||
11930 | break; | ||||||
11931 | case OMPD_target_data: | ||||||
11932 | case OMPD_target_enter_data: | ||||||
11933 | case OMPD_target_exit_data: | ||||||
11934 | case OMPD_target_update: | ||||||
11935 | case OMPD_target: | ||||||
11936 | case OMPD_target_simd: | ||||||
11937 | case OMPD_target_teams: | ||||||
11938 | case OMPD_target_teams_distribute: | ||||||
11939 | case OMPD_target_teams_distribute_simd: | ||||||
11940 | case OMPD_cancel: | ||||||
11941 | case OMPD_task: | ||||||
11942 | case OMPD_taskloop: | ||||||
11943 | case OMPD_taskloop_simd: | ||||||
11944 | case OMPD_master_taskloop: | ||||||
11945 | case OMPD_master_taskloop_simd: | ||||||
11946 | case OMPD_threadprivate: | ||||||
11947 | case OMPD_allocate: | ||||||
11948 | case OMPD_taskyield: | ||||||
11949 | case OMPD_barrier: | ||||||
11950 | case OMPD_taskwait: | ||||||
11951 | case OMPD_cancellation_point: | ||||||
11952 | case OMPD_flush: | ||||||
11953 | case OMPD_depobj: | ||||||
11954 | case OMPD_scan: | ||||||
11955 | case OMPD_declare_reduction: | ||||||
11956 | case OMPD_declare_mapper: | ||||||
11957 | case OMPD_declare_simd: | ||||||
11958 | case OMPD_declare_variant: | ||||||
11959 | case OMPD_begin_declare_variant: | ||||||
11960 | case OMPD_end_declare_variant: | ||||||
11961 | case OMPD_declare_target: | ||||||
11962 | case OMPD_end_declare_target: | ||||||
11963 | case OMPD_teams: | ||||||
11964 | case OMPD_simd: | ||||||
11965 | case OMPD_for: | ||||||
11966 | case OMPD_for_simd: | ||||||
11967 | case OMPD_sections: | ||||||
11968 | case OMPD_section: | ||||||
11969 | case OMPD_single: | ||||||
11970 | case OMPD_master: | ||||||
11971 | case OMPD_critical: | ||||||
11972 | case OMPD_taskgroup: | ||||||
11973 | case OMPD_distribute: | ||||||
11974 | case OMPD_ordered: | ||||||
11975 | case OMPD_atomic: | ||||||
11976 | case OMPD_distribute_simd: | ||||||
11977 | case OMPD_teams_distribute: | ||||||
11978 | case OMPD_teams_distribute_simd: | ||||||
11979 | case OMPD_requires: | ||||||
11980 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11980); | ||||||
11981 | case OMPD_unknown: | ||||||
11982 | default: | ||||||
11983 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11983); | ||||||
11984 | } | ||||||
11985 | break; | ||||||
11986 | case OMPC_num_teams: | ||||||
11987 | switch (DKind) { | ||||||
11988 | case OMPD_target_teams: | ||||||
11989 | case OMPD_target_teams_distribute: | ||||||
11990 | case OMPD_target_teams_distribute_simd: | ||||||
11991 | case OMPD_target_teams_distribute_parallel_for: | ||||||
11992 | case OMPD_target_teams_distribute_parallel_for_simd: | ||||||
11993 | CaptureRegion = OMPD_target; | ||||||
11994 | break; | ||||||
11995 | case OMPD_teams_distribute_parallel_for: | ||||||
11996 | case OMPD_teams_distribute_parallel_for_simd: | ||||||
11997 | case OMPD_teams: | ||||||
11998 | case OMPD_teams_distribute: | ||||||
11999 | case OMPD_teams_distribute_simd: | ||||||
12000 | // Do not capture num_teams-clause expressions. | ||||||
12001 | break; | ||||||
12002 | case OMPD_distribute_parallel_for: | ||||||
12003 | case OMPD_distribute_parallel_for_simd: | ||||||
12004 | case OMPD_task: | ||||||
12005 | case OMPD_taskloop: | ||||||
12006 | case OMPD_taskloop_simd: | ||||||
12007 | case OMPD_master_taskloop: | ||||||
12008 | case OMPD_master_taskloop_simd: | ||||||
12009 | case OMPD_parallel_master_taskloop: | ||||||
12010 | case OMPD_parallel_master_taskloop_simd: | ||||||
12011 | case OMPD_target_data: | ||||||
12012 | case OMPD_target_enter_data: | ||||||
12013 | case OMPD_target_exit_data: | ||||||
12014 | case OMPD_target_update: | ||||||
12015 | case OMPD_cancel: | ||||||
12016 | case OMPD_parallel: | ||||||
12017 | case OMPD_parallel_master: | ||||||
12018 | case OMPD_parallel_sections: | ||||||
12019 | case OMPD_parallel_for: | ||||||
12020 | case OMPD_parallel_for_simd: | ||||||
12021 | case OMPD_target: | ||||||
12022 | case OMPD_target_simd: | ||||||
12023 | case OMPD_target_parallel: | ||||||
12024 | case OMPD_target_parallel_for: | ||||||
12025 | case OMPD_target_parallel_for_simd: | ||||||
12026 | case OMPD_threadprivate: | ||||||
12027 | case OMPD_allocate: | ||||||
12028 | case OMPD_taskyield: | ||||||
12029 | case OMPD_barrier: | ||||||
12030 | case OMPD_taskwait: | ||||||
12031 | case OMPD_cancellation_point: | ||||||
12032 | case OMPD_flush: | ||||||
12033 | case OMPD_depobj: | ||||||
12034 | case OMPD_scan: | ||||||
12035 | case OMPD_declare_reduction: | ||||||
12036 | case OMPD_declare_mapper: | ||||||
12037 | case OMPD_declare_simd: | ||||||
12038 | case OMPD_declare_variant: | ||||||
12039 | case OMPD_begin_declare_variant: | ||||||
12040 | case OMPD_end_declare_variant: | ||||||
12041 | case OMPD_declare_target: | ||||||
12042 | case OMPD_end_declare_target: | ||||||
12043 | case OMPD_simd: | ||||||
12044 | case OMPD_for: | ||||||
12045 | case OMPD_for_simd: | ||||||
12046 | case OMPD_sections: | ||||||
12047 | case OMPD_section: | ||||||
12048 | case OMPD_single: | ||||||
12049 | case OMPD_master: | ||||||
12050 | case OMPD_critical: | ||||||
12051 | case OMPD_taskgroup: | ||||||
12052 | case OMPD_distribute: | ||||||
12053 | case OMPD_ordered: | ||||||
12054 | case OMPD_atomic: | ||||||
12055 | case OMPD_distribute_simd: | ||||||
12056 | case OMPD_requires: | ||||||
12057 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12057); | ||||||
12058 | case OMPD_unknown: | ||||||
12059 | default: | ||||||
12060 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12060); | ||||||
12061 | } | ||||||
12062 | break; | ||||||
12063 | case OMPC_thread_limit: | ||||||
12064 | switch (DKind) { | ||||||
12065 | case OMPD_target_teams: | ||||||
12066 | case OMPD_target_teams_distribute: | ||||||
12067 | case OMPD_target_teams_distribute_simd: | ||||||
12068 | case OMPD_target_teams_distribute_parallel_for: | ||||||
12069 | case OMPD_target_teams_distribute_parallel_for_simd: | ||||||
12070 | CaptureRegion = OMPD_target; | ||||||
12071 | break; | ||||||
12072 | case OMPD_teams_distribute_parallel_for: | ||||||
12073 | case OMPD_teams_distribute_parallel_for_simd: | ||||||
12074 | case OMPD_teams: | ||||||
12075 | case OMPD_teams_distribute: | ||||||
12076 | case OMPD_teams_distribute_simd: | ||||||
12077 | // Do not capture thread_limit-clause expressions. | ||||||
12078 | break; | ||||||
12079 | case OMPD_distribute_parallel_for: | ||||||
12080 | case OMPD_distribute_parallel_for_simd: | ||||||
12081 | case OMPD_task: | ||||||
12082 | case OMPD_taskloop: | ||||||
12083 | case OMPD_taskloop_simd: | ||||||
12084 | case OMPD_master_taskloop: | ||||||
12085 | case OMPD_master_taskloop_simd: | ||||||
12086 | case OMPD_parallel_master_taskloop: | ||||||
12087 | case OMPD_parallel_master_taskloop_simd: | ||||||
12088 | case OMPD_target_data: | ||||||
12089 | case OMPD_target_enter_data: | ||||||
12090 | case OMPD_target_exit_data: | ||||||
12091 | case OMPD_target_update: | ||||||
12092 | case OMPD_cancel: | ||||||
12093 | case OMPD_parallel: | ||||||
12094 | case OMPD_parallel_master: | ||||||
12095 | case OMPD_parallel_sections: | ||||||
12096 | case OMPD_parallel_for: | ||||||
12097 | case OMPD_parallel_for_simd: | ||||||
12098 | case OMPD_target: | ||||||
12099 | case OMPD_target_simd: | ||||||
12100 | case OMPD_target_parallel: | ||||||
12101 | case OMPD_target_parallel_for: | ||||||
12102 | case OMPD_target_parallel_for_simd: | ||||||
12103 | case OMPD_threadprivate: | ||||||
12104 | case OMPD_allocate: | ||||||
12105 | case OMPD_taskyield: | ||||||
12106 | case OMPD_barrier: | ||||||
12107 | case OMPD_taskwait: | ||||||
12108 | case OMPD_cancellation_point: | ||||||
12109 | case OMPD_flush: | ||||||
12110 | case OMPD_depobj: | ||||||
12111 | case OMPD_scan: | ||||||
12112 | case OMPD_declare_reduction: | ||||||
12113 | case OMPD_declare_mapper: | ||||||
12114 | case OMPD_declare_simd: | ||||||
12115 | case OMPD_declare_variant: | ||||||
12116 | case OMPD_begin_declare_variant: | ||||||
12117 | case OMPD_end_declare_variant: | ||||||
12118 | case OMPD_declare_target: | ||||||
12119 | case OMPD_end_declare_target: | ||||||
12120 | case OMPD_simd: | ||||||
12121 | case OMPD_for: | ||||||
12122 | case OMPD_for_simd: | ||||||
12123 | case OMPD_sections: | ||||||
12124 | case OMPD_section: | ||||||
12125 | case OMPD_single: | ||||||
12126 | case OMPD_master: | ||||||
12127 | case OMPD_critical: | ||||||
12128 | case OMPD_taskgroup: | ||||||
12129 | case OMPD_distribute: | ||||||
12130 | case OMPD_ordered: | ||||||
12131 | case OMPD_atomic: | ||||||
12132 | case OMPD_distribute_simd: | ||||||
12133 | case OMPD_requires: | ||||||
12134 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12134); | ||||||
12135 | case OMPD_unknown: | ||||||
12136 | default: | ||||||
12137 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12137); | ||||||
12138 | } | ||||||
12139 | break; | ||||||
12140 | case OMPC_schedule: | ||||||
12141 | switch (DKind) { | ||||||
12142 | case OMPD_parallel_for: | ||||||
12143 | case OMPD_parallel_for_simd: | ||||||
12144 | case OMPD_distribute_parallel_for: | ||||||
12145 | case OMPD_distribute_parallel_for_simd: | ||||||
12146 | case OMPD_teams_distribute_parallel_for: | ||||||
12147 | case OMPD_teams_distribute_parallel_for_simd: | ||||||
12148 | case OMPD_target_parallel_for: | ||||||
12149 | case OMPD_target_parallel_for_simd: | ||||||
12150 | case OMPD_target_teams_distribute_parallel_for: | ||||||
12151 | case OMPD_target_teams_distribute_parallel_for_simd: | ||||||
12152 | CaptureRegion = OMPD_parallel; | ||||||
12153 | break; | ||||||
12154 | case OMPD_for: | ||||||
12155 | case OMPD_for_simd: | ||||||
12156 | // Do not capture schedule-clause expressions. | ||||||
12157 | break; | ||||||
12158 | case OMPD_task: | ||||||
12159 | case OMPD_taskloop: | ||||||
12160 | case OMPD_taskloop_simd: | ||||||
12161 | case OMPD_master_taskloop: | ||||||
12162 | case OMPD_master_taskloop_simd: | ||||||
12163 | case OMPD_parallel_master_taskloop: | ||||||
12164 | case OMPD_parallel_master_taskloop_simd: | ||||||
12165 | case OMPD_target_data: | ||||||
12166 | case OMPD_target_enter_data: | ||||||
12167 | case OMPD_target_exit_data: | ||||||
12168 | case OMPD_target_update: | ||||||
12169 | case OMPD_teams: | ||||||
12170 | case OMPD_teams_distribute: | ||||||
12171 | case OMPD_teams_distribute_simd: | ||||||
12172 | case OMPD_target_teams_distribute: | ||||||
12173 | case OMPD_target_teams_distribute_simd: | ||||||
12174 | case OMPD_target: | ||||||
12175 | case OMPD_target_simd: | ||||||
12176 | case OMPD_target_parallel: | ||||||
12177 | case OMPD_cancel: | ||||||
12178 | case OMPD_parallel: | ||||||
12179 | case OMPD_parallel_master: | ||||||
12180 | case OMPD_parallel_sections: | ||||||
12181 | case OMPD_threadprivate: | ||||||
12182 | case OMPD_allocate: | ||||||
12183 | case OMPD_taskyield: | ||||||
12184 | case OMPD_barrier: | ||||||
12185 | case OMPD_taskwait: | ||||||
12186 | case OMPD_cancellation_point: | ||||||
12187 | case OMPD_flush: | ||||||
12188 | case OMPD_depobj: | ||||||
12189 | case OMPD_scan: | ||||||
12190 | case OMPD_declare_reduction: | ||||||
12191 | case OMPD_declare_mapper: | ||||||
12192 | case OMPD_declare_simd: | ||||||
12193 | case OMPD_declare_variant: | ||||||
12194 | case OMPD_begin_declare_variant: | ||||||
12195 | case OMPD_end_declare_variant: | ||||||
12196 | case OMPD_declare_target: | ||||||
12197 | case OMPD_end_declare_target: | ||||||
12198 | case OMPD_simd: | ||||||
12199 | case OMPD_sections: | ||||||
12200 | case OMPD_section: | ||||||
12201 | case OMPD_single: | ||||||
12202 | case OMPD_master: | ||||||
12203 | case OMPD_critical: | ||||||
12204 | case OMPD_taskgroup: | ||||||
12205 | case OMPD_distribute: | ||||||
12206 | case OMPD_ordered: | ||||||
12207 | case OMPD_atomic: | ||||||
12208 | case OMPD_distribute_simd: | ||||||
12209 | case OMPD_target_teams: | ||||||
12210 | case OMPD_requires: | ||||||
12211 | llvm_unreachable("Unexpected OpenMP directive with schedule clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with schedule clause" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12211); | ||||||
12212 | case OMPD_unknown: | ||||||
12213 | default: | ||||||
12214 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12214); | ||||||
12215 | } | ||||||
12216 | break; | ||||||
12217 | case OMPC_dist_schedule: | ||||||
12218 | switch (DKind) { | ||||||
12219 | case OMPD_teams_distribute_parallel_for: | ||||||
12220 | case OMPD_teams_distribute_parallel_for_simd: | ||||||
12221 | case OMPD_teams_distribute: | ||||||
12222 | case OMPD_teams_distribute_simd: | ||||||
12223 | case OMPD_target_teams_distribute_parallel_for: | ||||||
12224 | case OMPD_target_teams_distribute_parallel_for_simd: | ||||||
12225 | case OMPD_target_teams_distribute: | ||||||
12226 | case OMPD_target_teams_distribute_simd: | ||||||
12227 | CaptureRegion = OMPD_teams; | ||||||
12228 | break; | ||||||
12229 | case OMPD_distribute_parallel_for: | ||||||
12230 | case OMPD_distribute_parallel_for_simd: | ||||||
12231 | case OMPD_distribute: | ||||||
12232 | case OMPD_distribute_simd: | ||||||
12233 | // Do not capture thread_limit-clause expressions. | ||||||
12234 | break; | ||||||
12235 | case OMPD_parallel_for: | ||||||
12236 | case OMPD_parallel_for_simd: | ||||||
12237 | case OMPD_target_parallel_for_simd: | ||||||
12238 | case OMPD_target_parallel_for: | ||||||
12239 | case OMPD_task: | ||||||
12240 | case OMPD_taskloop: | ||||||
12241 | case OMPD_taskloop_simd: | ||||||
12242 | case OMPD_master_taskloop: | ||||||
12243 | case OMPD_master_taskloop_simd: | ||||||
12244 | case OMPD_parallel_master_taskloop: | ||||||
12245 | case OMPD_parallel_master_taskloop_simd: | ||||||
12246 | case OMPD_target_data: | ||||||
12247 | case OMPD_target_enter_data: | ||||||
12248 | case OMPD_target_exit_data: | ||||||
12249 | case OMPD_target_update: | ||||||
12250 | case OMPD_teams: | ||||||
12251 | case OMPD_target: | ||||||
12252 | case OMPD_target_simd: | ||||||
12253 | case OMPD_target_parallel: | ||||||
12254 | case OMPD_cancel: | ||||||
12255 | case OMPD_parallel: | ||||||
12256 | case OMPD_parallel_master: | ||||||
12257 | case OMPD_parallel_sections: | ||||||
12258 | case OMPD_threadprivate: | ||||||
12259 | case OMPD_allocate: | ||||||
12260 | case OMPD_taskyield: | ||||||
12261 | case OMPD_barrier: | ||||||
12262 | case OMPD_taskwait: | ||||||
12263 | case OMPD_cancellation_point: | ||||||
12264 | case OMPD_flush: | ||||||
12265 | case OMPD_depobj: | ||||||
12266 | case OMPD_scan: | ||||||
12267 | case OMPD_declare_reduction: | ||||||
12268 | case OMPD_declare_mapper: | ||||||
12269 | case OMPD_declare_simd: | ||||||
12270 | case OMPD_declare_variant: | ||||||
12271 | case OMPD_begin_declare_variant: | ||||||
12272 | case OMPD_end_declare_variant: | ||||||
12273 | case OMPD_declare_target: | ||||||
12274 | case OMPD_end_declare_target: | ||||||
12275 | case OMPD_simd: | ||||||
12276 | case OMPD_for: | ||||||
12277 | case OMPD_for_simd: | ||||||
12278 | case OMPD_sections: | ||||||
12279 | case OMPD_section: | ||||||
12280 | case OMPD_single: | ||||||
12281 | case OMPD_master: | ||||||
12282 | case OMPD_critical: | ||||||
12283 | case OMPD_taskgroup: | ||||||
12284 | case OMPD_ordered: | ||||||
12285 | case OMPD_atomic: | ||||||
12286 | case OMPD_target_teams: | ||||||
12287 | case OMPD_requires: | ||||||
12288 | llvm_unreachable("Unexpected OpenMP directive with schedule clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with schedule clause" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12288); | ||||||
12289 | case OMPD_unknown: | ||||||
12290 | default: | ||||||
12291 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12291); | ||||||
12292 | } | ||||||
12293 | break; | ||||||
12294 | case OMPC_device: | ||||||
12295 | switch (DKind) { | ||||||
12296 | case OMPD_target_update: | ||||||
12297 | case OMPD_target_enter_data: | ||||||
12298 | case OMPD_target_exit_data: | ||||||
12299 | case OMPD_target: | ||||||
12300 | case OMPD_target_simd: | ||||||
12301 | case OMPD_target_teams: | ||||||
12302 | case OMPD_target_parallel: | ||||||
12303 | case OMPD_target_teams_distribute: | ||||||
12304 | case OMPD_target_teams_distribute_simd: | ||||||
12305 | case OMPD_target_parallel_for: | ||||||
12306 | case OMPD_target_parallel_for_simd: | ||||||
12307 | case OMPD_target_teams_distribute_parallel_for: | ||||||
12308 | case OMPD_target_teams_distribute_parallel_for_simd: | ||||||
12309 | CaptureRegion = OMPD_task; | ||||||
12310 | break; | ||||||
12311 | case OMPD_target_data: | ||||||
12312 | // Do not capture device-clause expressions. | ||||||
12313 | break; | ||||||
12314 | case OMPD_teams_distribute_parallel_for: | ||||||
12315 | case OMPD_teams_distribute_parallel_for_simd: | ||||||
12316 | case OMPD_teams: | ||||||
12317 | case OMPD_teams_distribute: | ||||||
12318 | case OMPD_teams_distribute_simd: | ||||||
12319 | case OMPD_distribute_parallel_for: | ||||||
12320 | case OMPD_distribute_parallel_for_simd: | ||||||
12321 | case OMPD_task: | ||||||
12322 | case OMPD_taskloop: | ||||||
12323 | case OMPD_taskloop_simd: | ||||||
12324 | case OMPD_master_taskloop: | ||||||
12325 | case OMPD_master_taskloop_simd: | ||||||
12326 | case OMPD_parallel_master_taskloop: | ||||||
12327 | case OMPD_parallel_master_taskloop_simd: | ||||||
12328 | case OMPD_cancel: | ||||||
12329 | case OMPD_parallel: | ||||||
12330 | case OMPD_parallel_master: | ||||||
12331 | case OMPD_parallel_sections: | ||||||
12332 | case OMPD_parallel_for: | ||||||
12333 | case OMPD_parallel_for_simd: | ||||||
12334 | case OMPD_threadprivate: | ||||||
12335 | case OMPD_allocate: | ||||||
12336 | case OMPD_taskyield: | ||||||
12337 | case OMPD_barrier: | ||||||
12338 | case OMPD_taskwait: | ||||||
12339 | case OMPD_cancellation_point: | ||||||
12340 | case OMPD_flush: | ||||||
12341 | case OMPD_depobj: | ||||||
12342 | case OMPD_scan: | ||||||
12343 | case OMPD_declare_reduction: | ||||||
12344 | case OMPD_declare_mapper: | ||||||
12345 | case OMPD_declare_simd: | ||||||
12346 | case OMPD_declare_variant: | ||||||
12347 | case OMPD_begin_declare_variant: | ||||||
12348 | case OMPD_end_declare_variant: | ||||||
12349 | case OMPD_declare_target: | ||||||
12350 | case OMPD_end_declare_target: | ||||||
12351 | case OMPD_simd: | ||||||
12352 | case OMPD_for: | ||||||
12353 | case OMPD_for_simd: | ||||||
12354 | case OMPD_sections: | ||||||
12355 | case OMPD_section: | ||||||
12356 | case OMPD_single: | ||||||
12357 | case OMPD_master: | ||||||
12358 | case OMPD_critical: | ||||||
12359 | case OMPD_taskgroup: | ||||||
12360 | case OMPD_distribute: | ||||||
12361 | case OMPD_ordered: | ||||||
12362 | case OMPD_atomic: | ||||||
12363 | case OMPD_distribute_simd: | ||||||
12364 | case OMPD_requires: | ||||||
12365 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12365); | ||||||
12366 | case OMPD_unknown: | ||||||
12367 | default: | ||||||
12368 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12368); | ||||||
12369 | } | ||||||
12370 | break; | ||||||
12371 | case OMPC_grainsize: | ||||||
12372 | case OMPC_num_tasks: | ||||||
12373 | case OMPC_final: | ||||||
12374 | case OMPC_priority: | ||||||
12375 | switch (DKind) { | ||||||
12376 | case OMPD_task: | ||||||
12377 | case OMPD_taskloop: | ||||||
12378 | case OMPD_taskloop_simd: | ||||||
12379 | case OMPD_master_taskloop: | ||||||
12380 | case OMPD_master_taskloop_simd: | ||||||
12381 | break; | ||||||
12382 | case OMPD_parallel_master_taskloop: | ||||||
12383 | case OMPD_parallel_master_taskloop_simd: | ||||||
12384 | CaptureRegion = OMPD_parallel; | ||||||
12385 | break; | ||||||
12386 | case OMPD_target_update: | ||||||
12387 | case OMPD_target_enter_data: | ||||||
12388 | case OMPD_target_exit_data: | ||||||
12389 | case OMPD_target: | ||||||
12390 | case OMPD_target_simd: | ||||||
12391 | case OMPD_target_teams: | ||||||
12392 | case OMPD_target_parallel: | ||||||
12393 | case OMPD_target_teams_distribute: | ||||||
12394 | case OMPD_target_teams_distribute_simd: | ||||||
12395 | case OMPD_target_parallel_for: | ||||||
12396 | case OMPD_target_parallel_for_simd: | ||||||
12397 | case OMPD_target_teams_distribute_parallel_for: | ||||||
12398 | case OMPD_target_teams_distribute_parallel_for_simd: | ||||||
12399 | case OMPD_target_data: | ||||||
12400 | case OMPD_teams_distribute_parallel_for: | ||||||
12401 | case OMPD_teams_distribute_parallel_for_simd: | ||||||
12402 | case OMPD_teams: | ||||||
12403 | case OMPD_teams_distribute: | ||||||
12404 | case OMPD_teams_distribute_simd: | ||||||
12405 | case OMPD_distribute_parallel_for: | ||||||
12406 | case OMPD_distribute_parallel_for_simd: | ||||||
12407 | case OMPD_cancel: | ||||||
12408 | case OMPD_parallel: | ||||||
12409 | case OMPD_parallel_master: | ||||||
12410 | case OMPD_parallel_sections: | ||||||
12411 | case OMPD_parallel_for: | ||||||
12412 | case OMPD_parallel_for_simd: | ||||||
12413 | case OMPD_threadprivate: | ||||||
12414 | case OMPD_allocate: | ||||||
12415 | case OMPD_taskyield: | ||||||
12416 | case OMPD_barrier: | ||||||
12417 | case OMPD_taskwait: | ||||||
12418 | case OMPD_cancellation_point: | ||||||
12419 | case OMPD_flush: | ||||||
12420 | case OMPD_depobj: | ||||||
12421 | case OMPD_scan: | ||||||
12422 | case OMPD_declare_reduction: | ||||||
12423 | case OMPD_declare_mapper: | ||||||
12424 | case OMPD_declare_simd: | ||||||
12425 | case OMPD_declare_variant: | ||||||
12426 | case OMPD_begin_declare_variant: | ||||||
12427 | case OMPD_end_declare_variant: | ||||||
12428 | case OMPD_declare_target: | ||||||
12429 | case OMPD_end_declare_target: | ||||||
12430 | case OMPD_simd: | ||||||
12431 | case OMPD_for: | ||||||
12432 | case OMPD_for_simd: | ||||||
12433 | case OMPD_sections: | ||||||
12434 | case OMPD_section: | ||||||
12435 | case OMPD_single: | ||||||
12436 | case OMPD_master: | ||||||
12437 | case OMPD_critical: | ||||||
12438 | case OMPD_taskgroup: | ||||||
12439 | case OMPD_distribute: | ||||||
12440 | case OMPD_ordered: | ||||||
12441 | case OMPD_atomic: | ||||||
12442 | case OMPD_distribute_simd: | ||||||
12443 | case OMPD_requires: | ||||||
12444 | llvm_unreachable("Unexpected OpenMP directive with grainsize-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with grainsize-clause" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12444); | ||||||
12445 | case OMPD_unknown: | ||||||
12446 | default: | ||||||
12447 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12447); | ||||||
12448 | } | ||||||
12449 | break; | ||||||
12450 | case OMPC_firstprivate: | ||||||
12451 | case OMPC_lastprivate: | ||||||
12452 | case OMPC_reduction: | ||||||
12453 | case OMPC_task_reduction: | ||||||
12454 | case OMPC_in_reduction: | ||||||
12455 | case OMPC_linear: | ||||||
12456 | case OMPC_default: | ||||||
12457 | case OMPC_proc_bind: | ||||||
12458 | case OMPC_safelen: | ||||||
12459 | case OMPC_simdlen: | ||||||
12460 | case OMPC_allocator: | ||||||
12461 | case OMPC_collapse: | ||||||
12462 | case OMPC_private: | ||||||
12463 | case OMPC_shared: | ||||||
12464 | case OMPC_aligned: | ||||||
12465 | case OMPC_copyin: | ||||||
12466 | case OMPC_copyprivate: | ||||||
12467 | case OMPC_ordered: | ||||||
12468 | case OMPC_nowait: | ||||||
12469 | case OMPC_untied: | ||||||
12470 | case OMPC_mergeable: | ||||||
12471 | case OMPC_threadprivate: | ||||||
12472 | case OMPC_allocate: | ||||||
12473 | case OMPC_flush: | ||||||
12474 | case OMPC_depobj: | ||||||
12475 | case OMPC_read: | ||||||
12476 | case OMPC_write: | ||||||
12477 | case OMPC_update: | ||||||
12478 | case OMPC_capture: | ||||||
12479 | case OMPC_seq_cst: | ||||||
12480 | case OMPC_acq_rel: | ||||||
12481 | case OMPC_acquire: | ||||||
12482 | case OMPC_release: | ||||||
12483 | case OMPC_relaxed: | ||||||
12484 | case OMPC_depend: | ||||||
12485 | case OMPC_threads: | ||||||
12486 | case OMPC_simd: | ||||||
12487 | case OMPC_map: | ||||||
12488 | case OMPC_nogroup: | ||||||
12489 | case OMPC_hint: | ||||||
12490 | case OMPC_defaultmap: | ||||||
12491 | case OMPC_unknown: | ||||||
12492 | case OMPC_uniform: | ||||||
12493 | case OMPC_to: | ||||||
12494 | case OMPC_from: | ||||||
12495 | case OMPC_use_device_ptr: | ||||||
12496 | case OMPC_use_device_addr: | ||||||
12497 | case OMPC_is_device_ptr: | ||||||
12498 | case OMPC_unified_address: | ||||||
12499 | case OMPC_unified_shared_memory: | ||||||
12500 | case OMPC_reverse_offload: | ||||||
12501 | case OMPC_dynamic_allocators: | ||||||
12502 | case OMPC_atomic_default_mem_order: | ||||||
12503 | case OMPC_device_type: | ||||||
12504 | case OMPC_match: | ||||||
12505 | case OMPC_nontemporal: | ||||||
12506 | case OMPC_order: | ||||||
12507 | case OMPC_destroy: | ||||||
12508 | case OMPC_detach: | ||||||
12509 | case OMPC_inclusive: | ||||||
12510 | case OMPC_exclusive: | ||||||
12511 | case OMPC_uses_allocators: | ||||||
12512 | case OMPC_affinity: | ||||||
12513 | default: | ||||||
12514 | llvm_unreachable("Unexpected OpenMP clause.")::llvm::llvm_unreachable_internal("Unexpected OpenMP clause." , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12514); | ||||||
12515 | } | ||||||
12516 | return CaptureRegion; | ||||||
12517 | } | ||||||
12518 | |||||||
12519 | OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, | ||||||
12520 | Expr *Condition, SourceLocation StartLoc, | ||||||
12521 | SourceLocation LParenLoc, | ||||||
12522 | SourceLocation NameModifierLoc, | ||||||
12523 | SourceLocation ColonLoc, | ||||||
12524 | SourceLocation EndLoc) { | ||||||
12525 | Expr *ValExpr = Condition; | ||||||
12526 | Stmt *HelperValStmt = nullptr; | ||||||
12527 | OpenMPDirectiveKind CaptureRegion = OMPD_unknown; | ||||||
12528 | if (!Condition->isValueDependent() && !Condition->isTypeDependent() && | ||||||
12529 | !Condition->isInstantiationDependent() && | ||||||
12530 | !Condition->containsUnexpandedParameterPack()) { | ||||||
12531 | ExprResult Val = CheckBooleanCondition(StartLoc, Condition); | ||||||
12532 | if (Val.isInvalid()) | ||||||
12533 | return nullptr; | ||||||
12534 | |||||||
12535 | ValExpr = Val.get(); | ||||||
12536 | |||||||
12537 | OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); | ||||||
12538 | CaptureRegion = getOpenMPCaptureRegionForClause( | ||||||
12539 | DKind, OMPC_if, LangOpts.OpenMP, NameModifier); | ||||||
12540 | if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { | ||||||
12541 | ValExpr = MakeFullExpr(ValExpr).get(); | ||||||
12542 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; | ||||||
12543 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); | ||||||
12544 | HelperValStmt = buildPreInits(Context, Captures); | ||||||
12545 | } | ||||||
12546 | } | ||||||
12547 | |||||||
12548 | return new (Context) | ||||||
12549 | OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, | ||||||
12550 | LParenLoc, NameModifierLoc, ColonLoc, EndLoc); | ||||||
12551 | } | ||||||
12552 | |||||||
12553 | OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, | ||||||
12554 | SourceLocation StartLoc, | ||||||
12555 | SourceLocation LParenLoc, | ||||||
12556 | SourceLocation EndLoc) { | ||||||
12557 | Expr *ValExpr = Condition; | ||||||
12558 | Stmt *HelperValStmt = nullptr; | ||||||
12559 | OpenMPDirectiveKind CaptureRegion = OMPD_unknown; | ||||||
12560 | if (!Condition->isValueDependent() && !Condition->isTypeDependent() && | ||||||
12561 | !Condition->isInstantiationDependent() && | ||||||
12562 | !Condition->containsUnexpandedParameterPack()) { | ||||||
12563 | ExprResult Val = CheckBooleanCondition(StartLoc, Condition); | ||||||
12564 | if (Val.isInvalid()) | ||||||
12565 | return nullptr; | ||||||
12566 | |||||||
12567 | ValExpr = MakeFullExpr(Val.get()).get(); | ||||||
12568 | |||||||
12569 | OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); | ||||||
12570 | CaptureRegion = | ||||||
12571 | getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); | ||||||
12572 | if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { | ||||||
12573 | ValExpr = MakeFullExpr(ValExpr).get(); | ||||||
12574 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; | ||||||
12575 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); | ||||||
12576 | HelperValStmt = buildPreInits(Context, Captures); | ||||||
12577 | } | ||||||
12578 | } | ||||||
12579 | |||||||
12580 | return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, | ||||||
12581 | StartLoc, LParenLoc, EndLoc); | ||||||
12582 | } | ||||||
12583 | |||||||
12584 | ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, | ||||||
12585 | Expr *Op) { | ||||||
12586 | if (!Op) | ||||||
12587 | return ExprError(); | ||||||
12588 | |||||||
12589 | class IntConvertDiagnoser : public ICEConvertDiagnoser { | ||||||
12590 | public: | ||||||
12591 | IntConvertDiagnoser() | ||||||
12592 | : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} | ||||||
12593 | SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, | ||||||
12594 | QualType T) override { | ||||||
12595 | return S.Diag(Loc, diag::err_omp_not_integral) << T; | ||||||
12596 | } | ||||||
12597 | SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, | ||||||
12598 | QualType T) override { | ||||||
12599 | return S.Diag(Loc, diag::err_omp_incomplete_type) << T; | ||||||
12600 | } | ||||||
12601 | SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, | ||||||
12602 | QualType T, | ||||||
12603 | QualType ConvTy) override { | ||||||
12604 | return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; | ||||||
12605 | } | ||||||
12606 | SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, | ||||||
12607 | QualType ConvTy) override { | ||||||
12608 | return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) | ||||||
12609 | << ConvTy->isEnumeralType() << ConvTy; | ||||||
12610 | } | ||||||
12611 | SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, | ||||||
12612 | QualType T) override { | ||||||
12613 | return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; | ||||||
12614 | } | ||||||
12615 | SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, | ||||||
12616 | QualType ConvTy) override { | ||||||
12617 | return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) | ||||||
12618 | << ConvTy->isEnumeralType() << ConvTy; | ||||||
12619 | } | ||||||
12620 | SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, | ||||||
12621 | QualType) override { | ||||||
12622 | llvm_unreachable("conversion functions are permitted")::llvm::llvm_unreachable_internal("conversion functions are permitted" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12622); | ||||||
12623 | } | ||||||
12624 | } ConvertDiagnoser; | ||||||
12625 | return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); | ||||||
12626 | } | ||||||
12627 | |||||||
12628 | static bool | ||||||
12629 | isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, | ||||||
12630 | bool StrictlyPositive, bool BuildCapture = false, | ||||||
12631 | OpenMPDirectiveKind DKind = OMPD_unknown, | ||||||
12632 | OpenMPDirectiveKind *CaptureRegion = nullptr, | ||||||
12633 | Stmt **HelperValStmt = nullptr) { | ||||||
12634 | if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && | ||||||
12635 | !ValExpr->isInstantiationDependent()) { | ||||||
12636 | SourceLocation Loc = ValExpr->getExprLoc(); | ||||||
12637 | ExprResult Value = | ||||||
12638 | SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); | ||||||
12639 | if (Value.isInvalid()) | ||||||
12640 | return false; | ||||||
12641 | |||||||
12642 | ValExpr = Value.get(); | ||||||
12643 | // The expression must evaluate to a non-negative integer value. | ||||||
12644 | if (Optional<llvm::APSInt> Result = | ||||||
12645 | ValExpr->getIntegerConstantExpr(SemaRef.Context)) { | ||||||
12646 | if (Result->isSigned() && | ||||||
12647 | !((!StrictlyPositive && Result->isNonNegative()) || | ||||||
12648 | (StrictlyPositive && Result->isStrictlyPositive()))) { | ||||||
12649 | SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) | ||||||
12650 | << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) | ||||||
12651 | << ValExpr->getSourceRange(); | ||||||
12652 | return false; | ||||||
12653 | } | ||||||
12654 | } | ||||||
12655 | if (!BuildCapture) | ||||||
12656 | return true; | ||||||
12657 | *CaptureRegion = | ||||||
12658 | getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); | ||||||
12659 | if (*CaptureRegion != OMPD_unknown && | ||||||
12660 | !SemaRef.CurContext->isDependentContext()) { | ||||||
12661 | ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); | ||||||
12662 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; | ||||||
12663 | ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); | ||||||
12664 | *HelperValStmt = buildPreInits(SemaRef.Context, Captures); | ||||||
12665 | } | ||||||
12666 | } | ||||||
12667 | return true; | ||||||
12668 | } | ||||||
12669 | |||||||
12670 | OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, | ||||||
12671 | SourceLocation StartLoc, | ||||||
12672 | SourceLocation LParenLoc, | ||||||
12673 | SourceLocation EndLoc) { | ||||||
12674 | Expr *ValExpr = NumThreads; | ||||||
12675 | Stmt *HelperValStmt = nullptr; | ||||||
12676 | |||||||
12677 | // OpenMP [2.5, Restrictions] | ||||||
12678 | // The num_threads expression must evaluate to a positive integer value. | ||||||
12679 | if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, | ||||||
12680 | /*StrictlyPositive=*/true)) | ||||||
12681 | return nullptr; | ||||||
12682 | |||||||
12683 | OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); | ||||||
12684 | OpenMPDirectiveKind CaptureRegion = | ||||||
12685 | getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); | ||||||
12686 | if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { | ||||||
12687 | ValExpr = MakeFullExpr(ValExpr).get(); | ||||||
12688 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; | ||||||
12689 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); | ||||||
12690 | HelperValStmt = buildPreInits(Context, Captures); | ||||||
12691 | } | ||||||
12692 | |||||||
12693 | return new (Context) OMPNumThreadsClause( | ||||||
12694 | ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); | ||||||
12695 | } | ||||||
12696 | |||||||
12697 | ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, | ||||||
12698 | OpenMPClauseKind CKind, | ||||||
12699 | bool StrictlyPositive) { | ||||||
12700 | if (!E) | ||||||
12701 | return ExprError(); | ||||||
12702 | if (E->isValueDependent() || E->isTypeDependent() || | ||||||
12703 | E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) | ||||||
12704 | return E; | ||||||
12705 | llvm::APSInt Result; | ||||||
12706 | ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); | ||||||
12707 | if (ICE.isInvalid()) | ||||||
12708 | return ExprError(); | ||||||
12709 | if ((StrictlyPositive && !Result.isStrictlyPositive()) || | ||||||
12710 | (!StrictlyPositive && !Result.isNonNegative())) { | ||||||
12711 | Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) | ||||||
12712 | << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) | ||||||
12713 | << E->getSourceRange(); | ||||||
12714 | return ExprError(); | ||||||
12715 | } | ||||||
12716 | if (CKind == OMPC_aligned && !Result.isPowerOf2()) { | ||||||
12717 | Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) | ||||||
12718 | << E->getSourceRange(); | ||||||
12719 | return ExprError(); | ||||||
12720 | } | ||||||
12721 | if (CKind == OMPC_collapse && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getAssociatedLoops() == 1) | ||||||
12722 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setAssociatedLoops(Result.getExtValue()); | ||||||
12723 | else if (CKind == OMPC_ordered) | ||||||
12724 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setAssociatedLoops(Result.getExtValue()); | ||||||
12725 | return ICE; | ||||||
12726 | } | ||||||
12727 | |||||||
12728 | OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, | ||||||
12729 | SourceLocation LParenLoc, | ||||||
12730 | SourceLocation EndLoc) { | ||||||
12731 | // OpenMP [2.8.1, simd construct, Description] | ||||||
12732 | // The parameter of the safelen clause must be a constant | ||||||
12733 | // positive integer expression. | ||||||
12734 | ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); | ||||||
12735 | if (Safelen.isInvalid()) | ||||||
12736 | return nullptr; | ||||||
12737 | return new (Context) | ||||||
12738 | OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); | ||||||
12739 | } | ||||||
12740 | |||||||
12741 | OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, | ||||||
12742 | SourceLocation LParenLoc, | ||||||
12743 | SourceLocation EndLoc) { | ||||||
12744 | // OpenMP [2.8.1, simd construct, Description] | ||||||
12745 | // The parameter of the simdlen clause must be a constant | ||||||
12746 | // positive integer expression. | ||||||
12747 | ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); | ||||||
12748 | if (Simdlen.isInvalid()) | ||||||
12749 | return nullptr; | ||||||
12750 | return new (Context) | ||||||
12751 | OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); | ||||||
12752 | } | ||||||
12753 | |||||||
12754 | /// Tries to find omp_allocator_handle_t type. | ||||||
12755 | static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, | ||||||
12756 | DSAStackTy *Stack) { | ||||||
12757 | QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); | ||||||
12758 | if (!OMPAllocatorHandleT.isNull()) | ||||||
12759 | return true; | ||||||
12760 | // Build the predefined allocator expressions. | ||||||
12761 | bool ErrorFound = false; | ||||||
12762 | for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { | ||||||
12763 | auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); | ||||||
12764 | StringRef Allocator = | ||||||
12765 | OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); | ||||||
12766 | DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); | ||||||
12767 | auto *VD = dyn_cast_or_null<ValueDecl>( | ||||||
12768 | S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); | ||||||
12769 | if (!VD) { | ||||||
12770 | ErrorFound = true; | ||||||
12771 | break; | ||||||
12772 | } | ||||||
12773 | QualType AllocatorType = | ||||||
12774 | VD->getType().getNonLValueExprType(S.getASTContext()); | ||||||
12775 | ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); | ||||||
12776 | if (!Res.isUsable()) { | ||||||
12777 | ErrorFound = true; | ||||||
12778 | break; | ||||||
12779 | } | ||||||
12780 | if (OMPAllocatorHandleT.isNull()) | ||||||
12781 | OMPAllocatorHandleT = AllocatorType; | ||||||
12782 | if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { | ||||||
12783 | ErrorFound = true; | ||||||
12784 | break; | ||||||
12785 | } | ||||||
12786 | Stack->setAllocator(AllocatorKind, Res.get()); | ||||||
12787 | } | ||||||
12788 | if (ErrorFound) { | ||||||
12789 | S.Diag(Loc, diag::err_omp_implied_type_not_found) | ||||||
12790 | << "omp_allocator_handle_t"; | ||||||
12791 | return false; | ||||||
12792 | } | ||||||
12793 | OMPAllocatorHandleT.addConst(); | ||||||
12794 | Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); | ||||||
12795 | return true; | ||||||
12796 | } | ||||||
12797 | |||||||
12798 | OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, | ||||||
12799 | SourceLocation LParenLoc, | ||||||
12800 | SourceLocation EndLoc) { | ||||||
12801 | // OpenMP [2.11.3, allocate Directive, Description] | ||||||
12802 | // allocator is an expression of omp_allocator_handle_t type. | ||||||
12803 | if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||
12804 | return nullptr; | ||||||
12805 | |||||||
12806 | ExprResult Allocator = DefaultLvalueConversion(A); | ||||||
12807 | if (Allocator.isInvalid()) | ||||||
12808 | return nullptr; | ||||||
12809 | Allocator = PerformImplicitConversion(Allocator.get(), | ||||||
12810 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPAllocatorHandleT(), | ||||||
12811 | Sema::AA_Initializing, | ||||||
12812 | /*AllowExplicit=*/true); | ||||||
12813 | if (Allocator.isInvalid()) | ||||||
12814 | return nullptr; | ||||||
12815 | return new (Context) | ||||||
12816 | OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); | ||||||
12817 | } | ||||||
12818 | |||||||
12819 | OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, | ||||||
12820 | SourceLocation StartLoc, | ||||||
12821 | SourceLocation LParenLoc, | ||||||
12822 | SourceLocation EndLoc) { | ||||||
12823 | // OpenMP [2.7.1, loop construct, Description] | ||||||
12824 | // OpenMP [2.8.1, simd construct, Description] | ||||||
12825 | // OpenMP [2.9.6, distribute construct, Description] | ||||||
12826 | // The parameter of the collapse clause must be a constant | ||||||
12827 | // positive integer expression. | ||||||
12828 | ExprResult NumForLoopsResult = | ||||||
12829 | VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); | ||||||
12830 | if (NumForLoopsResult.isInvalid()) | ||||||
12831 | return nullptr; | ||||||
12832 | return new (Context) | ||||||
12833 | OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); | ||||||
12834 | } | ||||||
12835 | |||||||
12836 | OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, | ||||||
12837 | SourceLocation EndLoc, | ||||||
12838 | SourceLocation LParenLoc, | ||||||
12839 | Expr *NumForLoops) { | ||||||
12840 | // OpenMP [2.7.1, loop construct, Description] | ||||||
12841 | // OpenMP [2.8.1, simd construct, Description] | ||||||
12842 | // OpenMP [2.9.6, distribute construct, Description] | ||||||
12843 | // The parameter of the ordered clause must be a constant | ||||||
12844 | // positive integer expression if any. | ||||||
12845 | if (NumForLoops && LParenLoc.isValid()) { | ||||||
12846 | ExprResult NumForLoopsResult = | ||||||
12847 | VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); | ||||||
12848 | if (NumForLoopsResult.isInvalid()) | ||||||
12849 | return nullptr; | ||||||
12850 | NumForLoops = NumForLoopsResult.get(); | ||||||
12851 | } else { | ||||||
12852 | NumForLoops = nullptr; | ||||||
12853 | } | ||||||
12854 | auto *Clause = OMPOrderedClause::Create( | ||||||
12855 | Context, NumForLoops, NumForLoops ? DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getAssociatedLoops() : 0, | ||||||
12856 | StartLoc, LParenLoc, EndLoc); | ||||||
12857 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); | ||||||
12858 | return Clause; | ||||||
12859 | } | ||||||
12860 | |||||||
12861 | OMPClause *Sema::ActOnOpenMPSimpleClause( | ||||||
12862 | OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, | ||||||
12863 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { | ||||||
12864 | OMPClause *Res = nullptr; | ||||||
12865 | switch (Kind) { | ||||||
12866 | case OMPC_default: | ||||||
12867 | Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument), | ||||||
12868 | ArgumentLoc, StartLoc, LParenLoc, EndLoc); | ||||||
12869 | break; | ||||||
12870 | case OMPC_proc_bind: | ||||||
12871 | Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), | ||||||
12872 | ArgumentLoc, StartLoc, LParenLoc, EndLoc); | ||||||
12873 | break; | ||||||
12874 | case OMPC_atomic_default_mem_order: | ||||||
12875 | Res = ActOnOpenMPAtomicDefaultMemOrderClause( | ||||||
12876 | static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), | ||||||
12877 | ArgumentLoc, StartLoc, LParenLoc, EndLoc); | ||||||
12878 | break; | ||||||
12879 | case OMPC_order: | ||||||
12880 | Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), | ||||||
12881 | ArgumentLoc, StartLoc, LParenLoc, EndLoc); | ||||||
12882 | break; | ||||||
12883 | case OMPC_update: | ||||||
12884 | Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument), | ||||||
12885 | ArgumentLoc, StartLoc, LParenLoc, EndLoc); | ||||||
12886 | break; | ||||||
12887 | case OMPC_if: | ||||||
12888 | case OMPC_final: | ||||||
12889 | case OMPC_num_threads: | ||||||
12890 | case OMPC_safelen: | ||||||
12891 | case OMPC_simdlen: | ||||||
12892 | case OMPC_allocator: | ||||||
12893 | case OMPC_collapse: | ||||||
12894 | case OMPC_schedule: | ||||||
12895 | case OMPC_private: | ||||||
12896 | case OMPC_firstprivate: | ||||||
12897 | case OMPC_lastprivate: | ||||||
12898 | case OMPC_shared: | ||||||
12899 | case OMPC_reduction: | ||||||
12900 | case OMPC_task_reduction: | ||||||
12901 | case OMPC_in_reduction: | ||||||
12902 | case OMPC_linear: | ||||||
12903 | case OMPC_aligned: | ||||||
12904 | case OMPC_copyin: | ||||||
12905 | case OMPC_copyprivate: | ||||||
12906 | case OMPC_ordered: | ||||||
12907 | case OMPC_nowait: | ||||||
12908 | case OMPC_untied: | ||||||
12909 | case OMPC_mergeable: | ||||||
12910 | case OMPC_threadprivate: | ||||||
12911 | case OMPC_allocate: | ||||||
12912 | case OMPC_flush: | ||||||
12913 | case OMPC_depobj: | ||||||
12914 | case OMPC_read: | ||||||
12915 | case OMPC_write: | ||||||
12916 | case OMPC_capture: | ||||||
12917 | case OMPC_seq_cst: | ||||||
12918 | case OMPC_acq_rel: | ||||||
12919 | case OMPC_acquire: | ||||||
12920 | case OMPC_release: | ||||||
12921 | case OMPC_relaxed: | ||||||
12922 | case OMPC_depend: | ||||||
12923 | case OMPC_device: | ||||||
12924 | case OMPC_threads: | ||||||
12925 | case OMPC_simd: | ||||||
12926 | case OMPC_map: | ||||||
12927 | case OMPC_num_teams: | ||||||
12928 | case OMPC_thread_limit: | ||||||
12929 | case OMPC_priority: | ||||||
12930 | case OMPC_grainsize: | ||||||
12931 | case OMPC_nogroup: | ||||||
12932 | case OMPC_num_tasks: | ||||||
12933 | case OMPC_hint: | ||||||
12934 | case OMPC_dist_schedule: | ||||||
12935 | case OMPC_defaultmap: | ||||||
12936 | case OMPC_unknown: | ||||||
12937 | case OMPC_uniform: | ||||||
12938 | case OMPC_to: | ||||||
12939 | case OMPC_from: | ||||||
12940 | case OMPC_use_device_ptr: | ||||||
12941 | case OMPC_use_device_addr: | ||||||
12942 | case OMPC_is_device_ptr: | ||||||
12943 | case OMPC_unified_address: | ||||||
12944 | case OMPC_unified_shared_memory: | ||||||
12945 | case OMPC_reverse_offload: | ||||||
12946 | case OMPC_dynamic_allocators: | ||||||
12947 | case OMPC_device_type: | ||||||
12948 | case OMPC_match: | ||||||
12949 | case OMPC_nontemporal: | ||||||
12950 | case OMPC_destroy: | ||||||
12951 | case OMPC_detach: | ||||||
12952 | case OMPC_inclusive: | ||||||
12953 | case OMPC_exclusive: | ||||||
12954 | case OMPC_uses_allocators: | ||||||
12955 | case OMPC_affinity: | ||||||
12956 | default: | ||||||
12957 | llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12957); | ||||||
12958 | } | ||||||
12959 | return Res; | ||||||
12960 | } | ||||||
12961 | |||||||
12962 | static std::string | ||||||
12963 | getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, | ||||||
12964 | ArrayRef<unsigned> Exclude = llvm::None) { | ||||||
12965 | SmallString<256> Buffer; | ||||||
12966 | llvm::raw_svector_ostream Out(Buffer); | ||||||
12967 | unsigned Skipped = Exclude.size(); | ||||||
12968 | auto S = Exclude.begin(), E = Exclude.end(); | ||||||
12969 | for (unsigned I = First; I < Last; ++I) { | ||||||
12970 | if (std::find(S, E, I) != E) { | ||||||
12971 | --Skipped; | ||||||
12972 | continue; | ||||||
12973 | } | ||||||
12974 | Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; | ||||||
12975 | if (I + Skipped + 2 == Last) | ||||||
12976 | Out << " or "; | ||||||
12977 | else if (I + Skipped + 1 != Last) | ||||||
12978 | Out << ", "; | ||||||
12979 | } | ||||||
12980 | return std::string(Out.str()); | ||||||
12981 | } | ||||||
12982 | |||||||
12983 | OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, | ||||||
12984 | SourceLocation KindKwLoc, | ||||||
12985 | SourceLocation StartLoc, | ||||||
12986 | SourceLocation LParenLoc, | ||||||
12987 | SourceLocation EndLoc) { | ||||||
12988 | if (Kind == OMP_DEFAULT_unknown) { | ||||||
12989 | Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) | ||||||
12990 | << getListOfPossibleValues(OMPC_default, /*First=*/0, | ||||||
12991 | /*Last=*/unsigned(OMP_DEFAULT_unknown)) | ||||||
12992 | << getOpenMPClauseName(OMPC_default); | ||||||
12993 | return nullptr; | ||||||
12994 | } | ||||||
12995 | |||||||
12996 | switch (Kind) { | ||||||
12997 | case OMP_DEFAULT_none: | ||||||
12998 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setDefaultDSANone(KindKwLoc); | ||||||
12999 | break; | ||||||
13000 | case OMP_DEFAULT_shared: | ||||||
13001 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setDefaultDSAShared(KindKwLoc); | ||||||
13002 | break; | ||||||
13003 | case OMP_DEFAULT_firstprivate: | ||||||
13004 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setDefaultDSAFirstPrivate(KindKwLoc); | ||||||
13005 | break; | ||||||
13006 | default: | ||||||
13007 | llvm_unreachable("DSA unexpected in OpenMP default clause")::llvm::llvm_unreachable_internal("DSA unexpected in OpenMP default clause" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13007); | ||||||
13008 | } | ||||||
13009 | |||||||
13010 | return new (Context) | ||||||
13011 | OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); | ||||||
13012 | } | ||||||
13013 | |||||||
13014 | OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, | ||||||
13015 | SourceLocation KindKwLoc, | ||||||
13016 | SourceLocation StartLoc, | ||||||
13017 | SourceLocation LParenLoc, | ||||||
13018 | SourceLocation EndLoc) { | ||||||
13019 | if (Kind == OMP_PROC_BIND_unknown) { | ||||||
13020 | Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) | ||||||
13021 | << getListOfPossibleValues(OMPC_proc_bind, | ||||||
13022 | /*First=*/unsigned(OMP_PROC_BIND_master), | ||||||
13023 | /*Last=*/5) | ||||||
13024 | << getOpenMPClauseName(OMPC_proc_bind); | ||||||
13025 | return nullptr; | ||||||
13026 | } | ||||||
13027 | return new (Context) | ||||||
13028 | OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); | ||||||
13029 | } | ||||||
13030 | |||||||
13031 | OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( | ||||||
13032 | OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, | ||||||
13033 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { | ||||||
13034 | if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { | ||||||
13035 | Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) | ||||||
13036 | << getListOfPossibleValues( | ||||||
13037 | OMPC_atomic_default_mem_order, /*First=*/0, | ||||||
13038 | /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) | ||||||
13039 | << getOpenMPClauseName(OMPC_atomic_default_mem_order); | ||||||
13040 | return nullptr; | ||||||
13041 | } | ||||||
13042 | return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, | ||||||
13043 | LParenLoc, EndLoc); | ||||||
13044 | } | ||||||
13045 | |||||||
13046 | OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, | ||||||
13047 | SourceLocation KindKwLoc, | ||||||
13048 | SourceLocation StartLoc, | ||||||
13049 | SourceLocation LParenLoc, | ||||||
13050 | SourceLocation EndLoc) { | ||||||
13051 | if (Kind == OMPC_ORDER_unknown) { | ||||||
13052 | static_assert(OMPC_ORDER_unknown > 0, | ||||||
13053 | "OMPC_ORDER_unknown not greater than 0"); | ||||||
13054 | Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) | ||||||
13055 | << getListOfPossibleValues(OMPC_order, /*First=*/0, | ||||||
13056 | /*Last=*/OMPC_ORDER_unknown) | ||||||
13057 | << getOpenMPClauseName(OMPC_order); | ||||||
13058 | return nullptr; | ||||||
13059 | } | ||||||
13060 | return new (Context) | ||||||
13061 | OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); | ||||||
13062 | } | ||||||
13063 | |||||||
13064 | OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, | ||||||
13065 | SourceLocation KindKwLoc, | ||||||
13066 | SourceLocation StartLoc, | ||||||
13067 | SourceLocation LParenLoc, | ||||||
13068 | SourceLocation EndLoc) { | ||||||
13069 | if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source || | ||||||
13070 | Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) { | ||||||
13071 | unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink, | ||||||
13072 | OMPC_DEPEND_depobj}; | ||||||
13073 | Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) | ||||||
13074 | << getListOfPossibleValues(OMPC_depend, /*First=*/0, | ||||||
13075 | /*Last=*/OMPC_DEPEND_unknown, Except) | ||||||
13076 | << getOpenMPClauseName(OMPC_update); | ||||||
13077 | return nullptr; | ||||||
13078 | } | ||||||
13079 | return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind, | ||||||
13080 | EndLoc); | ||||||
13081 | } | ||||||
13082 | |||||||
13083 | OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( | ||||||
13084 | OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, | ||||||
13085 | SourceLocation StartLoc, SourceLocation LParenLoc, | ||||||
13086 | ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, | ||||||
13087 | SourceLocation EndLoc) { | ||||||
13088 | OMPClause *Res = nullptr; | ||||||
13089 | switch (Kind) { | ||||||
13090 | case OMPC_schedule: | ||||||
13091 | enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; | ||||||
13092 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13093, __PRETTY_FUNCTION__)) | ||||||
13093 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13093, __PRETTY_FUNCTION__)); | ||||||
13094 | Res = ActOnOpenMPScheduleClause( | ||||||
13095 | static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), | ||||||
13096 | static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), | ||||||
13097 | static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, | ||||||
13098 | StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], | ||||||
13099 | ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); | ||||||
13100 | break; | ||||||
13101 | case OMPC_if: | ||||||
13102 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13102, __PRETTY_FUNCTION__)); | ||||||
13103 | Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), | ||||||
13104 | Expr, StartLoc, LParenLoc, ArgumentLoc.back(), | ||||||
13105 | DelimLoc, EndLoc); | ||||||
13106 | break; | ||||||
13107 | case OMPC_dist_schedule: | ||||||
13108 | Res = ActOnOpenMPDistScheduleClause( | ||||||
13109 | static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, | ||||||
13110 | StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); | ||||||
13111 | break; | ||||||
13112 | case OMPC_defaultmap: | ||||||
13113 | enum { Modifier, DefaultmapKind }; | ||||||
13114 | Res = ActOnOpenMPDefaultmapClause( | ||||||
13115 | static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), | ||||||
13116 | static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), | ||||||
13117 | StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], | ||||||
13118 | EndLoc); | ||||||
13119 | break; | ||||||
13120 | case OMPC_device: | ||||||
13121 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13121, __PRETTY_FUNCTION__)); | ||||||
13122 | Res = ActOnOpenMPDeviceClause( | ||||||
13123 | static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr, | ||||||
13124 | StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); | ||||||
13125 | break; | ||||||
13126 | case OMPC_final: | ||||||
13127 | case OMPC_num_threads: | ||||||
13128 | case OMPC_safelen: | ||||||
13129 | case OMPC_simdlen: | ||||||
13130 | case OMPC_allocator: | ||||||
13131 | case OMPC_collapse: | ||||||
13132 | case OMPC_default: | ||||||
13133 | case OMPC_proc_bind: | ||||||
13134 | case OMPC_private: | ||||||
13135 | case OMPC_firstprivate: | ||||||
13136 | case OMPC_lastprivate: | ||||||
13137 | case OMPC_shared: | ||||||
13138 | case OMPC_reduction: | ||||||
13139 | case OMPC_task_reduction: | ||||||
13140 | case OMPC_in_reduction: | ||||||
13141 | case OMPC_linear: | ||||||
13142 | case OMPC_aligned: | ||||||
13143 | case OMPC_copyin: | ||||||
13144 | case OMPC_copyprivate: | ||||||
13145 | case OMPC_ordered: | ||||||
13146 | case OMPC_nowait: | ||||||
13147 | case OMPC_untied: | ||||||
13148 | case OMPC_mergeable: | ||||||
13149 | case OMPC_threadprivate: | ||||||
13150 | case OMPC_allocate: | ||||||
13151 | case OMPC_flush: | ||||||
13152 | case OMPC_depobj: | ||||||
13153 | case OMPC_read: | ||||||
13154 | case OMPC_write: | ||||||
13155 | case OMPC_update: | ||||||
13156 | case OMPC_capture: | ||||||
13157 | case OMPC_seq_cst: | ||||||
13158 | case OMPC_acq_rel: | ||||||
13159 | case OMPC_acquire: | ||||||
13160 | case OMPC_release: | ||||||
13161 | case OMPC_relaxed: | ||||||
13162 | case OMPC_depend: | ||||||
13163 | case OMPC_threads: | ||||||
13164 | case OMPC_simd: | ||||||
13165 | case OMPC_map: | ||||||
13166 | case OMPC_num_teams: | ||||||
13167 | case OMPC_thread_limit: | ||||||
13168 | case OMPC_priority: | ||||||
13169 | case OMPC_grainsize: | ||||||
13170 | case OMPC_nogroup: | ||||||
13171 | case OMPC_num_tasks: | ||||||
13172 | case OMPC_hint: | ||||||
13173 | case OMPC_unknown: | ||||||
13174 | case OMPC_uniform: | ||||||
13175 | case OMPC_to: | ||||||
13176 | case OMPC_from: | ||||||
13177 | case OMPC_use_device_ptr: | ||||||
13178 | case OMPC_use_device_addr: | ||||||
13179 | case OMPC_is_device_ptr: | ||||||
13180 | case OMPC_unified_address: | ||||||
13181 | case OMPC_unified_shared_memory: | ||||||
13182 | case OMPC_reverse_offload: | ||||||
13183 | case OMPC_dynamic_allocators: | ||||||
13184 | case OMPC_atomic_default_mem_order: | ||||||
13185 | case OMPC_device_type: | ||||||
13186 | case OMPC_match: | ||||||
13187 | case OMPC_nontemporal: | ||||||
13188 | case OMPC_order: | ||||||
13189 | case OMPC_destroy: | ||||||
13190 | case OMPC_detach: | ||||||
13191 | case OMPC_inclusive: | ||||||
13192 | case OMPC_exclusive: | ||||||
13193 | case OMPC_uses_allocators: | ||||||
13194 | case OMPC_affinity: | ||||||
13195 | default: | ||||||
13196 | llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13196); | ||||||
13197 | } | ||||||
13198 | return Res; | ||||||
13199 | } | ||||||
13200 | |||||||
13201 | static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, | ||||||
13202 | OpenMPScheduleClauseModifier M2, | ||||||
13203 | SourceLocation M1Loc, SourceLocation M2Loc) { | ||||||
13204 | if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { | ||||||
13205 | SmallVector<unsigned, 2> Excluded; | ||||||
13206 | if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) | ||||||
13207 | Excluded.push_back(M2); | ||||||
13208 | if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) | ||||||
13209 | Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); | ||||||
13210 | if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) | ||||||
13211 | Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); | ||||||
13212 | S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) | ||||||
13213 | << getListOfPossibleValues(OMPC_schedule, | ||||||
13214 | /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, | ||||||
13215 | /*Last=*/OMPC_SCHEDULE_MODIFIER_last, | ||||||
13216 | Excluded) | ||||||
13217 | << getOpenMPClauseName(OMPC_schedule); | ||||||
13218 | return true; | ||||||
13219 | } | ||||||
13220 | return false; | ||||||
13221 | } | ||||||
13222 | |||||||
13223 | OMPClause *Sema::ActOnOpenMPScheduleClause( | ||||||
13224 | OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, | ||||||
13225 | OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, | ||||||
13226 | SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, | ||||||
13227 | SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { | ||||||
13228 | if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || | ||||||
13229 | checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) | ||||||
13230 | return nullptr; | ||||||
13231 | // OpenMP, 2.7.1, Loop Construct, Restrictions | ||||||
13232 | // Either the monotonic modifier or the nonmonotonic modifier can be specified | ||||||
13233 | // but not both. | ||||||
13234 | if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || | ||||||
13235 | (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && | ||||||
13236 | M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || | ||||||
13237 | (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && | ||||||
13238 | M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { | ||||||
13239 | Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) | ||||||
13240 | << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) | ||||||
13241 | << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); | ||||||
13242 | return nullptr; | ||||||
13243 | } | ||||||
13244 | if (Kind == OMPC_SCHEDULE_unknown) { | ||||||
13245 | std::string Values; | ||||||
13246 | if (M1Loc.isInvalid() && M2Loc.isInvalid()) { | ||||||
13247 | unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; | ||||||
13248 | Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, | ||||||
13249 | /*Last=*/OMPC_SCHEDULE_MODIFIER_last, | ||||||
13250 | Exclude); | ||||||
13251 | } else { | ||||||
13252 | Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, | ||||||
13253 | /*Last=*/OMPC_SCHEDULE_unknown); | ||||||
13254 | } | ||||||
13255 | Diag(KindLoc, diag::err_omp_unexpected_clause_value) | ||||||
13256 | << Values << getOpenMPClauseName(OMPC_schedule); | ||||||
13257 | return nullptr; | ||||||
13258 | } | ||||||
13259 | // OpenMP, 2.7.1, Loop Construct, Restrictions | ||||||
13260 | // The nonmonotonic modifier can only be specified with schedule(dynamic) or | ||||||
13261 | // schedule(guided). | ||||||
13262 | // OpenMP 5.0 does not have this restriction. | ||||||
13263 | if (LangOpts.OpenMP < 50 && | ||||||
13264 | (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || | ||||||
13265 | M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && | ||||||
13266 | Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { | ||||||
13267 | Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, | ||||||
13268 | diag::err_omp_schedule_nonmonotonic_static); | ||||||
13269 | return nullptr; | ||||||
13270 | } | ||||||
13271 | Expr *ValExpr = ChunkSize; | ||||||
13272 | Stmt *HelperValStmt = nullptr; | ||||||
13273 | if (ChunkSize) { | ||||||
13274 | if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && | ||||||
13275 | !ChunkSize->isInstantiationDependent() && | ||||||
13276 | !ChunkSize->containsUnexpandedParameterPack()) { | ||||||
13277 | SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); | ||||||
13278 | ExprResult Val = | ||||||
13279 | PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); | ||||||
13280 | if (Val.isInvalid()) | ||||||
13281 | return nullptr; | ||||||
13282 | |||||||
13283 | ValExpr = Val.get(); | ||||||
13284 | |||||||
13285 | // OpenMP [2.7.1, Restrictions] | ||||||
13286 | // chunk_size must be a loop invariant integer expression with a positive | ||||||
13287 | // value. | ||||||
13288 | if (Optional<llvm::APSInt> Result = | ||||||
13289 | ValExpr->getIntegerConstantExpr(Context)) { | ||||||
13290 | if (Result->isSigned() && !Result->isStrictlyPositive()) { | ||||||
13291 | Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) | ||||||
13292 | << "schedule" << 1 << ChunkSize->getSourceRange(); | ||||||
13293 | return nullptr; | ||||||
13294 | } | ||||||
13295 | } else if (getOpenMPCaptureRegionForClause( | ||||||
13296 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(), OMPC_schedule, | ||||||
13297 | LangOpts.OpenMP) != OMPD_unknown && | ||||||
13298 | !CurContext->isDependentContext()) { | ||||||
13299 | ValExpr = MakeFullExpr(ValExpr).get(); | ||||||
13300 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; | ||||||
13301 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); | ||||||
13302 | HelperValStmt = buildPreInits(Context, Captures); | ||||||
13303 | } | ||||||
13304 | } | ||||||
13305 | } | ||||||
13306 | |||||||
13307 | return new (Context) | ||||||
13308 | OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, | ||||||
13309 | ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); | ||||||
13310 | } | ||||||
13311 | |||||||
13312 | OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, | ||||||
13313 | SourceLocation StartLoc, | ||||||
13314 | SourceLocation EndLoc) { | ||||||
13315 | OMPClause *Res = nullptr; | ||||||
13316 | switch (Kind) { | ||||||
13317 | case OMPC_ordered: | ||||||
13318 | Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); | ||||||
13319 | break; | ||||||
13320 | case OMPC_nowait: | ||||||
13321 | Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); | ||||||
13322 | break; | ||||||
13323 | case OMPC_untied: | ||||||
13324 | Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); | ||||||
13325 | break; | ||||||
13326 | case OMPC_mergeable: | ||||||
13327 | Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); | ||||||
13328 | break; | ||||||
13329 | case OMPC_read: | ||||||
13330 | Res = ActOnOpenMPReadClause(StartLoc, EndLoc); | ||||||
13331 | break; | ||||||
13332 | case OMPC_write: | ||||||
13333 | Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); | ||||||
13334 | break; | ||||||
13335 | case OMPC_update: | ||||||
13336 | Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); | ||||||
13337 | break; | ||||||
13338 | case OMPC_capture: | ||||||
13339 | Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); | ||||||
13340 | break; | ||||||
13341 | case OMPC_seq_cst: | ||||||
13342 | Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); | ||||||
13343 | break; | ||||||
13344 | case OMPC_acq_rel: | ||||||
13345 | Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); | ||||||
13346 | break; | ||||||
13347 | case OMPC_acquire: | ||||||
13348 | Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); | ||||||
13349 | break; | ||||||
13350 | case OMPC_release: | ||||||
13351 | Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); | ||||||
13352 | break; | ||||||
13353 | case OMPC_relaxed: | ||||||
13354 | Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); | ||||||
13355 | break; | ||||||
13356 | case OMPC_threads: | ||||||
13357 | Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); | ||||||
13358 | break; | ||||||
13359 | case OMPC_simd: | ||||||
13360 | Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); | ||||||
13361 | break; | ||||||
13362 | case OMPC_nogroup: | ||||||
13363 | Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); | ||||||
13364 | break; | ||||||
13365 | case OMPC_unified_address: | ||||||
13366 | Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); | ||||||
13367 | break; | ||||||
13368 | case OMPC_unified_shared_memory: | ||||||
13369 | Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); | ||||||
13370 | break; | ||||||
13371 | case OMPC_reverse_offload: | ||||||
13372 | Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); | ||||||
13373 | break; | ||||||
13374 | case OMPC_dynamic_allocators: | ||||||
13375 | Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); | ||||||
13376 | break; | ||||||
13377 | case OMPC_destroy: | ||||||
13378 | Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc); | ||||||
13379 | break; | ||||||
13380 | case OMPC_if: | ||||||
13381 | case OMPC_final: | ||||||
13382 | case OMPC_num_threads: | ||||||
13383 | case OMPC_safelen: | ||||||
13384 | case OMPC_simdlen: | ||||||
13385 | case OMPC_allocator: | ||||||
13386 | case OMPC_collapse: | ||||||
13387 | case OMPC_schedule: | ||||||
13388 | case OMPC_private: | ||||||
13389 | case OMPC_firstprivate: | ||||||
13390 | case OMPC_lastprivate: | ||||||
13391 | case OMPC_shared: | ||||||
13392 | case OMPC_reduction: | ||||||
13393 | case OMPC_task_reduction: | ||||||
13394 | case OMPC_in_reduction: | ||||||
13395 | case OMPC_linear: | ||||||
13396 | case OMPC_aligned: | ||||||
13397 | case OMPC_copyin: | ||||||
13398 | case OMPC_copyprivate: | ||||||
13399 | case OMPC_default: | ||||||
13400 | case OMPC_proc_bind: | ||||||
13401 | case OMPC_threadprivate: | ||||||
13402 | case OMPC_allocate: | ||||||
13403 | case OMPC_flush: | ||||||
13404 | case OMPC_depobj: | ||||||
13405 | case OMPC_depend: | ||||||
13406 | case OMPC_device: | ||||||
13407 | case OMPC_map: | ||||||
13408 | case OMPC_num_teams: | ||||||
13409 | case OMPC_thread_limit: | ||||||
13410 | case OMPC_priority: | ||||||
13411 | case OMPC_grainsize: | ||||||
13412 | case OMPC_num_tasks: | ||||||
13413 | case OMPC_hint: | ||||||
13414 | case OMPC_dist_schedule: | ||||||
13415 | case OMPC_defaultmap: | ||||||
13416 | case OMPC_unknown: | ||||||
13417 | case OMPC_uniform: | ||||||
13418 | case OMPC_to: | ||||||
13419 | case OMPC_from: | ||||||
13420 | case OMPC_use_device_ptr: | ||||||
13421 | case OMPC_use_device_addr: | ||||||
13422 | case OMPC_is_device_ptr: | ||||||
13423 | case OMPC_atomic_default_mem_order: | ||||||
13424 | case OMPC_device_type: | ||||||
13425 | case OMPC_match: | ||||||
13426 | case OMPC_nontemporal: | ||||||
13427 | case OMPC_order: | ||||||
13428 | case OMPC_detach: | ||||||
13429 | case OMPC_inclusive: | ||||||
13430 | case OMPC_exclusive: | ||||||
13431 | case OMPC_uses_allocators: | ||||||
13432 | case OMPC_affinity: | ||||||
13433 | default: | ||||||
13434 | llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13434); | ||||||
13435 | } | ||||||
13436 | return Res; | ||||||
13437 | } | ||||||
13438 | |||||||
13439 | OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, | ||||||
13440 | SourceLocation EndLoc) { | ||||||
13441 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setNowaitRegion(); | ||||||
13442 | return new (Context) OMPNowaitClause(StartLoc, EndLoc); | ||||||
13443 | } | ||||||
13444 | |||||||
13445 | OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, | ||||||
13446 | SourceLocation EndLoc) { | ||||||
13447 | return new (Context) OMPUntiedClause(StartLoc, EndLoc); | ||||||
13448 | } | ||||||
13449 | |||||||
13450 | OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, | ||||||
13451 | SourceLocation EndLoc) { | ||||||
13452 | return new (Context) OMPMergeableClause(StartLoc, EndLoc); | ||||||
13453 | } | ||||||
13454 | |||||||
13455 | OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, | ||||||
13456 | SourceLocation EndLoc) { | ||||||
13457 | return new (Context) OMPReadClause(StartLoc, EndLoc); | ||||||
13458 | } | ||||||
13459 | |||||||
13460 | OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, | ||||||
13461 | SourceLocation EndLoc) { | ||||||
13462 | return new (Context) OMPWriteClause(StartLoc, EndLoc); | ||||||
13463 | } | ||||||
13464 | |||||||
13465 | OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, | ||||||
13466 | SourceLocation EndLoc) { | ||||||
13467 | return OMPUpdateClause::Create(Context, StartLoc, EndLoc); | ||||||
13468 | } | ||||||
13469 | |||||||
13470 | OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, | ||||||
13471 | SourceLocation EndLoc) { | ||||||
13472 | return new (Context) OMPCaptureClause(StartLoc, EndLoc); | ||||||
13473 | } | ||||||
13474 | |||||||
13475 | OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, | ||||||
13476 | SourceLocation EndLoc) { | ||||||
13477 | return new (Context) OMPSeqCstClause(StartLoc, EndLoc); | ||||||
13478 | } | ||||||
13479 | |||||||
13480 | OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, | ||||||
13481 | SourceLocation EndLoc) { | ||||||
13482 | return new (Context) OMPAcqRelClause(StartLoc, EndLoc); | ||||||
13483 | } | ||||||
13484 | |||||||
13485 | OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, | ||||||
13486 | SourceLocation EndLoc) { | ||||||
13487 | return new (Context) OMPAcquireClause(StartLoc, EndLoc); | ||||||
13488 | } | ||||||
13489 | |||||||
13490 | OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, | ||||||
13491 | SourceLocation EndLoc) { | ||||||
13492 | return new (Context) OMPReleaseClause(StartLoc, EndLoc); | ||||||
13493 | } | ||||||
13494 | |||||||
13495 | OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, | ||||||
13496 | SourceLocation EndLoc) { | ||||||
13497 | return new (Context) OMPRelaxedClause(StartLoc, EndLoc); | ||||||
13498 | } | ||||||
13499 | |||||||
13500 | OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, | ||||||
13501 | SourceLocation EndLoc) { | ||||||
13502 | return new (Context) OMPThreadsClause(StartLoc, EndLoc); | ||||||
13503 | } | ||||||
13504 | |||||||
13505 | OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, | ||||||
13506 | SourceLocation EndLoc) { | ||||||
13507 | return new (Context) OMPSIMDClause(StartLoc, EndLoc); | ||||||
13508 | } | ||||||
13509 | |||||||
13510 | OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, | ||||||
13511 | SourceLocation EndLoc) { | ||||||
13512 | return new (Context) OMPNogroupClause(StartLoc, EndLoc); | ||||||
13513 | } | ||||||
13514 | |||||||
13515 | OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, | ||||||
13516 | SourceLocation EndLoc) { | ||||||
13517 | return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); | ||||||
13518 | } | ||||||
13519 | |||||||
13520 | OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, | ||||||
13521 | SourceLocation EndLoc) { | ||||||
13522 | return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); | ||||||
13523 | } | ||||||
13524 | |||||||
13525 | OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, | ||||||
13526 | SourceLocation EndLoc) { | ||||||
13527 | return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); | ||||||
13528 | } | ||||||
13529 | |||||||
13530 | OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, | ||||||
13531 | SourceLocation EndLoc) { | ||||||
13532 | return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); | ||||||
13533 | } | ||||||
13534 | |||||||
13535 | OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc, | ||||||
13536 | SourceLocation EndLoc) { | ||||||
13537 | return new (Context) OMPDestroyClause(StartLoc, EndLoc); | ||||||
13538 | } | ||||||
13539 | |||||||
13540 | OMPClause *Sema::ActOnOpenMPVarListClause( | ||||||
13541 | OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr, | ||||||
13542 | const OMPVarListLocTy &Locs, SourceLocation ColonLoc, | ||||||
13543 | CXXScopeSpec &ReductionOrMapperIdScopeSpec, | ||||||
13544 | DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, | ||||||
13545 | ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, | ||||||
13546 | ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, | ||||||
13547 | SourceLocation ExtraModifierLoc, | ||||||
13548 | ArrayRef<OpenMPMotionModifierKind> MotionModifiers, | ||||||
13549 | ArrayRef<SourceLocation> MotionModifiersLoc) { | ||||||
13550 | SourceLocation StartLoc = Locs.StartLoc; | ||||||
13551 | SourceLocation LParenLoc = Locs.LParenLoc; | ||||||
13552 | SourceLocation EndLoc = Locs.EndLoc; | ||||||
13553 | OMPClause *Res = nullptr; | ||||||
13554 | switch (Kind) { | ||||||
13555 | case OMPC_private: | ||||||
13556 | Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||||
13557 | break; | ||||||
13558 | case OMPC_firstprivate: | ||||||
13559 | Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||||
13560 | break; | ||||||
13561 | case OMPC_lastprivate: | ||||||
13562 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13563, __PRETTY_FUNCTION__)) | ||||||
13563 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13563, __PRETTY_FUNCTION__)); | ||||||
13564 | Res = ActOnOpenMPLastprivateClause( | ||||||
13565 | VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), | ||||||
13566 | ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); | ||||||
13567 | break; | ||||||
13568 | case OMPC_shared: | ||||||
13569 | Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||||
13570 | break; | ||||||
13571 | case OMPC_reduction: | ||||||
13572 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13573, __PRETTY_FUNCTION__)) | ||||||
13573 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13573, __PRETTY_FUNCTION__)); | ||||||
13574 | Res = ActOnOpenMPReductionClause( | ||||||
13575 | VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier), | ||||||
13576 | StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc, | ||||||
13577 | ReductionOrMapperIdScopeSpec, ReductionOrMapperId); | ||||||
13578 | break; | ||||||
13579 | case OMPC_task_reduction: | ||||||
13580 | Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, | ||||||
13581 | EndLoc, ReductionOrMapperIdScopeSpec, | ||||||
13582 | ReductionOrMapperId); | ||||||
13583 | break; | ||||||
13584 | case OMPC_in_reduction: | ||||||
13585 | Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, | ||||||
13586 | EndLoc, ReductionOrMapperIdScopeSpec, | ||||||
13587 | ReductionOrMapperId); | ||||||
13588 | break; | ||||||
13589 | case OMPC_linear: | ||||||
13590 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13591, __PRETTY_FUNCTION__)) | ||||||
13591 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13591, __PRETTY_FUNCTION__)); | ||||||
13592 | Res = ActOnOpenMPLinearClause( | ||||||
13593 | VarList, DepModOrTailExpr, StartLoc, LParenLoc, | ||||||
13594 | static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc, | ||||||
13595 | ColonLoc, EndLoc); | ||||||
13596 | break; | ||||||
13597 | case OMPC_aligned: | ||||||
13598 | Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc, | ||||||
13599 | LParenLoc, ColonLoc, EndLoc); | ||||||
13600 | break; | ||||||
13601 | case OMPC_copyin: | ||||||
13602 | Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||||
13603 | break; | ||||||
13604 | case OMPC_copyprivate: | ||||||
13605 | Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||||
13606 | break; | ||||||
13607 | case OMPC_flush: | ||||||
13608 | Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||||
13609 | break; | ||||||
13610 | case OMPC_depend: | ||||||
13611 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13612, __PRETTY_FUNCTION__)) | ||||||
13612 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13612, __PRETTY_FUNCTION__)); | ||||||
13613 | Res = ActOnOpenMPDependClause( | ||||||
13614 | DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier), | ||||||
13615 | ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); | ||||||
13616 | break; | ||||||
13617 | case OMPC_map: | ||||||
13618 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13619, __PRETTY_FUNCTION__)) | ||||||
13619 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13619, __PRETTY_FUNCTION__)); | ||||||
13620 | Res = ActOnOpenMPMapClause( | ||||||
13621 | MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec, | ||||||
13622 | ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier), | ||||||
13623 | IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs); | ||||||
13624 | break; | ||||||
13625 | case OMPC_to: | ||||||
13626 | Res = ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc, | ||||||
13627 | ReductionOrMapperIdScopeSpec, ReductionOrMapperId, | ||||||
13628 | ColonLoc, VarList, Locs); | ||||||
13629 | break; | ||||||
13630 | case OMPC_from: | ||||||
13631 | Res = ActOnOpenMPFromClause(MotionModifiers, MotionModifiersLoc, | ||||||
13632 | ReductionOrMapperIdScopeSpec, | ||||||
13633 | ReductionOrMapperId, ColonLoc, VarList, Locs); | ||||||
13634 | break; | ||||||
13635 | case OMPC_use_device_ptr: | ||||||
13636 | Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); | ||||||
13637 | break; | ||||||
13638 | case OMPC_use_device_addr: | ||||||
13639 | Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs); | ||||||
13640 | break; | ||||||
13641 | case OMPC_is_device_ptr: | ||||||
13642 | Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); | ||||||
13643 | break; | ||||||
13644 | case OMPC_allocate: | ||||||
13645 | Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc, | ||||||
13646 | LParenLoc, ColonLoc, EndLoc); | ||||||
13647 | break; | ||||||
13648 | case OMPC_nontemporal: | ||||||
13649 | Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||||
13650 | break; | ||||||
13651 | case OMPC_inclusive: | ||||||
13652 | Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||||
13653 | break; | ||||||
13654 | case OMPC_exclusive: | ||||||
13655 | Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||||
13656 | break; | ||||||
13657 | case OMPC_affinity: | ||||||
13658 | Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc, | ||||||
13659 | DepModOrTailExpr, VarList); | ||||||
13660 | break; | ||||||
13661 | case OMPC_if: | ||||||
13662 | case OMPC_depobj: | ||||||
13663 | case OMPC_final: | ||||||
13664 | case OMPC_num_threads: | ||||||
13665 | case OMPC_safelen: | ||||||
13666 | case OMPC_simdlen: | ||||||
13667 | case OMPC_allocator: | ||||||
13668 | case OMPC_collapse: | ||||||
13669 | case OMPC_default: | ||||||
13670 | case OMPC_proc_bind: | ||||||
13671 | case OMPC_schedule: | ||||||
13672 | case OMPC_ordered: | ||||||
13673 | case OMPC_nowait: | ||||||
13674 | case OMPC_untied: | ||||||
13675 | case OMPC_mergeable: | ||||||
13676 | case OMPC_threadprivate: | ||||||
13677 | case OMPC_read: | ||||||
13678 | case OMPC_write: | ||||||
13679 | case OMPC_update: | ||||||
13680 | case OMPC_capture: | ||||||
13681 | case OMPC_seq_cst: | ||||||
13682 | case OMPC_acq_rel: | ||||||
13683 | case OMPC_acquire: | ||||||
13684 | case OMPC_release: | ||||||
13685 | case OMPC_relaxed: | ||||||
13686 | case OMPC_device: | ||||||
13687 | case OMPC_threads: | ||||||
13688 | case OMPC_simd: | ||||||
13689 | case OMPC_num_teams: | ||||||
13690 | case OMPC_thread_limit: | ||||||
13691 | case OMPC_priority: | ||||||
13692 | case OMPC_grainsize: | ||||||
13693 | case OMPC_nogroup: | ||||||
13694 | case OMPC_num_tasks: | ||||||
13695 | case OMPC_hint: | ||||||
13696 | case OMPC_dist_schedule: | ||||||
13697 | case OMPC_defaultmap: | ||||||
13698 | case OMPC_unknown: | ||||||
13699 | case OMPC_uniform: | ||||||
13700 | case OMPC_unified_address: | ||||||
13701 | case OMPC_unified_shared_memory: | ||||||
13702 | case OMPC_reverse_offload: | ||||||
13703 | case OMPC_dynamic_allocators: | ||||||
13704 | case OMPC_atomic_default_mem_order: | ||||||
13705 | case OMPC_device_type: | ||||||
13706 | case OMPC_match: | ||||||
13707 | case OMPC_order: | ||||||
13708 | case OMPC_destroy: | ||||||
13709 | case OMPC_detach: | ||||||
13710 | case OMPC_uses_allocators: | ||||||
13711 | default: | ||||||
13712 | llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13712); | ||||||
13713 | } | ||||||
13714 | return Res; | ||||||
13715 | } | ||||||
13716 | |||||||
13717 | ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, | ||||||
13718 | ExprObjectKind OK, SourceLocation Loc) { | ||||||
13719 | ExprResult Res = BuildDeclRefExpr( | ||||||
13720 | Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); | ||||||
13721 | if (!Res.isUsable()) | ||||||
13722 | return ExprError(); | ||||||
13723 | if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { | ||||||
13724 | Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); | ||||||
13725 | if (!Res.isUsable()) | ||||||
13726 | return ExprError(); | ||||||
13727 | } | ||||||
13728 | if (VK != VK_LValue && Res.get()->isGLValue()) { | ||||||
13729 | Res = DefaultLvalueConversion(Res.get()); | ||||||
13730 | if (!Res.isUsable()) | ||||||
13731 | return ExprError(); | ||||||
13732 | } | ||||||
13733 | return Res; | ||||||
13734 | } | ||||||
13735 | |||||||
13736 | OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, | ||||||
13737 | SourceLocation StartLoc, | ||||||
13738 | SourceLocation LParenLoc, | ||||||
13739 | SourceLocation EndLoc) { | ||||||
13740 | SmallVector<Expr *, 8> Vars; | ||||||
13741 | SmallVector<Expr *, 8> PrivateCopies; | ||||||
13742 | for (Expr *RefExpr : VarList) { | ||||||
13743 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13743, __PRETTY_FUNCTION__)); | ||||||
13744 | SourceLocation ELoc; | ||||||
13745 | SourceRange ERange; | ||||||
13746 | Expr *SimpleRefExpr = RefExpr; | ||||||
13747 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||||
13748 | if (Res.second) { | ||||||
13749 | // It will be analyzed later. | ||||||
13750 | Vars.push_back(RefExpr); | ||||||
13751 | PrivateCopies.push_back(nullptr); | ||||||
13752 | } | ||||||
13753 | ValueDecl *D = Res.first; | ||||||
13754 | if (!D) | ||||||
13755 | continue; | ||||||
13756 | |||||||
13757 | QualType Type = D->getType(); | ||||||
13758 | auto *VD = dyn_cast<VarDecl>(D); | ||||||
13759 | |||||||
13760 | // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] | ||||||
13761 | // A variable that appears in a private clause must not have an incomplete | ||||||
13762 | // type or a reference type. | ||||||
13763 | if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) | ||||||
13764 | continue; | ||||||
13765 | Type = Type.getNonReferenceType(); | ||||||
13766 | |||||||
13767 | // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] | ||||||
13768 | // A variable that is privatized must not have a const-qualified type | ||||||
13769 | // unless it is of class type with a mutable member. This restriction does | ||||||
13770 | // not apply to the firstprivate clause. | ||||||
13771 | // | ||||||
13772 | // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] | ||||||
13773 | // A variable that appears in a private clause must not have a | ||||||
13774 | // const-qualified type unless it is of class type with a mutable member. | ||||||
13775 | if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) | ||||||
13776 | continue; | ||||||
13777 | |||||||
13778 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||
13779 | // in a Construct] | ||||||
13780 | // Variables with the predetermined data-sharing attributes may not be | ||||||
13781 | // listed in data-sharing attributes clauses, except for the cases | ||||||
13782 | // listed below. For these exceptions only, listing a predetermined | ||||||
13783 | // variable in a data-sharing attribute clause is allowed and overrides | ||||||
13784 | // the variable's predetermined data-sharing attributes. | ||||||
13785 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); | ||||||
13786 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { | ||||||
13787 | Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) | ||||||
13788 | << getOpenMPClauseName(OMPC_private); | ||||||
13789 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||
13790 | continue; | ||||||
13791 | } | ||||||
13792 | |||||||
13793 | OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); | ||||||
13794 | // Variably modified types are not supported for tasks. | ||||||
13795 | if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && | ||||||
13796 | isOpenMPTaskingDirective(CurrDir)) { | ||||||
13797 | Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) | ||||||
13798 | << getOpenMPClauseName(OMPC_private) << Type | ||||||
13799 | << getOpenMPDirectiveName(CurrDir); | ||||||
13800 | bool IsDecl = | ||||||
13801 | !VD || | ||||||
13802 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||||
13803 | Diag(D->getLocation(), | ||||||
13804 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||
13805 | << D; | ||||||
13806 | continue; | ||||||
13807 | } | ||||||
13808 | |||||||
13809 | // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] | ||||||
13810 | // A list item cannot appear in both a map clause and a data-sharing | ||||||
13811 | // attribute clause on the same construct | ||||||
13812 | // | ||||||
13813 | // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] | ||||||
13814 | // A list item cannot appear in both a map clause and a data-sharing | ||||||
13815 | // attribute clause on the same construct unless the construct is a | ||||||
13816 | // combined construct. | ||||||
13817 | if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || | ||||||
13818 | CurrDir == OMPD_target) { | ||||||
13819 | OpenMPClauseKind ConflictKind; | ||||||
13820 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->checkMappableExprComponentListsForDecl( | ||||||
13821 | VD, /*CurrentRegionOnly=*/true, | ||||||
13822 | [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, | ||||||
13823 | OpenMPClauseKind WhereFoundClauseKind) -> bool { | ||||||
13824 | ConflictKind = WhereFoundClauseKind; | ||||||
13825 | return true; | ||||||
13826 | })) { | ||||||
13827 | Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) | ||||||
13828 | << getOpenMPClauseName(OMPC_private) | ||||||
13829 | << getOpenMPClauseName(ConflictKind) | ||||||
13830 | << getOpenMPDirectiveName(CurrDir); | ||||||
13831 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||
13832 | continue; | ||||||
13833 | } | ||||||
13834 | } | ||||||
13835 | |||||||
13836 | // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] | ||||||
13837 | // A variable of class type (or array thereof) that appears in a private | ||||||
13838 | // clause requires an accessible, unambiguous default constructor for the | ||||||
13839 | // class type. | ||||||
13840 | // Generate helper private variable and initialize it with the default | ||||||
13841 | // value. The address of the original variable is replaced by the address of | ||||||
13842 | // the new private variable in CodeGen. This new variable is not added to | ||||||
13843 | // IdResolver, so the code in the OpenMP region uses original variable for | ||||||
13844 | // proper diagnostics. | ||||||
13845 | Type = Type.getUnqualifiedType(); | ||||||
13846 | VarDecl *VDPrivate = | ||||||
13847 | buildVarDecl(*this, ELoc, Type, D->getName(), | ||||||
13848 | D->hasAttrs() ? &D->getAttrs() : nullptr, | ||||||
13849 | VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); | ||||||
13850 | ActOnUninitializedDecl(VDPrivate); | ||||||
13851 | if (VDPrivate->isInvalidDecl()) | ||||||
13852 | continue; | ||||||
13853 | DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( | ||||||
13854 | *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); | ||||||
13855 | |||||||
13856 | DeclRefExpr *Ref = nullptr; | ||||||
13857 | if (!VD && !CurContext->isDependentContext()) | ||||||
13858 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); | ||||||
13859 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); | ||||||
13860 | Vars.push_back((VD || CurContext->isDependentContext()) | ||||||
13861 | ? RefExpr->IgnoreParens() | ||||||
13862 | : Ref); | ||||||
13863 | PrivateCopies.push_back(VDPrivateRefExpr); | ||||||
13864 | } | ||||||
13865 | |||||||
13866 | if (Vars.empty()) | ||||||
13867 | return nullptr; | ||||||
13868 | |||||||
13869 | return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, | ||||||
13870 | PrivateCopies); | ||||||
13871 | } | ||||||
13872 | |||||||
13873 | namespace { | ||||||
13874 | class DiagsUninitializedSeveretyRAII { | ||||||
13875 | private: | ||||||
13876 | DiagnosticsEngine &Diags; | ||||||
13877 | SourceLocation SavedLoc; | ||||||
13878 | bool IsIgnored = false; | ||||||
13879 | |||||||
13880 | public: | ||||||
13881 | DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, | ||||||
13882 | bool IsIgnored) | ||||||
13883 | : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { | ||||||
13884 | if (!IsIgnored) { | ||||||
13885 | Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, | ||||||
13886 | /*Map*/ diag::Severity::Ignored, Loc); | ||||||
13887 | } | ||||||
13888 | } | ||||||
13889 | ~DiagsUninitializedSeveretyRAII() { | ||||||
13890 | if (!IsIgnored) | ||||||
13891 | Diags.popMappings(SavedLoc); | ||||||
13892 | } | ||||||
13893 | }; | ||||||
13894 | } | ||||||
13895 | |||||||
13896 | OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, | ||||||
13897 | SourceLocation StartLoc, | ||||||
13898 | SourceLocation LParenLoc, | ||||||
13899 | SourceLocation EndLoc) { | ||||||
13900 | SmallVector<Expr *, 8> Vars; | ||||||
13901 | SmallVector<Expr *, 8> PrivateCopies; | ||||||
13902 | SmallVector<Expr *, 8> Inits; | ||||||
13903 | SmallVector<Decl *, 4> ExprCaptures; | ||||||
13904 | bool IsImplicitClause = | ||||||
13905 | StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); | ||||||
13906 | SourceLocation ImplicitClauseLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(); | ||||||
13907 | |||||||
13908 | for (Expr *RefExpr : VarList) { | ||||||
13909 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13909, __PRETTY_FUNCTION__)); | ||||||
13910 | SourceLocation ELoc; | ||||||
13911 | SourceRange ERange; | ||||||
13912 | Expr *SimpleRefExpr = RefExpr; | ||||||
13913 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||||
13914 | if (Res.second) { | ||||||
13915 | // It will be analyzed later. | ||||||
13916 | Vars.push_back(RefExpr); | ||||||
13917 | PrivateCopies.push_back(nullptr); | ||||||
13918 | Inits.push_back(nullptr); | ||||||
13919 | } | ||||||
13920 | ValueDecl *D = Res.first; | ||||||
13921 | if (!D) | ||||||
13922 | continue; | ||||||
13923 | |||||||
13924 | ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; | ||||||
13925 | QualType Type = D->getType(); | ||||||
13926 | auto *VD = dyn_cast<VarDecl>(D); | ||||||
13927 | |||||||
13928 | // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] | ||||||
13929 | // A variable that appears in a private clause must not have an incomplete | ||||||
13930 | // type or a reference type. | ||||||
13931 | if (RequireCompleteType(ELoc, Type, | ||||||
13932 | diag::err_omp_firstprivate_incomplete_type)) | ||||||
13933 | continue; | ||||||
13934 | Type = Type.getNonReferenceType(); | ||||||
13935 | |||||||
13936 | // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] | ||||||
13937 | // A variable of class type (or array thereof) that appears in a private | ||||||
13938 | // clause requires an accessible, unambiguous copy constructor for the | ||||||
13939 | // class type. | ||||||
13940 | QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); | ||||||
13941 | |||||||
13942 | // If an implicit firstprivate variable found it was checked already. | ||||||
13943 | DSAStackTy::DSAVarData TopDVar; | ||||||
13944 | if (!IsImplicitClause) { | ||||||
13945 | DSAStackTy::DSAVarData DVar = | ||||||
13946 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); | ||||||
13947 | TopDVar = DVar; | ||||||
13948 | OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); | ||||||
13949 | bool IsConstant = ElemType.isConstant(Context); | ||||||
13950 | // OpenMP [2.4.13, Data-sharing Attribute Clauses] | ||||||
13951 | // A list item that specifies a given variable may not appear in more | ||||||
13952 | // than one clause on the same directive, except that a variable may be | ||||||
13953 | // specified in both firstprivate and lastprivate clauses. | ||||||
13954 | // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] | ||||||
13955 | // A list item may appear in a firstprivate or lastprivate clause but not | ||||||
13956 | // both. | ||||||
13957 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && | ||||||
13958 | (isOpenMPDistributeDirective(CurrDir) || | ||||||
13959 | DVar.CKind != OMPC_lastprivate) && | ||||||
13960 | DVar.RefExpr) { | ||||||
13961 | Diag(ELoc, diag::err_omp_wrong_dsa) | ||||||
13962 | << getOpenMPClauseName(DVar.CKind) | ||||||
13963 | << getOpenMPClauseName(OMPC_firstprivate); | ||||||
13964 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||
13965 | continue; | ||||||
13966 | } | ||||||
13967 | |||||||
13968 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||
13969 | // in a Construct] | ||||||
13970 | // Variables with the predetermined data-sharing attributes may not be | ||||||
13971 | // listed in data-sharing attributes clauses, except for the cases | ||||||
13972 | // listed below. For these exceptions only, listing a predetermined | ||||||
13973 | // variable in a data-sharing attribute clause is allowed and overrides | ||||||
13974 | // the variable's predetermined data-sharing attributes. | ||||||
13975 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||
13976 | // in a Construct, C/C++, p.2] | ||||||
13977 | // Variables with const-qualified type having no mutable member may be | ||||||
13978 | // listed in a firstprivate clause, even if they are static data members. | ||||||
13979 | if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && | ||||||
13980 | DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { | ||||||
13981 | Diag(ELoc, diag::err_omp_wrong_dsa) | ||||||
13982 | << getOpenMPClauseName(DVar.CKind) | ||||||
13983 | << getOpenMPClauseName(OMPC_firstprivate); | ||||||
13984 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||
13985 | continue; | ||||||
13986 | } | ||||||
13987 | |||||||
13988 | // OpenMP [2.9.3.4, Restrictions, p.2] | ||||||
13989 | // A list item that is private within a parallel region must not appear | ||||||
13990 | // in a firstprivate clause on a worksharing construct if any of the | ||||||
13991 | // worksharing regions arising from the worksharing construct ever bind | ||||||
13992 | // to any of the parallel regions arising from the parallel construct. | ||||||
13993 | // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] | ||||||
13994 | // A list item that is private within a teams region must not appear in a | ||||||
13995 | // firstprivate clause on a distribute construct if any of the distribute | ||||||
13996 | // regions arising from the distribute construct ever bind to any of the | ||||||
13997 | // teams regions arising from the teams construct. | ||||||
13998 | // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] | ||||||
13999 | // A list item that appears in a reduction clause of a teams construct | ||||||
14000 | // must not appear in a firstprivate clause on a distribute construct if | ||||||
14001 | // any of the distribute regions arising from the distribute construct | ||||||
14002 | // ever bind to any of the teams regions arising from the teams construct. | ||||||
14003 | if ((isOpenMPWorksharingDirective(CurrDir) || | ||||||
14004 | isOpenMPDistributeDirective(CurrDir)) && | ||||||
14005 | !isOpenMPParallelDirective(CurrDir) && | ||||||
14006 | !isOpenMPTeamsDirective(CurrDir)) { | ||||||
14007 | DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getImplicitDSA(D, true); | ||||||
14008 | if (DVar.CKind != OMPC_shared && | ||||||
14009 | (isOpenMPParallelDirective(DVar.DKind) || | ||||||
14010 | isOpenMPTeamsDirective(DVar.DKind) || | ||||||
14011 | DVar.DKind == OMPD_unknown)) { | ||||||
14012 | Diag(ELoc, diag::err_omp_required_access) | ||||||
14013 | << getOpenMPClauseName(OMPC_firstprivate) | ||||||
14014 | << getOpenMPClauseName(OMPC_shared); | ||||||
14015 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||
14016 | continue; | ||||||
14017 | } | ||||||
14018 | } | ||||||
14019 | // OpenMP [2.9.3.4, Restrictions, p.3] | ||||||
14020 | // A list item that appears in a reduction clause of a parallel construct | ||||||
14021 | // must not appear in a firstprivate clause on a worksharing or task | ||||||
14022 | // construct if any of the worksharing or task regions arising from the | ||||||
14023 | // worksharing or task construct ever bind to any of the parallel regions | ||||||
14024 | // arising from the parallel construct. | ||||||
14025 | // OpenMP [2.9.3.4, Restrictions, p.4] | ||||||
14026 | // A list item that appears in a reduction clause in worksharing | ||||||
14027 | // construct must not appear in a firstprivate clause in a task construct | ||||||
14028 | // encountered during execution of any of the worksharing regions arising | ||||||
14029 | // from the worksharing construct. | ||||||
14030 | if (isOpenMPTaskingDirective(CurrDir)) { | ||||||
14031 | DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasInnermostDSA( | ||||||
14032 | D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, | ||||||
14033 | [](OpenMPDirectiveKind K) { | ||||||
14034 | return isOpenMPParallelDirective(K) || | ||||||
14035 | isOpenMPWorksharingDirective(K) || | ||||||
14036 | isOpenMPTeamsDirective(K); | ||||||
14037 | }, | ||||||
14038 | /*FromParent=*/true); | ||||||
14039 | if (DVar.CKind == OMPC_reduction && | ||||||
14040 | (isOpenMPParallelDirective(DVar.DKind) || | ||||||
14041 | isOpenMPWorksharingDirective(DVar.DKind) || | ||||||
14042 | isOpenMPTeamsDirective(DVar.DKind))) { | ||||||
14043 | Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) | ||||||
14044 | << getOpenMPDirectiveName(DVar.DKind); | ||||||
14045 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||
14046 | continue; | ||||||
14047 | } | ||||||
14048 | } | ||||||
14049 | |||||||
14050 | // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] | ||||||
14051 | // A list item cannot appear in both a map clause and a data-sharing | ||||||
14052 | // attribute clause on the same construct | ||||||
14053 | // | ||||||
14054 | // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] | ||||||
14055 | // A list item cannot appear in both a map clause and a data-sharing | ||||||
14056 | // attribute clause on the same construct unless the construct is a | ||||||
14057 | // combined construct. | ||||||
14058 | if ((LangOpts.OpenMP <= 45 && | ||||||
14059 | isOpenMPTargetExecutionDirective(CurrDir)) || | ||||||
14060 | CurrDir == OMPD_target) { | ||||||
14061 | OpenMPClauseKind ConflictKind; | ||||||
14062 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->checkMappableExprComponentListsForDecl( | ||||||
14063 | VD, /*CurrentRegionOnly=*/true, | ||||||
14064 | [&ConflictKind]( | ||||||
14065 | OMPClauseMappableExprCommon::MappableExprComponentListRef, | ||||||
14066 | OpenMPClauseKind WhereFoundClauseKind) { | ||||||
14067 | ConflictKind = WhereFoundClauseKind; | ||||||
14068 | return true; | ||||||
14069 | })) { | ||||||
14070 | Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) | ||||||
14071 | << getOpenMPClauseName(OMPC_firstprivate) | ||||||
14072 | << getOpenMPClauseName(ConflictKind) | ||||||
14073 | << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()); | ||||||
14074 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||
14075 | continue; | ||||||
14076 | } | ||||||
14077 | } | ||||||
14078 | } | ||||||
14079 | |||||||
14080 | // Variably modified types are not supported for tasks. | ||||||
14081 | if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && | ||||||
14082 | isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective())) { | ||||||
14083 | Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) | ||||||
14084 | << getOpenMPClauseName(OMPC_firstprivate) << Type | ||||||
14085 | << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()); | ||||||
14086 | bool IsDecl = | ||||||
14087 | !VD || | ||||||
14088 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||||
14089 | Diag(D->getLocation(), | ||||||
14090 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||
14091 | << D; | ||||||
14092 | continue; | ||||||
14093 | } | ||||||
14094 | |||||||
14095 | Type = Type.getUnqualifiedType(); | ||||||
14096 | VarDecl *VDPrivate = | ||||||
14097 | buildVarDecl(*this, ELoc, Type, D->getName(), | ||||||
14098 | D->hasAttrs() ? &D->getAttrs() : nullptr, | ||||||
14099 | VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); | ||||||
14100 | // Generate helper private variable and initialize it with the value of the | ||||||
14101 | // original variable. The address of the original variable is replaced by | ||||||
14102 | // the address of the new private variable in the CodeGen. This new variable | ||||||
14103 | // is not added to IdResolver, so the code in the OpenMP region uses | ||||||
14104 | // original variable for proper diagnostics and variable capturing. | ||||||
14105 | Expr *VDInitRefExpr = nullptr; | ||||||
14106 | // For arrays generate initializer for single element and replace it by the | ||||||
14107 | // original array element in CodeGen. | ||||||
14108 | if (Type->isArrayType()) { | ||||||
14109 | VarDecl *VDInit = | ||||||
14110 | buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); | ||||||
14111 | VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); | ||||||
14112 | Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); | ||||||
14113 | ElemType = ElemType.getUnqualifiedType(); | ||||||
14114 | VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, | ||||||
14115 | ".firstprivate.temp"); | ||||||
14116 | InitializedEntity Entity = | ||||||
14117 | InitializedEntity::InitializeVariable(VDInitTemp); | ||||||
14118 | InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); | ||||||
14119 | |||||||
14120 | InitializationSequence InitSeq(*this, Entity, Kind, Init); | ||||||
14121 | ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); | ||||||
14122 | if (Result.isInvalid()) | ||||||
14123 | VDPrivate->setInvalidDecl(); | ||||||
14124 | else | ||||||
14125 | VDPrivate->setInit(Result.getAs<Expr>()); | ||||||
14126 | // Remove temp variable declaration. | ||||||
14127 | Context.Deallocate(VDInitTemp); | ||||||
14128 | } else { | ||||||
14129 | VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, | ||||||
14130 | ".firstprivate.temp"); | ||||||
14131 | VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), | ||||||
14132 | RefExpr->getExprLoc()); | ||||||
14133 | AddInitializerToDecl(VDPrivate, | ||||||
14134 | DefaultLvalueConversion(VDInitRefExpr).get(), | ||||||
14135 | /*DirectInit=*/false); | ||||||
14136 | } | ||||||
14137 | if (VDPrivate->isInvalidDecl()) { | ||||||
14138 | if (IsImplicitClause) { | ||||||
14139 | Diag(RefExpr->getExprLoc(), | ||||||
14140 | diag::note_omp_task_predetermined_firstprivate_here); | ||||||
14141 | } | ||||||
14142 | continue; | ||||||
14143 | } | ||||||
14144 | CurContext->addDecl(VDPrivate); | ||||||
14145 | DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( | ||||||
14146 | *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), | ||||||
14147 | RefExpr->getExprLoc()); | ||||||
14148 | DeclRefExpr *Ref = nullptr; | ||||||
14149 | if (!VD && !CurContext->isDependentContext()) { | ||||||
14150 | if (TopDVar.CKind == OMPC_lastprivate) { | ||||||
14151 | Ref = TopDVar.PrivateCopy; | ||||||
14152 | } else { | ||||||
14153 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); | ||||||
14154 | if (!isOpenMPCapturedDecl(D)) | ||||||
14155 | ExprCaptures.push_back(Ref->getDecl()); | ||||||
14156 | } | ||||||
14157 | } | ||||||
14158 | if (!IsImplicitClause) | ||||||
14159 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); | ||||||
14160 | Vars.push_back((VD || CurContext->isDependentContext()) | ||||||
14161 | ? RefExpr->IgnoreParens() | ||||||
14162 | : Ref); | ||||||
14163 | PrivateCopies.push_back(VDPrivateRefExpr); | ||||||
14164 | Inits.push_back(VDInitRefExpr); | ||||||
14165 | } | ||||||
14166 | |||||||
14167 | if (Vars.empty()) | ||||||
14168 | return nullptr; | ||||||
14169 | |||||||
14170 | return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, | ||||||
14171 | Vars, PrivateCopies, Inits, | ||||||
14172 | buildPreInits(Context, ExprCaptures)); | ||||||
14173 | } | ||||||
14174 | |||||||
14175 | OMPClause *Sema::ActOnOpenMPLastprivateClause( | ||||||
14176 | ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, | ||||||
14177 | SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, | ||||||
14178 | SourceLocation LParenLoc, SourceLocation EndLoc) { | ||||||
14179 | if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { | ||||||
14180 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 14180, __PRETTY_FUNCTION__)); | ||||||
14181 | Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) | ||||||
14182 | << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, | ||||||
14183 | /*Last=*/OMPC_LASTPRIVATE_unknown) | ||||||
14184 | << getOpenMPClauseName(OMPC_lastprivate); | ||||||
14185 | return nullptr; | ||||||
14186 | } | ||||||
14187 | |||||||
14188 | SmallVector<Expr *, 8> Vars; | ||||||
14189 | SmallVector<Expr *, 8> SrcExprs; | ||||||
14190 | SmallVector<Expr *, 8> DstExprs; | ||||||
14191 | SmallVector<Expr *, 8> AssignmentOps; | ||||||
14192 | SmallVector<Decl *, 4> ExprCaptures; | ||||||
14193 | SmallVector<Expr *, 4> ExprPostUpdates; | ||||||
14194 | for (Expr *RefExpr : VarList) { | ||||||
14195 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 14195, __PRETTY_FUNCTION__)); | ||||||
14196 | SourceLocation ELoc; | ||||||
14197 | SourceRange ERange; | ||||||
14198 | Expr *SimpleRefExpr = RefExpr; | ||||||
14199 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||||
14200 | if (Res.second) { | ||||||
14201 | // It will be analyzed later. | ||||||
14202 | Vars.push_back(RefExpr); | ||||||
14203 | SrcExprs.push_back(nullptr); | ||||||
14204 | DstExprs.push_back(nullptr); | ||||||
14205 | AssignmentOps.push_back(nullptr); | ||||||
14206 | } | ||||||
14207 | ValueDecl *D = Res.first; | ||||||
14208 | if (!D) | ||||||
14209 | continue; | ||||||
14210 | |||||||
14211 | QualType Type = D->getType(); | ||||||
14212 | auto *VD = dyn_cast<VarDecl>(D); | ||||||
14213 | |||||||
14214 | // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] | ||||||
14215 | // A variable that appears in a lastprivate clause must not have an | ||||||
14216 | // incomplete type or a reference type. | ||||||
14217 | if (RequireCompleteType(ELoc, Type, | ||||||
14218 | diag::err_omp_lastprivate_incomplete_type)) | ||||||
14219 | continue; | ||||||
14220 | Type = Type.getNonReferenceType(); | ||||||
14221 | |||||||
14222 | // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] | ||||||
14223 | // A variable that is privatized must not have a const-qualified type | ||||||
14224 | // unless it is of class type with a mutable member. This restriction does | ||||||
14225 | // not apply to the firstprivate clause. | ||||||
14226 | // | ||||||
14227 | // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] | ||||||
14228 | // A variable that appears in a lastprivate clause must not have a | ||||||
14229 | // const-qualified type unless it is of class type with a mutable member. | ||||||
14230 | if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) | ||||||
14231 | continue; | ||||||
14232 | |||||||
14233 | // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] | ||||||
14234 | // A list item that appears in a lastprivate clause with the conditional | ||||||
14235 | // modifier must be a scalar variable. | ||||||
14236 | if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { | ||||||
14237 | Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); | ||||||
14238 | bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == | ||||||
14239 | VarDecl::DeclarationOnly; | ||||||
14240 | Diag(D->getLocation(), | ||||||
14241 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||
14242 | << D; | ||||||
14243 | continue; | ||||||
14244 | } | ||||||
14245 | |||||||
14246 | OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); | ||||||
14247 | // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||
14248 | // in a Construct] | ||||||
14249 | // Variables with the predetermined data-sharing attributes may not be | ||||||
14250 | // listed in data-sharing attributes clauses, except for the cases | ||||||
14251 | // listed below. | ||||||
14252 | // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] | ||||||
14253 | // A list item may appear in a firstprivate or lastprivate clause but not | ||||||
14254 | // both. | ||||||
14255 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); | ||||||
14256 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && | ||||||
14257 | (isOpenMPDistributeDirective(CurrDir) || | ||||||
14258 | DVar.CKind != OMPC_firstprivate) && | ||||||
14259 | (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { | ||||||
14260 | Diag(ELoc, diag::err_omp_wrong_dsa) | ||||||
14261 | << getOpenMPClauseName(DVar.CKind) | ||||||
14262 | << getOpenMPClauseName(OMPC_lastprivate); | ||||||
14263 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||
14264 | continue; | ||||||
14265 | } | ||||||
14266 | |||||||
14267 | // OpenMP [2.14.3.5, Restrictions, p.2] | ||||||
14268 | // A list item that is private within a parallel region, or that appears in | ||||||
14269 | // the reduction clause of a parallel construct, must not appear in a | ||||||
14270 | // lastprivate clause on a worksharing construct if any of the corresponding | ||||||
14271 | // worksharing regions ever binds to any of the corresponding parallel | ||||||
14272 | // regions. | ||||||
14273 | DSAStackTy::DSAVarData TopDVar = DVar; | ||||||
14274 | if (isOpenMPWorksharingDirective(CurrDir) && | ||||||
14275 | !isOpenMPParallelDirective(CurrDir) && | ||||||
14276 | !isOpenMPTeamsDirective(CurrDir)) { | ||||||
14277 | DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getImplicitDSA(D, true); | ||||||
14278 | if (DVar.CKind != OMPC_shared) { | ||||||
14279 | Diag(ELoc, diag::err_omp_required_access) | ||||||
14280 | << getOpenMPClauseName(OMPC_lastprivate) | ||||||
14281 | << getOpenMPClauseName(OMPC_shared); | ||||||
14282 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||
14283 | continue; | ||||||
14284 | } | ||||||
14285 | } | ||||||
14286 | |||||||
14287 | // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] | ||||||
14288 | // A variable of class type (or array thereof) that appears in a | ||||||
14289 | // lastprivate clause requires an accessible, unambiguous default | ||||||
14290 | // constructor for the class type, unless the list item is also specified | ||||||
14291 | // in a firstprivate clause. | ||||||
14292 | // A variable of class type (or array thereof) that appears in a | ||||||
14293 | // lastprivate clause requires an accessible, unambiguous copy assignment | ||||||
14294 | // operator for the class type. | ||||||
14295 | Type = Context.getBaseElementType(Type).getNonReferenceType(); | ||||||
14296 | VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), | ||||||
14297 | Type.getUnqualifiedType(), ".lastprivate.src", | ||||||
14298 | D->hasAttrs() ? &D->getAttrs() : nullptr); | ||||||
14299 | DeclRefExpr *PseudoSrcExpr = | ||||||
14300 | buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); | ||||||
14301 | VarDecl *DstVD = | ||||||
14302 | buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", | ||||||
14303 | D->hasAttrs() ? &D->getAttrs() : nullptr); | ||||||
14304 | DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); | ||||||
14305 | // For arrays generate assignment operation for single element and replace | ||||||
14306 | // it by the original array element in CodeGen. | ||||||
14307 | ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, | ||||||
14308 | PseudoDstExpr, PseudoSrcExpr); | ||||||
14309 | if (AssignmentOp.isInvalid()) | ||||||
14310 | continue; | ||||||
14311 | AssignmentOp = | ||||||
14312 | ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); | ||||||
14313 | if (AssignmentOp.isInvalid()) | ||||||
14314 | continue; | ||||||
14315 | |||||||
14316 | DeclRefExpr *Ref = nullptr; | ||||||
14317 | if (!VD && !CurContext->isDependentContext()) { | ||||||
14318 | if (TopDVar.CKind == OMPC_firstprivate) { | ||||||
14319 | Ref = TopDVar.PrivateCopy; | ||||||
14320 | } else { | ||||||
14321 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); | ||||||
14322 | if (!isOpenMPCapturedDecl(D)) | ||||||
14323 | ExprCaptures.push_back(Ref->getDecl()); | ||||||
14324 | } | ||||||
14325 | if (TopDVar.CKind == OMPC_firstprivate || | ||||||
14326 | (!isOpenMPCapturedDecl(D) && | ||||||
14327 | Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { | ||||||
14328 | ExprResult RefRes = DefaultLvalueConversion(Ref); | ||||||
14329 | if (!RefRes.isUsable()) | ||||||
14330 | continue; | ||||||
14331 | ExprResult PostUpdateRes = | ||||||
14332 | BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, | ||||||
14333 | RefRes.get()); | ||||||
14334 | if (!PostUpdateRes.isUsable()) | ||||||
14335 | continue; | ||||||
14336 | ExprPostUpdates.push_back( | ||||||
14337 | IgnoredValueConversions(PostUpdateRes.get()).get()); | ||||||
14338 | } | ||||||
14339 | } | ||||||
14340 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); | ||||||
14341 | Vars.push_back((VD || CurContext->isDependentContext()) | ||||||
14342 | ? RefExpr->IgnoreParens() | ||||||
14343 | : Ref); | ||||||
14344 | SrcExprs.push_back(PseudoSrcExpr); | ||||||
14345 | DstExprs.push_back(PseudoDstExpr); | ||||||
14346 | AssignmentOps.push_back(AssignmentOp.get()); | ||||||
14347 | } | ||||||
14348 | |||||||
14349 | if (Vars.empty()) | ||||||
14350 | return nullptr; | ||||||
14351 | |||||||
14352 | return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, | ||||||
14353 | Vars, SrcExprs, DstExprs, AssignmentOps, | ||||||
14354 | LPKind, LPKindLoc, ColonLoc, | ||||||
14355 | buildPreInits(Context, ExprCaptures), | ||||||
14356 | buildPostUpdate(*this, ExprPostUpdates)); | ||||||
14357 | } | ||||||
14358 | |||||||
14359 | OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, | ||||||
14360 | SourceLocation StartLoc, | ||||||
14361 | SourceLocation LParenLoc, | ||||||
14362 | SourceLocation EndLoc) { | ||||||
14363 | SmallVector<Expr *, 8> Vars; | ||||||
14364 | for (Expr *RefExpr : VarList) { | ||||||
14365 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 14365, __PRETTY_FUNCTION__)); | ||||||
14366 | SourceLocation ELoc; | ||||||
14367 | SourceRange ERange; | ||||||
14368 | Expr *SimpleRefExpr = RefExpr; | ||||||
14369 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||||
14370 | if (Res.second) { | ||||||
14371 | // It will be analyzed later. | ||||||
14372 | Vars.push_back(RefExpr); | ||||||
14373 | } | ||||||
14374 | ValueDecl *D = Res.first; | ||||||
14375 | if (!D) | ||||||
14376 | continue; | ||||||
14377 | |||||||
14378 | auto *VD = dyn_cast<VarDecl>(D); | ||||||
14379 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||
14380 | // in a Construct] | ||||||
14381 | // Variables with the predetermined data-sharing attributes may not be | ||||||
14382 | // listed in data-sharing attributes clauses, except for the cases | ||||||
14383 | // listed below. For these exceptions only, listing a predetermined | ||||||
14384 | // variable in a data-sharing attribute clause is allowed and overrides | ||||||
14385 | // the variable's predetermined data-sharing attributes. | ||||||
14386 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); | ||||||
14387 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && | ||||||
14388 | DVar.RefExpr) { | ||||||
14389 | Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) | ||||||
14390 | << getOpenMPClauseName(OMPC_shared); | ||||||
14391 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||
14392 | continue; | ||||||
14393 | } | ||||||
14394 | |||||||
14395 | DeclRefExpr *Ref = nullptr; | ||||||
14396 | if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) | ||||||
14397 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); | ||||||
14398 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); | ||||||
14399 | Vars.push_back((VD || !Ref || CurContext->isDependentContext()) | ||||||
14400 | ? RefExpr->IgnoreParens() | ||||||
14401 | : Ref); | ||||||
14402 | } | ||||||
14403 | |||||||
14404 | if (Vars.empty()) | ||||||
14405 | return nullptr; | ||||||
14406 | |||||||
14407 | return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); | ||||||
14408 | } | ||||||
14409 | |||||||
14410 | namespace { | ||||||
14411 | class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { | ||||||
14412 | DSAStackTy *Stack; | ||||||
14413 | |||||||
14414 | public: | ||||||
14415 | bool VisitDeclRefExpr(DeclRefExpr *E) { | ||||||
14416 | if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { | ||||||
14417 | DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); | ||||||
14418 | if (DVar.CKind == OMPC_shared && !DVar.RefExpr) | ||||||
14419 | return false; | ||||||
14420 | if (DVar.CKind != OMPC_unknown) | ||||||
14421 | return true; | ||||||
14422 | DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( | ||||||
14423 | VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, | ||||||
14424 | /*FromParent=*/true); | ||||||
14425 | return DVarPrivate.CKind != OMPC_unknown; | ||||||
14426 | } | ||||||
14427 | return false; | ||||||
14428 | } | ||||||
14429 | bool VisitStmt(Stmt *S) { | ||||||
14430 | for (Stmt *Child : S->children()) { | ||||||
14431 | if (Child && Visit(Child)) | ||||||
14432 | return true; | ||||||
14433 | } | ||||||
14434 | return false; | ||||||
14435 | } | ||||||
14436 | explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} | ||||||
14437 | }; | ||||||
14438 | } // namespace | ||||||
14439 | |||||||
14440 | namespace { | ||||||
14441 | // Transform MemberExpression for specified FieldDecl of current class to | ||||||
14442 | // DeclRefExpr to specified OMPCapturedExprDecl. | ||||||
14443 | class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { | ||||||
14444 | typedef TreeTransform<TransformExprToCaptures> BaseTransform; | ||||||
14445 | ValueDecl *Field = nullptr; | ||||||
14446 | DeclRefExpr *CapturedExpr = nullptr; | ||||||
14447 | |||||||
14448 | public: | ||||||
14449 | TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) | ||||||
14450 | : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} | ||||||
14451 | |||||||
14452 | ExprResult TransformMemberExpr(MemberExpr *E) { | ||||||
14453 | if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && | ||||||
| |||||||
14454 | E->getMemberDecl() == Field) { | ||||||
14455 | CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); | ||||||
14456 | return CapturedExpr; | ||||||
14457 | } | ||||||
14458 | return BaseTransform::TransformMemberExpr(E); | ||||||
14459 | } | ||||||
14460 | DeclRefExpr *getCapturedExpr() { return CapturedExpr; } | ||||||
14461 | }; | ||||||
14462 | } // namespace | ||||||
14463 | |||||||
14464 | template <typename T, typename U> | ||||||
14465 | static T filterLookupForUDReductionAndMapper( | ||||||
14466 | SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { | ||||||
14467 | for (U &Set : Lookups) { | ||||||
14468 | for (auto *D : Set) { | ||||||
14469 | if (T Res = Gen(cast<ValueDecl>(D))) | ||||||
14470 | return Res; | ||||||
14471 | } | ||||||
14472 | } | ||||||
14473 | return T(); | ||||||
14474 | } | ||||||
14475 | |||||||
14476 | static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { | ||||||
14477 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 14477, __PRETTY_FUNCTION__)); | ||||||
14478 | |||||||
14479 | for (auto RD : D->redecls()) { | ||||||
14480 | // Don't bother with extra checks if we already know this one isn't visible. | ||||||
14481 | if (RD == D) | ||||||
14482 | continue; | ||||||
14483 | |||||||
14484 | auto ND = cast<NamedDecl>(RD); | ||||||
14485 | if (LookupResult::isVisible(SemaRef, ND)) | ||||||
14486 | return ND; | ||||||
14487 | } | ||||||
14488 | |||||||
14489 | return nullptr; | ||||||
14490 | } | ||||||
14491 | |||||||
14492 | static void | ||||||
14493 | argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, | ||||||
14494 | SourceLocation Loc, QualType Ty, | ||||||
14495 | SmallVectorImpl<UnresolvedSet<8>> &Lookups) { | ||||||
14496 | // Find all of the associated namespaces and classes based on the | ||||||
14497 | // arguments we have. | ||||||
14498 | Sema::AssociatedNamespaceSet AssociatedNamespaces; | ||||||
14499 | Sema::AssociatedClassSet AssociatedClasses; | ||||||
14500 | OpaqueValueExpr OVE(Loc, Ty, VK_LValue); | ||||||
14501 | SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, | ||||||
14502 | AssociatedClasses); | ||||||
14503 | |||||||
14504 | // C++ [basic.lookup.argdep]p3: | ||||||
14505 | // Let X be the lookup set produced by unqualified lookup (3.4.1) | ||||||
14506 | // and let Y be the lookup set produced by argument dependent | ||||||
14507 | // lookup (defined as follows). If X contains [...] then Y is | ||||||
14508 | // empty. Otherwise Y is the set of declarations found in the | ||||||
14509 | // namespaces associated with the argument types as described | ||||||
14510 | // below. The set of declarations found by the lookup of the name | ||||||
14511 | // is the union of X and Y. | ||||||
14512 | // | ||||||
14513 | // Here, we compute Y and add its members to the overloaded | ||||||
14514 | // candidate set. | ||||||
14515 | for (auto *NS : AssociatedNamespaces) { | ||||||
14516 | // When considering an associated namespace, the lookup is the | ||||||
14517 | // same as the lookup performed when the associated namespace is | ||||||
14518 | // used as a qualifier (3.4.3.2) except that: | ||||||
14519 | // | ||||||
14520 | // -- Any using-directives in the associated namespace are | ||||||
14521 | // ignored. | ||||||
14522 | // | ||||||
14523 | // -- Any namespace-scope friend functions declared in | ||||||
14524 | // associated classes are visible within their respective | ||||||
14525 | // namespaces even if they are not visible during an ordinary | ||||||
14526 | // lookup (11.4). | ||||||
14527 | DeclContext::lookup_result R = NS->lookup(Id.getName()); | ||||||
14528 | for (auto *D : R) { | ||||||
14529 | auto *Underlying = D; | ||||||
14530 | if (auto *USD = dyn_cast<UsingShadowDecl>(D)) | ||||||
14531 | Underlying = USD->getTargetDecl(); | ||||||
14532 | |||||||
14533 | if (!isa<OMPDeclareReductionDecl>(Underlying) && | ||||||
14534 | !isa<OMPDeclareMapperDecl>(Underlying)) | ||||||
14535 | continue; | ||||||
14536 | |||||||
14537 | if (!SemaRef.isVisible(D)) { | ||||||
14538 | D = findAcceptableDecl(SemaRef, D); | ||||||
14539 | if (!D) | ||||||
14540 | continue; | ||||||
14541 | if (auto *USD = dyn_cast<UsingShadowDecl>(D)) | ||||||
14542 | Underlying = USD->getTargetDecl(); | ||||||
14543 | } | ||||||
14544 | Lookups.emplace_back(); | ||||||
14545 | Lookups.back().addDecl(Underlying); | ||||||
14546 | } | ||||||
14547 | } | ||||||
14548 | } | ||||||
14549 | |||||||
14550 | static ExprResult | ||||||
14551 | buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, | ||||||
14552 | Scope *S, CXXScopeSpec &ReductionIdScopeSpec, | ||||||
14553 | const DeclarationNameInfo &ReductionId, QualType Ty, | ||||||
14554 | CXXCastPath &BasePath, Expr *UnresolvedReduction) { | ||||||
14555 | if (ReductionIdScopeSpec.isInvalid()) | ||||||
14556 | return ExprError(); | ||||||
14557 | SmallVector<UnresolvedSet<8>, 4> Lookups; | ||||||
14558 | if (S) { | ||||||
14559 | LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); | ||||||
14560 | Lookup.suppressDiagnostics(); | ||||||
14561 | while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { | ||||||
14562 | NamedDecl *D = Lookup.getRepresentativeDecl(); | ||||||
14563 | do { | ||||||
14564 | S = S->getParent(); | ||||||
14565 | } while (S && !S->isDeclScope(D)); | ||||||
14566 | if (S) | ||||||
14567 | S = S->getParent(); | ||||||
14568 | Lookups.emplace_back(); | ||||||
14569 | Lookups.back().append(Lookup.begin(), Lookup.end()); | ||||||
14570 | Lookup.clear(); | ||||||
14571 | } | ||||||
14572 | } else if (auto *ULE = | ||||||
14573 | cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { | ||||||
14574 | Lookups.push_back(UnresolvedSet<8>()); | ||||||
14575 | Decl *PrevD = nullptr; | ||||||
14576 | for (NamedDecl *D : ULE->decls()) { | ||||||
14577 | if (D == PrevD) | ||||||
14578 | Lookups.push_back(UnresolvedSet<8>()); | ||||||
14579 | else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) | ||||||
14580 | Lookups.back().addDecl(DRD); | ||||||
14581 | PrevD = D; | ||||||
14582 | } | ||||||
14583 | } | ||||||
14584 | if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || | ||||||
14585 | Ty->isInstantiationDependentType() || | ||||||
14586 | Ty->containsUnexpandedParameterPack() || | ||||||
14587 | filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { | ||||||
14588 | return !D->isInvalidDecl() && | ||||||
14589 | (D->getType()->isDependentType() || | ||||||
14590 | D->getType()->isInstantiationDependentType() || | ||||||
14591 | D->getType()->containsUnexpandedParameterPack()); | ||||||
14592 | })) { | ||||||
14593 | UnresolvedSet<8> ResSet; | ||||||
14594 | for (const UnresolvedSet<8> &Set : Lookups) { | ||||||
14595 | if (Set.empty()) | ||||||
14596 | continue; | ||||||
14597 | ResSet.append(Set.begin(), Set.end()); | ||||||
14598 | // The last item marks the end of all declarations at the specified scope. | ||||||
14599 | ResSet.addDecl(Set[Set.size() - 1]); | ||||||
14600 | } | ||||||
14601 | return UnresolvedLookupExpr::Create( | ||||||
14602 | SemaRef.Context, /*NamingClass=*/nullptr, | ||||||
14603 | ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, | ||||||
14604 | /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); | ||||||
14605 | } | ||||||
14606 | // Lookup inside the classes. | ||||||
14607 | // C++ [over.match.oper]p3: | ||||||
14608 | // For a unary operator @ with an operand of a type whose | ||||||
14609 | // cv-unqualified version is T1, and for a binary operator @ with | ||||||
14610 | // a left operand of a type whose cv-unqualified version is T1 and | ||||||
14611 | // a right operand of a type whose cv-unqualified version is T2, | ||||||
14612 | // three sets of candidate functions, designated member | ||||||
14613 | // candidates, non-member candidates and built-in candidates, are | ||||||
14614 | // constructed as follows: | ||||||
14615 | // -- If T1 is a complete class type or a class currently being | ||||||
14616 | // defined, the set of member candidates is the result of the | ||||||
14617 | // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, | ||||||
14618 | // the set of member candidates is empty. | ||||||
14619 | LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); | ||||||
14620 | Lookup.suppressDiagnostics(); | ||||||
14621 | if (const auto *TyRec = Ty->getAs<RecordType>()) { | ||||||
14622 | // Complete the type if it can be completed. | ||||||
14623 | // If the type is neither complete nor being defined, bail out now. | ||||||
14624 | if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || | ||||||
14625 | TyRec->getDecl()->getDefinition()) { | ||||||
14626 | Lookup.clear(); | ||||||
14627 | SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); | ||||||
14628 | if (Lookup.empty()) { | ||||||
14629 | Lookups.emplace_back(); | ||||||
14630 | Lookups.back().append(Lookup.begin(), Lookup.end()); | ||||||
14631 | } | ||||||
14632 | } | ||||||
14633 | } | ||||||
14634 | // Perform ADL. | ||||||
14635 | if (SemaRef.getLangOpts().CPlusPlus) | ||||||
14636 | argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); | ||||||
14637 | if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( | ||||||
14638 | Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { | ||||||
14639 | if (!D->isInvalidDecl() && | ||||||
14640 | SemaRef.Context.hasSameType(D->getType(), Ty)) | ||||||
14641 | return D; | ||||||
14642 | return nullptr; | ||||||
14643 | })) | ||||||
14644 | return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), | ||||||
14645 | VK_LValue, Loc); | ||||||
14646 | if (SemaRef.getLangOpts().CPlusPlus) { | ||||||
14647 | if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( | ||||||
14648 | Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { | ||||||
14649 | if (!D->isInvalidDecl() && | ||||||
14650 | SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && | ||||||
14651 | !Ty.isMoreQualifiedThan(D->getType())) | ||||||
14652 | return D; | ||||||
14653 | return nullptr; | ||||||
14654 | })) { | ||||||
14655 | CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, | ||||||
14656 | /*DetectVirtual=*/false); | ||||||
14657 | if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { | ||||||
14658 | if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( | ||||||
14659 | VD->getType().getUnqualifiedType()))) { | ||||||
14660 | if (SemaRef.CheckBaseClassAccess( | ||||||
14661 | Loc, VD->getType(), Ty, Paths.front(), | ||||||
14662 | /*DiagID=*/0) != Sema::AR_inaccessible) { | ||||||
14663 | SemaRef.BuildBasePathArray(Paths, BasePath); | ||||||
14664 | return SemaRef.BuildDeclRefExpr( | ||||||
14665 | VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); | ||||||
14666 | } | ||||||
14667 | } | ||||||
14668 | } | ||||||
14669 | } | ||||||
14670 | } | ||||||
14671 | if (ReductionIdScopeSpec.isSet()) { | ||||||
14672 | SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) | ||||||
14673 | << Ty << Range; | ||||||
14674 | return ExprError(); | ||||||
14675 | } | ||||||
14676 | return ExprEmpty(); | ||||||
14677 | } | ||||||
14678 | |||||||
14679 | namespace { | ||||||
14680 | /// Data for the reduction-based clauses. | ||||||
14681 | struct ReductionData { | ||||||
14682 | /// List of original reduction items. | ||||||
14683 | SmallVector<Expr *, 8> Vars; | ||||||
14684 | /// List of private copies of the reduction items. | ||||||
14685 | SmallVector<Expr *, 8> Privates; | ||||||
14686 | /// LHS expressions for the reduction_op expressions. | ||||||
14687 | SmallVector<Expr *, 8> LHSs; | ||||||
14688 | /// RHS expressions for the reduction_op expressions. | ||||||
14689 | SmallVector<Expr *, 8> RHSs; | ||||||
14690 | /// Reduction operation expression. | ||||||
14691 | SmallVector<Expr *, 8> ReductionOps; | ||||||
14692 | /// inscan copy operation expressions. | ||||||
14693 | SmallVector<Expr *, 8> InscanCopyOps; | ||||||
14694 | /// inscan copy temp array expressions for prefix sums. | ||||||
14695 | SmallVector<Expr *, 8> InscanCopyArrayTemps; | ||||||
14696 | /// inscan copy temp array element expressions for prefix sums. | ||||||
14697 | SmallVector<Expr *, 8> InscanCopyArrayElems; | ||||||
14698 | /// Taskgroup descriptors for the corresponding reduction items in | ||||||
14699 | /// in_reduction clauses. | ||||||
14700 | SmallVector<Expr *, 8> TaskgroupDescriptors; | ||||||
14701 | /// List of captures for clause. | ||||||
14702 | SmallVector<Decl *, 4> ExprCaptures; | ||||||
14703 | /// List of postupdate expressions. | ||||||
14704 | SmallVector<Expr *, 4> ExprPostUpdates; | ||||||
14705 | /// Reduction modifier. | ||||||
14706 | unsigned RedModifier = 0; | ||||||
14707 | ReductionData() = delete; | ||||||
14708 | /// Reserves required memory for the reduction data. | ||||||
14709 | ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) { | ||||||
14710 | Vars.reserve(Size); | ||||||
14711 | Privates.reserve(Size); | ||||||
14712 | LHSs.reserve(Size); | ||||||
14713 | RHSs.reserve(Size); | ||||||
14714 | ReductionOps.reserve(Size); | ||||||
14715 | if (RedModifier == OMPC_REDUCTION_inscan) { | ||||||
14716 | InscanCopyOps.reserve(Size); | ||||||
14717 | InscanCopyArrayTemps.reserve(Size); | ||||||
14718 | InscanCopyArrayElems.reserve(Size); | ||||||
14719 | } | ||||||
14720 | TaskgroupDescriptors.reserve(Size); | ||||||
14721 | ExprCaptures.reserve(Size); | ||||||
14722 | ExprPostUpdates.reserve(Size); | ||||||
14723 | } | ||||||
14724 | /// Stores reduction item and reduction operation only (required for dependent | ||||||
14725 | /// reduction item). | ||||||
14726 | void push(Expr *Item, Expr *ReductionOp) { | ||||||
14727 | Vars.emplace_back(Item); | ||||||
14728 | Privates.emplace_back(nullptr); | ||||||
14729 | LHSs.emplace_back(nullptr); | ||||||
14730 | RHSs.emplace_back(nullptr); | ||||||
14731 | ReductionOps.emplace_back(ReductionOp); | ||||||
14732 | TaskgroupDescriptors.emplace_back(nullptr); | ||||||
14733 | if (RedModifier == OMPC_REDUCTION_inscan) { | ||||||
14734 | InscanCopyOps.push_back(nullptr); | ||||||
14735 | InscanCopyArrayTemps.push_back(nullptr); | ||||||
14736 | InscanCopyArrayElems.push_back(nullptr); | ||||||
14737 | } | ||||||
14738 | } | ||||||
14739 | /// Stores reduction data. | ||||||
14740 | void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, | ||||||
14741 | Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp, | ||||||
14742 | Expr *CopyArrayElem) { | ||||||
14743 | Vars.emplace_back(Item); | ||||||
14744 | Privates.emplace_back(Private); | ||||||
14745 | LHSs.emplace_back(LHS); | ||||||
14746 | RHSs.emplace_back(RHS); | ||||||
14747 | ReductionOps.emplace_back(ReductionOp); | ||||||
14748 | TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); | ||||||
14749 | if (RedModifier == OMPC_REDUCTION_inscan) { | ||||||
14750 | InscanCopyOps.push_back(CopyOp); | ||||||
14751 | InscanCopyArrayTemps.push_back(CopyArrayTemp); | ||||||
14752 | InscanCopyArrayElems.push_back(CopyArrayElem); | ||||||
14753 | } else { | ||||||
14754 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 14756, __PRETTY_FUNCTION__)) | ||||||
14755 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 14756, __PRETTY_FUNCTION__)) | ||||||
14756 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 14756, __PRETTY_FUNCTION__)); | ||||||
14757 | } | ||||||
14758 | } | ||||||
14759 | }; | ||||||
14760 | } // namespace | ||||||
14761 | |||||||
14762 | static bool checkOMPArraySectionConstantForReduction( | ||||||
14763 | ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, | ||||||
14764 | SmallVectorImpl<llvm::APSInt> &ArraySizes) { | ||||||
14765 | const Expr *Length = OASE->getLength(); | ||||||
14766 | if (Length == nullptr) { | ||||||
14767 | // For array sections of the form [1:] or [:], we would need to analyze | ||||||
14768 | // the lower bound... | ||||||
14769 | if (OASE->getColonLocFirst().isValid()) | ||||||
14770 | return false; | ||||||
14771 | |||||||
14772 | // This is an array subscript which has implicit length 1! | ||||||
14773 | SingleElement = true; | ||||||
14774 | ArraySizes.push_back(llvm::APSInt::get(1)); | ||||||
14775 | } else { | ||||||
14776 | Expr::EvalResult Result; | ||||||
14777 | if (!Length->EvaluateAsInt(Result, Context)) | ||||||
14778 | return false; | ||||||
14779 | |||||||
14780 | llvm::APSInt ConstantLengthValue = Result.Val.getInt(); | ||||||
14781 | SingleElement = (ConstantLengthValue.getSExtValue() == 1); | ||||||
14782 | ArraySizes.push_back(ConstantLengthValue); | ||||||
14783 | } | ||||||
14784 | |||||||
14785 | // Get the base of this array section and walk up from there. | ||||||
14786 | const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); | ||||||
14787 | |||||||
14788 | // We require length = 1 for all array sections except the right-most to | ||||||
14789 | // guarantee that the memory region is contiguous and has no holes in it. | ||||||
14790 | while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { | ||||||
14791 | Length = TempOASE->getLength(); | ||||||
14792 | if (Length == nullptr) { | ||||||
14793 | // For array sections of the form [1:] or [:], we would need to analyze | ||||||
14794 | // the lower bound... | ||||||
14795 | if (OASE->getColonLocFirst().isValid()) | ||||||
14796 | return false; | ||||||
14797 | |||||||
14798 | // This is an array subscript which has implicit length 1! | ||||||
14799 | ArraySizes.push_back(llvm::APSInt::get(1)); | ||||||
14800 | } else { | ||||||
14801 | Expr::EvalResult Result; | ||||||
14802 | if (!Length->EvaluateAsInt(Result, Context)) | ||||||
14803 | return false; | ||||||
14804 | |||||||
14805 | llvm::APSInt ConstantLengthValue = Result.Val.getInt(); | ||||||
14806 | if (ConstantLengthValue.getSExtValue() != 1) | ||||||
14807 | return false; | ||||||
14808 | |||||||
14809 | ArraySizes.push_back(ConstantLengthValue); | ||||||
14810 | } | ||||||
14811 | Base = TempOASE->getBase()->IgnoreParenImpCasts(); | ||||||
14812 | } | ||||||
14813 | |||||||
14814 | // If we have a single element, we don't need to add the implicit lengths. | ||||||
14815 | if (!SingleElement) { | ||||||
14816 | while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { | ||||||
14817 | // Has implicit length 1! | ||||||
14818 | ArraySizes.push_back(llvm::APSInt::get(1)); | ||||||
14819 | Base = TempASE->getBase()->IgnoreParenImpCasts(); | ||||||
14820 | } | ||||||
14821 | } | ||||||
14822 | |||||||
14823 | // This array section can be privatized as a single value or as a constant | ||||||
14824 | // sized array. | ||||||
14825 | return true; | ||||||
14826 | } | ||||||
14827 | |||||||
14828 | static bool actOnOMPReductionKindClause( | ||||||
14829 | Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, | ||||||
14830 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, | ||||||
14831 | SourceLocation ColonLoc, SourceLocation EndLoc, | ||||||
14832 | CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, | ||||||
14833 | ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { | ||||||
14834 | DeclarationName DN = ReductionId.getName(); | ||||||
14835 | OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); | ||||||
14836 | BinaryOperatorKind BOK = BO_Comma; | ||||||
14837 | |||||||
14838 | ASTContext &Context = S.Context; | ||||||
14839 | // OpenMP [2.14.3.6, reduction clause] | ||||||
14840 | // C | ||||||
14841 | // reduction-identifier is either an identifier or one of the following | ||||||
14842 | // operators: +, -, *, &, |, ^, && and || | ||||||
14843 | // C++ | ||||||
14844 | // reduction-identifier is either an id-expression or one of the following | ||||||
14845 | // operators: +, -, *, &, |, ^, && and || | ||||||
14846 | switch (OOK) { | ||||||
14847 | case OO_Plus: | ||||||
14848 | case OO_Minus: | ||||||
14849 | BOK = BO_Add; | ||||||
14850 | break; | ||||||
14851 | case OO_Star: | ||||||
14852 | BOK = BO_Mul; | ||||||
14853 | break; | ||||||
14854 | case OO_Amp: | ||||||
14855 | BOK = BO_And; | ||||||
14856 | break; | ||||||
14857 | case OO_Pipe: | ||||||
14858 | BOK = BO_Or; | ||||||
14859 | break; | ||||||
14860 | case OO_Caret: | ||||||
14861 | BOK = BO_Xor; | ||||||
14862 | break; | ||||||
14863 | case OO_AmpAmp: | ||||||
14864 | BOK = BO_LAnd; | ||||||
14865 | break; | ||||||
14866 | case OO_PipePipe: | ||||||
14867 | BOK = BO_LOr; | ||||||
14868 | break; | ||||||
14869 | case OO_New: | ||||||
14870 | case OO_Delete: | ||||||
14871 | case OO_Array_New: | ||||||
14872 | case OO_Array_Delete: | ||||||
14873 | case OO_Slash: | ||||||
14874 | case OO_Percent: | ||||||
14875 | case OO_Tilde: | ||||||
14876 | case OO_Exclaim: | ||||||
14877 | case OO_Equal: | ||||||
14878 | case OO_Less: | ||||||
14879 | case OO_Greater: | ||||||
14880 | case OO_LessEqual: | ||||||
14881 | case OO_GreaterEqual: | ||||||
14882 | case OO_PlusEqual: | ||||||
14883 | case OO_MinusEqual: | ||||||
14884 | case OO_StarEqual: | ||||||
14885 | case OO_SlashEqual: | ||||||
14886 | case OO_PercentEqual: | ||||||
14887 | case OO_CaretEqual: | ||||||
14888 | case OO_AmpEqual: | ||||||
14889 | case OO_PipeEqual: | ||||||
14890 | case OO_LessLess: | ||||||
14891 | case OO_GreaterGreater: | ||||||
14892 | case OO_LessLessEqual: | ||||||
14893 | case OO_GreaterGreaterEqual: | ||||||
14894 | case OO_EqualEqual: | ||||||
14895 | case OO_ExclaimEqual: | ||||||
14896 | case OO_Spaceship: | ||||||
14897 | case OO_PlusPlus: | ||||||
14898 | case OO_MinusMinus: | ||||||
14899 | case OO_Comma: | ||||||
14900 | case OO_ArrowStar: | ||||||
14901 | case OO_Arrow: | ||||||
14902 | case OO_Call: | ||||||
14903 | case OO_Subscript: | ||||||
14904 | case OO_Conditional: | ||||||
14905 | case OO_Coawait: | ||||||
14906 | case NUM_OVERLOADED_OPERATORS: | ||||||
14907 | llvm_unreachable("Unexpected reduction identifier")::llvm::llvm_unreachable_internal("Unexpected reduction identifier" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 14907); | ||||||
14908 | case OO_None: | ||||||
14909 | if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { | ||||||
14910 | if (II->isStr("max")) | ||||||
14911 | BOK = BO_GT; | ||||||
14912 | else if (II->isStr("min")) | ||||||
14913 | BOK = BO_LT; | ||||||
14914 | } | ||||||
14915 | break; | ||||||
14916 | } | ||||||
14917 | SourceRange ReductionIdRange; | ||||||
14918 | if (ReductionIdScopeSpec.isValid()) | ||||||
14919 | ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); | ||||||
14920 | else | ||||||
14921 | ReductionIdRange.setBegin(ReductionId.getBeginLoc()); | ||||||
14922 | ReductionIdRange.setEnd(ReductionId.getEndLoc()); | ||||||
14923 | |||||||
14924 | auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); | ||||||
14925 | bool FirstIter = true; | ||||||
14926 | for (Expr *RefExpr : VarList) { | ||||||
14927 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 14927, __PRETTY_FUNCTION__)); | ||||||
14928 | // OpenMP [2.1, C/C++] | ||||||
14929 | // A list item is a variable or array section, subject to the restrictions | ||||||
14930 | // specified in Section 2.4 on page 42 and in each of the sections | ||||||
14931 | // describing clauses and directives for which a list appears. | ||||||
14932 | // OpenMP [2.14.3.3, Restrictions, p.1] | ||||||
14933 | // A variable that is part of another variable (as an array or | ||||||
14934 | // structure element) cannot appear in a private clause. | ||||||
14935 | if (!FirstIter && IR != ER) | ||||||
14936 | ++IR; | ||||||
14937 | FirstIter = false; | ||||||
14938 | SourceLocation ELoc; | ||||||
14939 | SourceRange ERange; | ||||||
14940 | Expr *SimpleRefExpr = RefExpr; | ||||||
14941 | auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, | ||||||
14942 | /*AllowArraySection=*/true); | ||||||
14943 | if (Res.second) { | ||||||
14944 | // Try to find 'declare reduction' corresponding construct before using | ||||||
14945 | // builtin/overloaded operators. | ||||||
14946 | QualType Type = Context.DependentTy; | ||||||
14947 | CXXCastPath BasePath; | ||||||
14948 | ExprResult DeclareReductionRef = buildDeclareReductionRef( | ||||||
14949 | S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, | ||||||
14950 | ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); | ||||||
14951 | Expr *ReductionOp = nullptr; | ||||||
14952 | if (S.CurContext->isDependentContext() && | ||||||
14953 | (DeclareReductionRef.isUnset() || | ||||||
14954 | isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) | ||||||
14955 | ReductionOp = DeclareReductionRef.get(); | ||||||
14956 | // It will be analyzed later. | ||||||
14957 | RD.push(RefExpr, ReductionOp); | ||||||
14958 | } | ||||||
14959 | ValueDecl *D = Res.first; | ||||||
14960 | if (!D) | ||||||
14961 | continue; | ||||||
14962 | |||||||
14963 | Expr *TaskgroupDescriptor = nullptr; | ||||||
14964 | QualType Type; | ||||||
14965 | auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); | ||||||
14966 | auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); | ||||||
14967 | if (ASE) { | ||||||
14968 | Type = ASE->getType().getNonReferenceType(); | ||||||
14969 | } else if (OASE) { | ||||||
14970 | QualType BaseType = | ||||||
14971 | OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); | ||||||
14972 | if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) | ||||||
14973 | Type = ATy->getElementType(); | ||||||
14974 | else | ||||||
14975 | Type = BaseType->getPointeeType(); | ||||||
14976 | Type = Type.getNonReferenceType(); | ||||||
14977 | } else { | ||||||
14978 | Type = Context.getBaseElementType(D->getType().getNonReferenceType()); | ||||||
14979 | } | ||||||
14980 | auto *VD = dyn_cast<VarDecl>(D); | ||||||
14981 | |||||||
14982 | // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] | ||||||
14983 | // A variable that appears in a private clause must not have an incomplete | ||||||
14984 | // type or a reference type. | ||||||
14985 | if (S.RequireCompleteType(ELoc, D->getType(), | ||||||
14986 | diag::err_omp_reduction_incomplete_type)) | ||||||
14987 | continue; | ||||||
14988 | // OpenMP [2.14.3.6, reduction clause, Restrictions] | ||||||
14989 | // A list item that appears in a reduction clause must not be | ||||||
14990 | // const-qualified. | ||||||
14991 | if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, | ||||||
14992 | /*AcceptIfMutable*/ false, ASE || OASE)) | ||||||
14993 | continue; | ||||||
14994 | |||||||
14995 | OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); | ||||||
14996 | // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] | ||||||
14997 | // If a list-item is a reference type then it must bind to the same object | ||||||
14998 | // for all threads of the team. | ||||||
14999 | if (!ASE && !OASE) { | ||||||
15000 | if (VD) { | ||||||
15001 | VarDecl *VDDef = VD->getDefinition(); | ||||||
15002 | if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { | ||||||
15003 | DSARefChecker Check(Stack); | ||||||
15004 | if (Check.Visit(VDDef->getInit())) { | ||||||
15005 | S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) | ||||||
15006 | << getOpenMPClauseName(ClauseKind) << ERange; | ||||||
15007 | S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; | ||||||
15008 | continue; | ||||||
15009 | } | ||||||
15010 | } | ||||||
15011 | } | ||||||
15012 | |||||||
15013 | // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||||
15014 | // in a Construct] | ||||||
15015 | // Variables with the predetermined data-sharing attributes may not be | ||||||
15016 | // listed in data-sharing attributes clauses, except for the cases | ||||||
15017 | // listed below. For these exceptions only, listing a predetermined | ||||||
15018 | // variable in a data-sharing attribute clause is allowed and overrides | ||||||
15019 | // the variable's predetermined data-sharing attributes. | ||||||
15020 | // OpenMP [2.14.3.6, Restrictions, p.3] | ||||||
15021 | // Any number of reduction clauses can be specified on the directive, | ||||||
15022 | // but a list item can appear only once in the reduction clauses for that | ||||||
15023 | // directive. | ||||||
15024 | DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); | ||||||
15025 | if (DVar.CKind == OMPC_reduction) { | ||||||
15026 | S.Diag(ELoc, diag::err_omp_once_referenced) | ||||||
15027 | << getOpenMPClauseName(ClauseKind); | ||||||
15028 | if (DVar.RefExpr) | ||||||
15029 | S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); | ||||||
15030 | continue; | ||||||
15031 | } | ||||||
15032 | if (DVar.CKind != OMPC_unknown) { | ||||||
15033 | S.Diag(ELoc, diag::err_omp_wrong_dsa) | ||||||
15034 | << getOpenMPClauseName(DVar.CKind) | ||||||
15035 | << getOpenMPClauseName(OMPC_reduction); | ||||||
15036 | reportOriginalDsa(S, Stack, D, DVar); | ||||||
15037 | continue; | ||||||
15038 | } | ||||||
15039 | |||||||
15040 | // OpenMP [2.14.3.6, Restrictions, p.1] | ||||||
15041 | // A list item that appears in a reduction clause of a worksharing | ||||||
15042 | // construct must be shared in the parallel regions to which any of the | ||||||
15043 | // worksharing regions arising from the worksharing construct bind. | ||||||
15044 | if (isOpenMPWorksharingDirective(CurrDir) && | ||||||
15045 | !isOpenMPParallelDirective(CurrDir) && | ||||||
15046 | !isOpenMPTeamsDirective(CurrDir)) { | ||||||
15047 | DVar = Stack->getImplicitDSA(D, true); | ||||||
15048 | if (DVar.CKind != OMPC_shared) { | ||||||
15049 | S.Diag(ELoc, diag::err_omp_required_access) | ||||||
15050 | << getOpenMPClauseName(OMPC_reduction) | ||||||
15051 | << getOpenMPClauseName(OMPC_shared); | ||||||
15052 | reportOriginalDsa(S, Stack, D, DVar); | ||||||
15053 | continue; | ||||||
15054 | } | ||||||
15055 | } | ||||||
15056 | } | ||||||
15057 | |||||||
15058 | // Try to find 'declare reduction' corresponding construct before using | ||||||
15059 | // builtin/overloaded operators. | ||||||
15060 | CXXCastPath BasePath; | ||||||
15061 | ExprResult DeclareReductionRef = buildDeclareReductionRef( | ||||||
15062 | S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, | ||||||
15063 | ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); | ||||||
15064 | if (DeclareReductionRef.isInvalid()) | ||||||
15065 | continue; | ||||||
15066 | if (S.CurContext->isDependentContext() && | ||||||
15067 | (DeclareReductionRef.isUnset() || | ||||||
15068 | isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { | ||||||
15069 | RD.push(RefExpr, DeclareReductionRef.get()); | ||||||
15070 | continue; | ||||||
15071 | } | ||||||
15072 | if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { | ||||||
15073 | // Not allowed reduction identifier is found. | ||||||
15074 | S.Diag(ReductionId.getBeginLoc(), | ||||||
15075 | diag::err_omp_unknown_reduction_identifier) | ||||||
15076 | << Type << ReductionIdRange; | ||||||
15077 | continue; | ||||||
15078 | } | ||||||
15079 | |||||||
15080 | // OpenMP [2.14.3.6, reduction clause, Restrictions] | ||||||
15081 | // The type of a list item that appears in a reduction clause must be valid | ||||||
15082 | // for the reduction-identifier. For a max or min reduction in C, the type | ||||||
15083 | // of the list item must be an allowed arithmetic data type: char, int, | ||||||
15084 | // float, double, or _Bool, possibly modified with long, short, signed, or | ||||||
15085 | // unsigned. For a max or min reduction in C++, the type of the list item | ||||||
15086 | // must be an allowed arithmetic data type: char, wchar_t, int, float, | ||||||
15087 | // double, or bool, possibly modified with long, short, signed, or unsigned. | ||||||
15088 | if (DeclareReductionRef.isUnset()) { | ||||||
15089 | if ((BOK == BO_GT || BOK == BO_LT) && | ||||||
15090 | !(Type->isScalarType() || | ||||||
15091 | (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { | ||||||
15092 | S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) | ||||||
15093 | << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; | ||||||
15094 | if (!ASE && !OASE) { | ||||||
15095 | bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == | ||||||
15096 | VarDecl::DeclarationOnly; | ||||||
15097 | S.Diag(D->getLocation(), | ||||||
15098 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||
15099 | << D; | ||||||
15100 | } | ||||||
15101 | continue; | ||||||
15102 | } | ||||||
15103 | if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && | ||||||
15104 | !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { | ||||||
15105 | S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) | ||||||
15106 | << getOpenMPClauseName(ClauseKind); | ||||||
15107 | if (!ASE && !OASE) { | ||||||
15108 | bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == | ||||||
15109 | VarDecl::DeclarationOnly; | ||||||
15110 | S.Diag(D->getLocation(), | ||||||
15111 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||
15112 | << D; | ||||||
15113 | } | ||||||
15114 | continue; | ||||||
15115 | } | ||||||
15116 | } | ||||||
15117 | |||||||
15118 | Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); | ||||||
15119 | VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", | ||||||
15120 | D->hasAttrs() ? &D->getAttrs() : nullptr); | ||||||
15121 | VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), | ||||||
15122 | D->hasAttrs() ? &D->getAttrs() : nullptr); | ||||||
15123 | QualType PrivateTy = Type; | ||||||
15124 | |||||||
15125 | // Try if we can determine constant lengths for all array sections and avoid | ||||||
15126 | // the VLA. | ||||||
15127 | bool ConstantLengthOASE = false; | ||||||
15128 | if (OASE) { | ||||||
15129 | bool SingleElement; | ||||||
15130 | llvm::SmallVector<llvm::APSInt, 4> ArraySizes; | ||||||
15131 | ConstantLengthOASE = checkOMPArraySectionConstantForReduction( | ||||||
15132 | Context, OASE, SingleElement, ArraySizes); | ||||||
15133 | |||||||
15134 | // If we don't have a single element, we must emit a constant array type. | ||||||
15135 | if (ConstantLengthOASE && !SingleElement) { | ||||||
15136 | for (llvm::APSInt &Size : ArraySizes) | ||||||
15137 | PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, | ||||||
15138 | ArrayType::Normal, | ||||||
15139 | /*IndexTypeQuals=*/0); | ||||||
15140 | } | ||||||
15141 | } | ||||||
15142 | |||||||
15143 | if ((OASE && !ConstantLengthOASE) || | ||||||
15144 | (!OASE && !ASE && | ||||||
15145 | D->getType().getNonReferenceType()->isVariablyModifiedType())) { | ||||||
15146 | if (!Context.getTargetInfo().isVLASupported()) { | ||||||
15147 | if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { | ||||||
15148 | S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; | ||||||
15149 | S.Diag(ELoc, diag::note_vla_unsupported); | ||||||
15150 | continue; | ||||||
15151 | } else { | ||||||
15152 | S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; | ||||||
15153 | S.targetDiag(ELoc, diag::note_vla_unsupported); | ||||||
15154 | } | ||||||
15155 | } | ||||||
15156 | // For arrays/array sections only: | ||||||
15157 | // Create pseudo array type for private copy. The size for this array will | ||||||
15158 | // be generated during codegen. | ||||||
15159 | // For array subscripts or single variables Private Ty is the same as Type | ||||||
15160 | // (type of the variable or single array element). | ||||||
15161 | PrivateTy = Context.getVariableArrayType( | ||||||
15162 | Type, | ||||||
15163 | new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), | ||||||
15164 | ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); | ||||||
15165 | } else if (!ASE && !OASE && | ||||||
15166 | Context.getAsArrayType(D->getType().getNonReferenceType())) { | ||||||
15167 | PrivateTy = D->getType().getNonReferenceType(); | ||||||
15168 | } | ||||||
15169 | // Private copy. | ||||||
15170 | VarDecl *PrivateVD = | ||||||
15171 | buildVarDecl(S, ELoc, PrivateTy, D->getName(), | ||||||
15172 | D->hasAttrs() ? &D->getAttrs() : nullptr, | ||||||
15173 | VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); | ||||||
15174 | // Add initializer for private variable. | ||||||
15175 | Expr *Init = nullptr; | ||||||
15176 | DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); | ||||||
15177 | DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); | ||||||
15178 | if (DeclareReductionRef.isUsable()) { | ||||||
15179 | auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); | ||||||
15180 | auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); | ||||||
15181 | if (DRD->getInitializer()) { | ||||||
15182 | S.ActOnUninitializedDecl(PrivateVD); | ||||||
15183 | Init = DRDRef; | ||||||
15184 | RHSVD->setInit(DRDRef); | ||||||
15185 | RHSVD->setInitStyle(VarDecl::CallInit); | ||||||
15186 | } | ||||||
15187 | } else { | ||||||
15188 | switch (BOK) { | ||||||
15189 | case BO_Add: | ||||||
15190 | case BO_Xor: | ||||||
15191 | case BO_Or: | ||||||
15192 | case BO_LOr: | ||||||
15193 | // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. | ||||||
15194 | if (Type->isScalarType() || Type->isAnyComplexType()) | ||||||
15195 | Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); | ||||||
15196 | break; | ||||||
15197 | case BO_Mul: | ||||||
15198 | case BO_LAnd: | ||||||
15199 | if (Type->isScalarType() || Type->isAnyComplexType()) { | ||||||
15200 | // '*' and '&&' reduction ops - initializer is '1'. | ||||||
15201 | Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); | ||||||
15202 | } | ||||||
15203 | break; | ||||||
15204 | case BO_And: { | ||||||
15205 | // '&' reduction op - initializer is '~0'. | ||||||
15206 | QualType OrigType = Type; | ||||||
15207 | if (auto *ComplexTy = OrigType->getAs<ComplexType>()) | ||||||
15208 | Type = ComplexTy->getElementType(); | ||||||
15209 | if (Type->isRealFloatingType()) { | ||||||
15210 | llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue( | ||||||
15211 | Context.getFloatTypeSemantics(Type), | ||||||
15212 | Context.getTypeSize(Type)); | ||||||
15213 | Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, | ||||||
15214 | Type, ELoc); | ||||||
15215 | } else if (Type->isScalarType()) { | ||||||
15216 | uint64_t Size = Context.getTypeSize(Type); | ||||||
15217 | QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); | ||||||
15218 | llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); | ||||||
15219 | Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); | ||||||
15220 | } | ||||||
15221 | if (Init && OrigType->isAnyComplexType()) { | ||||||
15222 | // Init = 0xFFFF + 0xFFFFi; | ||||||
15223 | auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); | ||||||
15224 | Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); | ||||||
15225 | } | ||||||
15226 | Type = OrigType; | ||||||
15227 | break; | ||||||
15228 | } | ||||||
15229 | case BO_LT: | ||||||
15230 | case BO_GT: { | ||||||
15231 | // 'min' reduction op - initializer is 'Largest representable number in | ||||||
15232 | // the reduction list item type'. | ||||||
15233 | // 'max' reduction op - initializer is 'Least representable number in | ||||||
15234 | // the reduction list item type'. | ||||||
15235 | if (Type->isIntegerType() || Type->isPointerType()) { | ||||||
15236 | bool IsSigned = Type->hasSignedIntegerRepresentation(); | ||||||
15237 | uint64_t Size = Context.getTypeSize(Type); | ||||||
15238 | QualType IntTy = | ||||||
15239 | Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); | ||||||
15240 | llvm::APInt InitValue = | ||||||
15241 | (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) | ||||||
15242 | : llvm::APInt::getMinValue(Size) | ||||||
15243 | : IsSigned ? llvm::APInt::getSignedMaxValue(Size) | ||||||
15244 | : llvm::APInt::getMaxValue(Size); | ||||||
15245 | Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); | ||||||
15246 | if (Type->isPointerType()) { | ||||||
15247 | // Cast to pointer type. | ||||||
15248 | ExprResult CastExpr = S.BuildCStyleCastExpr( | ||||||
15249 | ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); | ||||||
15250 | if (CastExpr.isInvalid()) | ||||||
15251 | continue; | ||||||
15252 | Init = CastExpr.get(); | ||||||
15253 | } | ||||||
15254 | } else if (Type->isRealFloatingType()) { | ||||||
15255 | llvm::APFloat InitValue = llvm::APFloat::getLargest( | ||||||
15256 | Context.getFloatTypeSemantics(Type), BOK != BO_LT); | ||||||
15257 | Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, | ||||||
15258 | Type, ELoc); | ||||||
15259 | } | ||||||
15260 | break; | ||||||
15261 | } | ||||||
15262 | case BO_PtrMemD: | ||||||
15263 | case BO_PtrMemI: | ||||||
15264 | case BO_MulAssign: | ||||||
15265 | case BO_Div: | ||||||
15266 | case BO_Rem: | ||||||
15267 | case BO_Sub: | ||||||
15268 | case BO_Shl: | ||||||
15269 | case BO_Shr: | ||||||
15270 | case BO_LE: | ||||||
15271 | case BO_GE: | ||||||
15272 | case BO_EQ: | ||||||
15273 | case BO_NE: | ||||||
15274 | case BO_Cmp: | ||||||
15275 | case BO_AndAssign: | ||||||
15276 | case BO_XorAssign: | ||||||
15277 | case BO_OrAssign: | ||||||
15278 | case BO_Assign: | ||||||
15279 | case BO_AddAssign: | ||||||
15280 | case BO_SubAssign: | ||||||
15281 | case BO_DivAssign: | ||||||
15282 | case BO_RemAssign: | ||||||
15283 | case BO_ShlAssign: | ||||||
15284 | case BO_ShrAssign: | ||||||
15285 | case BO_Comma: | ||||||
15286 | llvm_unreachable("Unexpected reduction operation")::llvm::llvm_unreachable_internal("Unexpected reduction operation" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 15286); | ||||||
15287 | } | ||||||
15288 | } | ||||||
15289 | if (Init && DeclareReductionRef.isUnset()) { | ||||||
15290 | S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); | ||||||
15291 | // Store initializer for single element in private copy. Will be used | ||||||
15292 | // during codegen. | ||||||
15293 | PrivateVD->setInit(RHSVD->getInit()); | ||||||
15294 | PrivateVD->setInitStyle(RHSVD->getInitStyle()); | ||||||
15295 | } else if (!Init) { | ||||||
15296 | S.ActOnUninitializedDecl(RHSVD); | ||||||
15297 | // Store initializer for single element in private copy. Will be used | ||||||
15298 | // during codegen. | ||||||
15299 | PrivateVD->setInit(RHSVD->getInit()); | ||||||
15300 | PrivateVD->setInitStyle(RHSVD->getInitStyle()); | ||||||
15301 | } | ||||||
15302 | if (RHSVD->isInvalidDecl()) | ||||||
15303 | continue; | ||||||
15304 | if (!RHSVD->hasInit() && | ||||||
15305 | (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { | ||||||
15306 | S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) | ||||||
15307 | << Type << ReductionIdRange; | ||||||
15308 | bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == | ||||||
15309 | VarDecl::DeclarationOnly; | ||||||
15310 | S.Diag(D->getLocation(), | ||||||
15311 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||
15312 | << D; | ||||||
15313 | continue; | ||||||
15314 | } | ||||||
15315 | DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); | ||||||
15316 | ExprResult ReductionOp; | ||||||
15317 | if (DeclareReductionRef.isUsable()) { | ||||||
15318 | QualType RedTy = DeclareReductionRef.get()->getType(); | ||||||
15319 | QualType PtrRedTy = Context.getPointerType(RedTy); | ||||||
15320 | ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); | ||||||
15321 | ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); | ||||||
15322 | if (!BasePath.empty()) { | ||||||
15323 | LHS = S.DefaultLvalueConversion(LHS.get()); | ||||||
15324 | RHS = S.DefaultLvalueConversion(RHS.get()); | ||||||
15325 | LHS = ImplicitCastExpr::Create(Context, PtrRedTy, | ||||||
15326 | CK_UncheckedDerivedToBase, LHS.get(), | ||||||
15327 | &BasePath, LHS.get()->getValueKind()); | ||||||
15328 | RHS = ImplicitCastExpr::Create(Context, PtrRedTy, | ||||||
15329 | CK_UncheckedDerivedToBase, RHS.get(), | ||||||
15330 | &BasePath, RHS.get()->getValueKind()); | ||||||
15331 | } | ||||||
15332 | FunctionProtoType::ExtProtoInfo EPI; | ||||||
15333 | QualType Params[] = {PtrRedTy, PtrRedTy}; | ||||||
15334 | QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); | ||||||
15335 | auto *OVE = new (Context) OpaqueValueExpr( | ||||||
15336 | ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, | ||||||
15337 | S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); | ||||||
15338 | Expr *Args[] = {LHS.get(), RHS.get()}; | ||||||
15339 | ReductionOp = | ||||||
15340 | CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc, | ||||||
15341 | S.CurFPFeatureOverrides()); | ||||||
15342 | } else { | ||||||
15343 | ReductionOp = S.BuildBinOp( | ||||||
15344 | Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); | ||||||
15345 | if (ReductionOp.isUsable()) { | ||||||
15346 | if (BOK != BO_LT && BOK != BO_GT) { | ||||||
15347 | ReductionOp = | ||||||
15348 | S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), | ||||||
15349 | BO_Assign, LHSDRE, ReductionOp.get()); | ||||||
15350 | } else { | ||||||
15351 | auto *ConditionalOp = new (Context) | ||||||
15352 | ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, | ||||||
15353 | Type, VK_LValue, OK_Ordinary); | ||||||
15354 | ReductionOp = | ||||||
15355 | S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), | ||||||
15356 | BO_Assign, LHSDRE, ConditionalOp); | ||||||
15357 | } | ||||||
15358 | if (ReductionOp.isUsable()) | ||||||
15359 | ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), | ||||||
15360 | /*DiscardedValue*/ false); | ||||||
15361 | } | ||||||
15362 | if (!ReductionOp.isUsable()) | ||||||
15363 | continue; | ||||||
15364 | } | ||||||
15365 | |||||||
15366 | // Add copy operations for inscan reductions. | ||||||
15367 | // LHS = RHS; | ||||||
15368 | ExprResult CopyOpRes, TempArrayRes, TempArrayElem; | ||||||
15369 | if (ClauseKind == OMPC_reduction && | ||||||
15370 | RD.RedModifier == OMPC_REDUCTION_inscan) { | ||||||
15371 | ExprResult RHS = S.DefaultLvalueConversion(RHSDRE); | ||||||
15372 | CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE, | ||||||
15373 | RHS.get()); | ||||||
15374 | if (!CopyOpRes.isUsable()) | ||||||
15375 | continue; | ||||||
15376 | CopyOpRes = | ||||||
15377 | S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true); | ||||||
15378 | if (!CopyOpRes.isUsable()) | ||||||
15379 | continue; | ||||||
15380 | // For simd directive and simd-based directives in simd mode no need to | ||||||
15381 | // construct temp array, need just a single temp element. | ||||||
15382 | if (Stack->getCurrentDirective() == OMPD_simd || | ||||||
15383 | (S.getLangOpts().OpenMPSimd && | ||||||
15384 | isOpenMPSimdDirective(Stack->getCurrentDirective()))) { | ||||||
15385 | VarDecl *TempArrayVD = | ||||||
15386 | buildVarDecl(S, ELoc, PrivateTy, D->getName(), | ||||||
15387 | D->hasAttrs() ? &D->getAttrs() : nullptr); | ||||||
15388 | // Add a constructor to the temp decl. | ||||||
15389 | S.ActOnUninitializedDecl(TempArrayVD); | ||||||
15390 | TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc); | ||||||
15391 | } else { | ||||||
15392 | // Build temp array for prefix sum. | ||||||
15393 | auto *Dim = new (S.Context) | ||||||
15394 | OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue); | ||||||
15395 | QualType ArrayTy = | ||||||
15396 | S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal, | ||||||
15397 | /*IndexTypeQuals=*/0, {ELoc, ELoc}); | ||||||
15398 | VarDecl *TempArrayVD = | ||||||
15399 | buildVarDecl(S, ELoc, ArrayTy, D->getName(), | ||||||
15400 | D->hasAttrs() ? &D->getAttrs() : nullptr); | ||||||
15401 | // Add a constructor to the temp decl. | ||||||
15402 | S.ActOnUninitializedDecl(TempArrayVD); | ||||||
15403 | TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc); | ||||||
15404 | TempArrayElem = | ||||||
15405 | S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get()); | ||||||
15406 | auto *Idx = new (S.Context) | ||||||
15407 | OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue); | ||||||
15408 | TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(), | ||||||
15409 | ELoc, Idx, ELoc); | ||||||
15410 | } | ||||||
15411 | } | ||||||
15412 | |||||||
15413 | // OpenMP [2.15.4.6, Restrictions, p.2] | ||||||
15414 | // A list item that appears in an in_reduction clause of a task construct | ||||||
15415 | // must appear in a task_reduction clause of a construct associated with a | ||||||
15416 | // taskgroup region that includes the participating task in its taskgroup | ||||||
15417 | // set. The construct associated with the innermost region that meets this | ||||||
15418 | // condition must specify the same reduction-identifier as the in_reduction | ||||||
15419 | // clause. | ||||||
15420 | if (ClauseKind == OMPC_in_reduction) { | ||||||
15421 | SourceRange ParentSR; | ||||||
15422 | BinaryOperatorKind ParentBOK; | ||||||
15423 | const Expr *ParentReductionOp = nullptr; | ||||||
15424 | Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr; | ||||||
15425 | DSAStackTy::DSAVarData ParentBOKDSA = | ||||||
15426 | Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, | ||||||
15427 | ParentBOKTD); | ||||||
15428 | DSAStackTy::DSAVarData ParentReductionOpDSA = | ||||||
15429 | Stack->getTopMostTaskgroupReductionData( | ||||||
15430 | D, ParentSR, ParentReductionOp, ParentReductionOpTD); | ||||||
15431 | bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; | ||||||
15432 | bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; | ||||||
15433 | if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || | ||||||
15434 | (DeclareReductionRef.isUsable() && IsParentBOK) || | ||||||
15435 | (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) { | ||||||
15436 | bool EmitError = true; | ||||||
15437 | if (IsParentReductionOp && DeclareReductionRef.isUsable()) { | ||||||
15438 | llvm::FoldingSetNodeID RedId, ParentRedId; | ||||||
15439 | ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); | ||||||
15440 | DeclareReductionRef.get()->Profile(RedId, Context, | ||||||
15441 | /*Canonical=*/true); | ||||||
15442 | EmitError = RedId != ParentRedId; | ||||||
15443 | } | ||||||
15444 | if (EmitError) { | ||||||
15445 | S.Diag(ReductionId.getBeginLoc(), | ||||||
15446 | diag::err_omp_reduction_identifier_mismatch) | ||||||
15447 | << ReductionIdRange << RefExpr->getSourceRange(); | ||||||
15448 | S.Diag(ParentSR.getBegin(), | ||||||
15449 | diag::note_omp_previous_reduction_identifier) | ||||||
15450 | << ParentSR | ||||||
15451 | << (IsParentBOK ? ParentBOKDSA.RefExpr | ||||||
15452 | : ParentReductionOpDSA.RefExpr) | ||||||
15453 | ->getSourceRange(); | ||||||
15454 | continue; | ||||||
15455 | } | ||||||
15456 | } | ||||||
15457 | TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; | ||||||
15458 | } | ||||||
15459 | |||||||
15460 | DeclRefExpr *Ref = nullptr; | ||||||
15461 | Expr *VarsExpr = RefExpr->IgnoreParens(); | ||||||
15462 | if (!VD && !S.CurContext->isDependentContext()) { | ||||||
15463 | if (ASE || OASE) { | ||||||
15464 | TransformExprToCaptures RebuildToCapture(S, D); | ||||||
15465 | VarsExpr = | ||||||
15466 | RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); | ||||||
15467 | Ref = RebuildToCapture.getCapturedExpr(); | ||||||
15468 | } else { | ||||||
15469 | VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); | ||||||
15470 | } | ||||||
15471 | if (!S.isOpenMPCapturedDecl(D)) { | ||||||
15472 | RD.ExprCaptures.emplace_back(Ref->getDecl()); | ||||||
15473 | if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { | ||||||
15474 | ExprResult RefRes = S.DefaultLvalueConversion(Ref); | ||||||
15475 | if (!RefRes.isUsable()) | ||||||
15476 | continue; | ||||||
15477 | ExprResult PostUpdateRes = | ||||||
15478 | S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, | ||||||
15479 | RefRes.get()); | ||||||
15480 | if (!PostUpdateRes.isUsable()) | ||||||
15481 | continue; | ||||||
15482 | if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || | ||||||
15483 | Stack->getCurrentDirective() == OMPD_taskgroup) { | ||||||
15484 | S.Diag(RefExpr->getExprLoc(), | ||||||
15485 | diag::err_omp_reduction_non_addressable_expression) | ||||||
15486 | << RefExpr->getSourceRange(); | ||||||
15487 | continue; | ||||||
15488 | } | ||||||
15489 | RD.ExprPostUpdates.emplace_back( | ||||||
15490 | S.IgnoredValueConversions(PostUpdateRes.get()).get()); | ||||||
15491 | } | ||||||
15492 | } | ||||||
15493 | } | ||||||
15494 | // All reduction items are still marked as reduction (to do not increase | ||||||
15495 | // code base size). | ||||||
15496 | unsigned Modifier = RD.RedModifier; | ||||||
15497 | // Consider task_reductions as reductions with task modifier. Required for | ||||||
15498 | // correct analysis of in_reduction clauses. | ||||||
15499 | if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction) | ||||||
15500 | Modifier = OMPC_REDUCTION_task; | ||||||
15501 | Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier); | ||||||
15502 | if (Modifier == OMPC_REDUCTION_task && | ||||||
15503 | (CurrDir == OMPD_taskgroup || | ||||||
15504 | ((isOpenMPParallelDirective(CurrDir) || | ||||||
15505 | isOpenMPWorksharingDirective(CurrDir)) && | ||||||
15506 | !isOpenMPSimdDirective(CurrDir)))) { | ||||||
15507 | if (DeclareReductionRef.isUsable()) | ||||||
15508 | Stack->addTaskgroupReductionData(D, ReductionIdRange, | ||||||
15509 | DeclareReductionRef.get()); | ||||||
15510 | else | ||||||
15511 | Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); | ||||||
15512 | } | ||||||
15513 | RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), | ||||||
15514 | TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(), | ||||||
15515 | TempArrayElem.get()); | ||||||
15516 | } | ||||||
15517 | return RD.Vars.empty(); | ||||||
15518 | } | ||||||
15519 | |||||||
15520 | OMPClause *Sema::ActOnOpenMPReductionClause( | ||||||
15521 | ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, | ||||||
15522 | SourceLocation StartLoc, SourceLocation LParenLoc, | ||||||
15523 | SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, | ||||||
15524 | CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, | ||||||
15525 | ArrayRef<Expr *> UnresolvedReductions) { | ||||||
15526 | if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) { | ||||||
15527 | Diag(LParenLoc, diag::err_omp_unexpected_clause_value) | ||||||
15528 | << getListOfPossibleValues(OMPC_reduction, /*First=*/0, | ||||||
15529 | /*Last=*/OMPC_REDUCTION_unknown) | ||||||
15530 | << getOpenMPClauseName(OMPC_reduction); | ||||||
15531 | return nullptr; | ||||||
15532 | } | ||||||
15533 | // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions | ||||||
15534 | // A reduction clause with the inscan reduction-modifier may only appear on a | ||||||
15535 | // worksharing-loop construct, a worksharing-loop SIMD construct, a simd | ||||||
15536 | // construct, a parallel worksharing-loop construct or a parallel | ||||||
15537 | // worksharing-loop SIMD construct. | ||||||
15538 | if (Modifier == OMPC_REDUCTION_inscan && | ||||||
15539 | (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() != OMPD_for && | ||||||
15540 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() != OMPD_for_simd && | ||||||
15541 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() != OMPD_simd && | ||||||
15542 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() != OMPD_parallel_for && | ||||||
15543 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() != OMPD_parallel_for_simd)) { | ||||||
15544 | Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); | ||||||
15545 | return nullptr; | ||||||
15546 | } | ||||||
15547 | |||||||
15548 | ReductionData RD(VarList.size(), Modifier); | ||||||
15549 | if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), OMPC_reduction, VarList, | ||||||
15550 | StartLoc, LParenLoc, ColonLoc, EndLoc, | ||||||
15551 | ReductionIdScopeSpec, ReductionId, | ||||||
15552 | UnresolvedReductions, RD)) | ||||||
15553 | return nullptr; | ||||||
15554 | |||||||
15555 | return OMPReductionClause::Create( | ||||||
15556 | Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier, | ||||||
15557 | RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, | ||||||
15558 | RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps, | ||||||
15559 | RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems, | ||||||
15560 | buildPreInits(Context, RD.ExprCaptures), | ||||||
15561 | buildPostUpdate(*this, RD.ExprPostUpdates)); | ||||||
15562 | } | ||||||
15563 | |||||||
15564 | OMPClause *Sema::ActOnOpenMPTaskReductionClause( | ||||||
15565 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, | ||||||
15566 | SourceLocation ColonLoc, SourceLocation EndLoc, | ||||||
15567 | CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, | ||||||
15568 | ArrayRef<Expr *> UnresolvedReductions) { | ||||||
15569 | ReductionData RD(VarList.size()); | ||||||
15570 | if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), OMPC_task_reduction, VarList, | ||||||
15571 | StartLoc, LParenLoc, ColonLoc, EndLoc, | ||||||
15572 | ReductionIdScopeSpec, ReductionId, | ||||||
15573 | UnresolvedReductions, RD)) | ||||||
15574 | return nullptr; | ||||||
15575 | |||||||
15576 | return OMPTaskReductionClause::Create( | ||||||
15577 | Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, | ||||||
15578 | ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, | ||||||
15579 | RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, | ||||||
15580 | buildPreInits(Context, RD.ExprCaptures), | ||||||
15581 | buildPostUpdate(*this, RD.ExprPostUpdates)); | ||||||
15582 | } | ||||||
15583 | |||||||
15584 | OMPClause *Sema::ActOnOpenMPInReductionClause( | ||||||
15585 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, | ||||||
15586 | SourceLocation ColonLoc, SourceLocation EndLoc, | ||||||
15587 | CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, | ||||||
15588 | ArrayRef<Expr *> UnresolvedReductions) { | ||||||
15589 | ReductionData RD(VarList.size()); | ||||||
15590 | if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), OMPC_in_reduction, VarList, | ||||||
15591 | StartLoc, LParenLoc, ColonLoc, EndLoc, | ||||||
15592 | ReductionIdScopeSpec, ReductionId, | ||||||
15593 | UnresolvedReductions, RD)) | ||||||
15594 | return nullptr; | ||||||
15595 | |||||||
15596 | return OMPInReductionClause::Create( | ||||||
15597 | Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, | ||||||
15598 | ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, | ||||||
15599 | RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, | ||||||
15600 | buildPreInits(Context, RD.ExprCaptures), | ||||||
15601 | buildPostUpdate(*this, RD.ExprPostUpdates)); | ||||||
15602 | } | ||||||
15603 | |||||||
15604 | bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, | ||||||
15605 | SourceLocation LinLoc) { | ||||||
15606 | if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || | ||||||
15607 | LinKind == OMPC_LINEAR_unknown) { | ||||||
15608 | Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; | ||||||
15609 | return true; | ||||||
15610 | } | ||||||
15611 | return false; | ||||||
15612 | } | ||||||
15613 | |||||||
15614 | bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, | ||||||
15615 | OpenMPLinearClauseKind LinKind, QualType Type, | ||||||
15616 | bool IsDeclareSimd) { | ||||||
15617 | const auto *VD = dyn_cast_or_null<VarDecl>(D); | ||||||
15618 | // A variable must not have an incomplete type or a reference type. | ||||||
15619 | if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) | ||||||
15620 | return true; | ||||||
15621 | if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && | ||||||
15622 | !Type->isReferenceType()) { | ||||||
15623 | Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) | ||||||
15624 | << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); | ||||||
15625 | return true; | ||||||
15626 | } | ||||||
15627 | Type = Type.getNonReferenceType(); | ||||||
15628 | |||||||
15629 | // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] | ||||||
15630 | // A variable that is privatized must not have a const-qualified type | ||||||
15631 | // unless it is of class type with a mutable member. This restriction does | ||||||
15632 | // not apply to the firstprivate clause, nor to the linear clause on | ||||||
15633 | // declarative directives (like declare simd). | ||||||
15634 | if (!IsDeclareSimd && | ||||||
15635 | rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) | ||||||
15636 | return true; | ||||||
15637 | |||||||
15638 | // A list item must be of integral or pointer type. | ||||||
15639 | Type = Type.getUnqualifiedType().getCanonicalType(); | ||||||
15640 | const auto *Ty = Type.getTypePtrOrNull(); | ||||||
15641 | if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && | ||||||
15642 | !Ty->isIntegralType(Context) && !Ty->isPointerType())) { | ||||||
15643 | Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; | ||||||
15644 | if (D) { | ||||||
15645 | bool IsDecl = | ||||||
15646 | !VD || | ||||||
15647 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||||
15648 | Diag(D->getLocation(), | ||||||
15649 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||
15650 | << D; | ||||||
15651 | } | ||||||
15652 | return true; | ||||||
15653 | } | ||||||
15654 | return false; | ||||||
15655 | } | ||||||
15656 | |||||||
15657 | OMPClause *Sema::ActOnOpenMPLinearClause( | ||||||
15658 | ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, | ||||||
15659 | SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, | ||||||
15660 | SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { | ||||||
15661 | SmallVector<Expr *, 8> Vars; | ||||||
15662 | SmallVector<Expr *, 8> Privates; | ||||||
15663 | SmallVector<Expr *, 8> Inits; | ||||||
15664 | SmallVector<Decl *, 4> ExprCaptures; | ||||||
15665 | SmallVector<Expr *, 4> ExprPostUpdates; | ||||||
15666 | if (CheckOpenMPLinearModifier(LinKind, LinLoc)) | ||||||
15667 | LinKind = OMPC_LINEAR_val; | ||||||
15668 | for (Expr *RefExpr : VarList) { | ||||||
15669 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 15669, __PRETTY_FUNCTION__)); | ||||||
15670 | SourceLocation ELoc; | ||||||
15671 | SourceRange ERange; | ||||||
15672 | Expr *SimpleRefExpr = RefExpr; | ||||||
15673 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||||
15674 | if (Res.second) { | ||||||
15675 | // It will be analyzed later. | ||||||
15676 | Vars.push_back(RefExpr); | ||||||
15677 | Privates.push_back(nullptr); | ||||||
15678 | Inits.push_back(nullptr); | ||||||
15679 | } | ||||||
15680 | ValueDecl *D = Res.first; | ||||||
15681 | if (!D) | ||||||
15682 | continue; | ||||||
15683 | |||||||
15684 | QualType Type = D->getType(); | ||||||
15685 | auto *VD = dyn_cast<VarDecl>(D); | ||||||
15686 | |||||||
15687 | // OpenMP [2.14.3.7, linear clause] | ||||||
15688 | // A list-item cannot appear in more than one linear clause. | ||||||
15689 | // A list-item that appears in a linear clause cannot appear in any | ||||||
15690 | // other data-sharing attribute clause. | ||||||
15691 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); | ||||||
15692 | if (DVar.RefExpr) { | ||||||
15693 | Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) | ||||||
15694 | << getOpenMPClauseName(OMPC_linear); | ||||||
15695 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||
15696 | continue; | ||||||
15697 | } | ||||||
15698 | |||||||
15699 | if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) | ||||||
15700 | continue; | ||||||
15701 | Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); | ||||||
15702 | |||||||
15703 | // Build private copy of original var. | ||||||
15704 | VarDecl *Private = | ||||||
15705 | buildVarDecl(*this, ELoc, Type, D->getName(), | ||||||
15706 | D->hasAttrs() ? &D->getAttrs() : nullptr, | ||||||
15707 | VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); | ||||||
15708 | DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); | ||||||
15709 | // Build var to save initial value. | ||||||
15710 | VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); | ||||||
15711 | Expr *InitExpr; | ||||||
15712 | DeclRefExpr *Ref = nullptr; | ||||||
15713 | if (!VD && !CurContext->isDependentContext()) { | ||||||
15714 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); | ||||||
15715 | if (!isOpenMPCapturedDecl(D)) { | ||||||
15716 | ExprCaptures.push_back(Ref->getDecl()); | ||||||
15717 | if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { | ||||||
15718 | ExprResult RefRes = DefaultLvalueConversion(Ref); | ||||||
15719 | if (!RefRes.isUsable()) | ||||||
15720 | continue; | ||||||
15721 | ExprResult PostUpdateRes = | ||||||
15722 | BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurScope(), ELoc, BO_Assign, | ||||||
15723 | SimpleRefExpr, RefRes.get()); | ||||||
15724 | if (!PostUpdateRes.isUsable()) | ||||||
15725 | continue; | ||||||
15726 | ExprPostUpdates.push_back( | ||||||
15727 | IgnoredValueConversions(PostUpdateRes.get()).get()); | ||||||
15728 | } | ||||||
15729 | } | ||||||
15730 | } | ||||||
15731 | if (LinKind == OMPC_LINEAR_uval) | ||||||
15732 | InitExpr = VD ? VD->getInit() : SimpleRefExpr; | ||||||
15733 | else | ||||||
15734 | InitExpr = VD ? SimpleRefExpr : Ref; | ||||||
15735 | AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), | ||||||
15736 | /*DirectInit=*/false); | ||||||
15737 | DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); | ||||||
15738 | |||||||
15739 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); | ||||||
15740 | Vars.push_back((VD || CurContext->isDependentContext()) | ||||||
15741 | ? RefExpr->IgnoreParens() | ||||||
15742 | : Ref); | ||||||
15743 | Privates.push_back(PrivateRef); | ||||||
15744 | Inits.push_back(InitRef); | ||||||
15745 | } | ||||||
15746 | |||||||
15747 | if (Vars.empty()) | ||||||
15748 | return nullptr; | ||||||
15749 | |||||||
15750 | Expr *StepExpr = Step; | ||||||
15751 | Expr *CalcStepExpr = nullptr; | ||||||
15752 | if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && | ||||||
15753 | !Step->isInstantiationDependent() && | ||||||
15754 | !Step->containsUnexpandedParameterPack()) { | ||||||
15755 | SourceLocation StepLoc = Step->getBeginLoc(); | ||||||
15756 | ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); | ||||||
15757 | if (Val.isInvalid()) | ||||||
15758 | return nullptr; | ||||||
15759 | StepExpr = Val.get(); | ||||||
15760 | |||||||
15761 | // Build var to save the step value. | ||||||
15762 | VarDecl *SaveVar = | ||||||
15763 | buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); | ||||||
15764 | ExprResult SaveRef = | ||||||
15765 | buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); | ||||||
15766 | ExprResult CalcStep = | ||||||
15767 | BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); | ||||||
15768 | CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); | ||||||
15769 | |||||||
15770 | // Warn about zero linear step (it would be probably better specified as | ||||||
15771 | // making corresponding variables 'const'). | ||||||
15772 | if (Optional<llvm::APSInt> Result = | ||||||
15773 | StepExpr->getIntegerConstantExpr(Context)) { | ||||||
15774 | if (!Result->isNegative() && !Result->isStrictlyPositive()) | ||||||
15775 | Diag(StepLoc, diag::warn_omp_linear_step_zero) | ||||||
15776 | << Vars[0] << (Vars.size() > 1); | ||||||
15777 | } else if (CalcStep.isUsable()) { | ||||||
15778 | // Calculate the step beforehand instead of doing this on each iteration. | ||||||
15779 | // (This is not used if the number of iterations may be kfold-ed). | ||||||
15780 | CalcStepExpr = CalcStep.get(); | ||||||
15781 | } | ||||||
15782 | } | ||||||
15783 | |||||||
15784 | return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, | ||||||
15785 | ColonLoc, EndLoc, Vars, Privates, Inits, | ||||||
15786 | StepExpr, CalcStepExpr, | ||||||
15787 | buildPreInits(Context, ExprCaptures), | ||||||
15788 | buildPostUpdate(*this, ExprPostUpdates)); | ||||||
15789 | } | ||||||
15790 | |||||||
15791 | static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, | ||||||
15792 | Expr *NumIterations, Sema &SemaRef, | ||||||
15793 | Scope *S, DSAStackTy *Stack) { | ||||||
15794 | // Walk the vars and build update/final expressions for the CodeGen. | ||||||
15795 | SmallVector<Expr *, 8> Updates; | ||||||
15796 | SmallVector<Expr *, 8> Finals; | ||||||
15797 | SmallVector<Expr *, 8> UsedExprs; | ||||||
15798 | Expr *Step = Clause.getStep(); | ||||||
15799 | Expr *CalcStep = Clause.getCalcStep(); | ||||||
15800 | // OpenMP [2.14.3.7, linear clause] | ||||||
15801 | // If linear-step is not specified it is assumed to be 1. | ||||||
15802 | if (!Step) | ||||||
15803 | Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); | ||||||
15804 | else if (CalcStep) | ||||||
15805 | Step = cast<BinaryOperator>(CalcStep)->getLHS(); | ||||||
15806 | bool HasErrors = false; | ||||||
15807 | auto CurInit = Clause.inits().begin(); | ||||||
15808 | auto CurPrivate = Clause.privates().begin(); | ||||||
15809 | OpenMPLinearClauseKind LinKind = Clause.getModifier(); | ||||||
15810 | for (Expr *RefExpr : Clause.varlists()) { | ||||||
15811 | SourceLocation ELoc; | ||||||
15812 | SourceRange ERange; | ||||||
15813 | Expr *SimpleRefExpr = RefExpr; | ||||||
15814 | auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); | ||||||
15815 | ValueDecl *D = Res.first; | ||||||
15816 | if (Res.second || !D) { | ||||||
15817 | Updates.push_back(nullptr); | ||||||
15818 | Finals.push_back(nullptr); | ||||||
15819 | HasErrors = true; | ||||||
15820 | continue; | ||||||
15821 | } | ||||||
15822 | auto &&Info = Stack->isLoopControlVariable(D); | ||||||
15823 | // OpenMP [2.15.11, distribute simd Construct] | ||||||
15824 | // A list item may not appear in a linear clause, unless it is the loop | ||||||
15825 | // iteration variable. | ||||||
15826 | if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && | ||||||
15827 | isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { | ||||||
15828 | SemaRef.Diag(ELoc, | ||||||
15829 | diag::err_omp_linear_distribute_var_non_loop_iteration); | ||||||
15830 | Updates.push_back(nullptr); | ||||||
15831 | Finals.push_back(nullptr); | ||||||
15832 | HasErrors = true; | ||||||
15833 | continue; | ||||||
15834 | } | ||||||
15835 | Expr *InitExpr = *CurInit; | ||||||
15836 | |||||||
15837 | // Build privatized reference to the current linear var. | ||||||
15838 | auto *DE = cast<DeclRefExpr>(SimpleRefExpr); | ||||||
15839 | Expr *CapturedRef; | ||||||
15840 | if (LinKind == OMPC_LINEAR_uval) | ||||||
15841 | CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); | ||||||
15842 | else | ||||||
15843 | CapturedRef = | ||||||
15844 | buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), | ||||||
15845 | DE->getType().getUnqualifiedType(), DE->getExprLoc(), | ||||||
15846 | /*RefersToCapture=*/true); | ||||||
15847 | |||||||
15848 | // Build update: Var = InitExpr + IV * Step | ||||||
15849 | ExprResult Update; | ||||||
15850 | if (!Info.first) | ||||||
15851 | Update = buildCounterUpdate( | ||||||
15852 | SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, | ||||||
15853 | /*Subtract=*/false, /*IsNonRectangularLB=*/false); | ||||||
15854 | else | ||||||
15855 | Update = *CurPrivate; | ||||||
15856 | Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), | ||||||
15857 | /*DiscardedValue*/ false); | ||||||
15858 | |||||||
15859 | // Build final: Var = InitExpr + NumIterations * Step | ||||||
15860 | ExprResult Final; | ||||||
15861 | if (!Info.first) | ||||||
15862 | Final = | ||||||
15863 | buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, | ||||||
15864 | InitExpr, NumIterations, Step, /*Subtract=*/false, | ||||||
15865 | /*IsNonRectangularLB=*/false); | ||||||
15866 | else | ||||||
15867 | Final = *CurPrivate; | ||||||
15868 | Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), | ||||||
15869 | /*DiscardedValue*/ false); | ||||||
15870 | |||||||
15871 | if (!Update.isUsable() || !Final.isUsable()) { | ||||||
15872 | Updates.push_back(nullptr); | ||||||
15873 | Finals.push_back(nullptr); | ||||||
15874 | UsedExprs.push_back(nullptr); | ||||||
15875 | HasErrors = true; | ||||||
15876 | } else { | ||||||
15877 | Updates.push_back(Update.get()); | ||||||
15878 | Finals.push_back(Final.get()); | ||||||
15879 | if (!Info.first) | ||||||
15880 | UsedExprs.push_back(SimpleRefExpr); | ||||||
15881 | } | ||||||
15882 | ++CurInit; | ||||||
15883 | ++CurPrivate; | ||||||
15884 | } | ||||||
15885 | if (Expr *S = Clause.getStep()) | ||||||
15886 | UsedExprs.push_back(S); | ||||||
15887 | // Fill the remaining part with the nullptr. | ||||||
15888 | UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); | ||||||
15889 | Clause.setUpdates(Updates); | ||||||
15890 | Clause.setFinals(Finals); | ||||||
15891 | Clause.setUsedExprs(UsedExprs); | ||||||
15892 | return HasErrors; | ||||||
15893 | } | ||||||
15894 | |||||||
15895 | OMPClause *Sema::ActOnOpenMPAlignedClause( | ||||||
15896 | ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, | ||||||
15897 | SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { | ||||||
15898 | SmallVector<Expr *, 8> Vars; | ||||||
15899 | for (Expr *RefExpr : VarList) { | ||||||
15900 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 15900, __PRETTY_FUNCTION__)); | ||||||
15901 | SourceLocation ELoc; | ||||||
15902 | SourceRange ERange; | ||||||
15903 | Expr *SimpleRefExpr = RefExpr; | ||||||
15904 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||||
15905 | if (Res.second) { | ||||||
15906 | // It will be analyzed later. | ||||||
15907 | Vars.push_back(RefExpr); | ||||||
15908 | } | ||||||
15909 | ValueDecl *D = Res.first; | ||||||
15910 | if (!D) | ||||||
15911 | continue; | ||||||
15912 | |||||||
15913 | QualType QType = D->getType(); | ||||||
15914 | auto *VD = dyn_cast<VarDecl>(D); | ||||||
15915 | |||||||
15916 | // OpenMP [2.8.1, simd construct, Restrictions] | ||||||
15917 | // The type of list items appearing in the aligned clause must be | ||||||
15918 | // array, pointer, reference to array, or reference to pointer. | ||||||
15919 | QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); | ||||||
15920 | const Type *Ty = QType.getTypePtrOrNull(); | ||||||
15921 | if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { | ||||||
15922 | Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) | ||||||
15923 | << QType << getLangOpts().CPlusPlus << ERange; | ||||||
15924 | bool IsDecl = | ||||||
15925 | !VD || | ||||||
15926 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||||
15927 | Diag(D->getLocation(), | ||||||
15928 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||
15929 | << D; | ||||||
15930 | continue; | ||||||
15931 | } | ||||||
15932 | |||||||
15933 | // OpenMP [2.8.1, simd construct, Restrictions] | ||||||
15934 | // A list-item cannot appear in more than one aligned clause. | ||||||
15935 | if (const Expr *PrevRef = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addUniqueAligned(D, SimpleRefExpr)) { | ||||||
15936 | Diag(ELoc, diag::err_omp_used_in_clause_twice) | ||||||
15937 | << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; | ||||||
15938 | Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) | ||||||
15939 | << getOpenMPClauseName(OMPC_aligned); | ||||||
15940 | continue; | ||||||
15941 | } | ||||||
15942 | |||||||
15943 | DeclRefExpr *Ref = nullptr; | ||||||
15944 | if (!VD && isOpenMPCapturedDecl(D)) | ||||||
15945 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); | ||||||
15946 | Vars.push_back(DefaultFunctionArrayConversion( | ||||||
15947 | (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) | ||||||
15948 | .get()); | ||||||
15949 | } | ||||||
15950 | |||||||
15951 | // OpenMP [2.8.1, simd construct, Description] | ||||||
15952 | // The parameter of the aligned clause, alignment, must be a constant | ||||||
15953 | // positive integer expression. | ||||||
15954 | // If no optional parameter is specified, implementation-defined default | ||||||
15955 | // alignments for SIMD instructions on the target platforms are assumed. | ||||||
15956 | if (Alignment != nullptr) { | ||||||
15957 | ExprResult AlignResult = | ||||||
15958 | VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); | ||||||
15959 | if (AlignResult.isInvalid()) | ||||||
15960 | return nullptr; | ||||||
15961 | Alignment = AlignResult.get(); | ||||||
15962 | } | ||||||
15963 | if (Vars.empty()) | ||||||
15964 | return nullptr; | ||||||
15965 | |||||||
15966 | return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, | ||||||
15967 | EndLoc, Vars, Alignment); | ||||||
15968 | } | ||||||
15969 | |||||||
15970 | OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, | ||||||
15971 | SourceLocation StartLoc, | ||||||
15972 | SourceLocation LParenLoc, | ||||||
15973 | SourceLocation EndLoc) { | ||||||
15974 | SmallVector<Expr *, 8> Vars; | ||||||
15975 | SmallVector<Expr *, 8> SrcExprs; | ||||||
15976 | SmallVector<Expr *, 8> DstExprs; | ||||||
15977 | SmallVector<Expr *, 8> AssignmentOps; | ||||||
15978 | for (Expr *RefExpr : VarList) { | ||||||
15979 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 15979, __PRETTY_FUNCTION__)); | ||||||
15980 | if (isa<DependentScopeDeclRefExpr>(RefExpr)) { | ||||||
15981 | // It will be analyzed later. | ||||||
15982 | Vars.push_back(RefExpr); | ||||||
15983 | SrcExprs.push_back(nullptr); | ||||||
15984 | DstExprs.push_back(nullptr); | ||||||
15985 | AssignmentOps.push_back(nullptr); | ||||||
15986 | continue; | ||||||
15987 | } | ||||||
15988 | |||||||
15989 | SourceLocation ELoc = RefExpr->getExprLoc(); | ||||||
15990 | // OpenMP [2.1, C/C++] | ||||||
15991 | // A list item is a variable name. | ||||||
15992 | // OpenMP [2.14.4.1, Restrictions, p.1] | ||||||
15993 | // A list item that appears in a copyin clause must be threadprivate. | ||||||
15994 | auto *DE = dyn_cast<DeclRefExpr>(RefExpr); | ||||||
15995 | if (!DE || !isa<VarDecl>(DE->getDecl())) { | ||||||
15996 | Diag(ELoc, diag::err_omp_expected_var_name_member_expr) | ||||||
15997 | << 0 << RefExpr->getSourceRange(); | ||||||
15998 | continue; | ||||||
15999 | } | ||||||
16000 | |||||||
16001 | Decl *D = DE->getDecl(); | ||||||
16002 | auto *VD = cast<VarDecl>(D); | ||||||
16003 | |||||||
16004 | QualType Type = VD->getType(); | ||||||
16005 | if (Type->isDependentType() || Type->isInstantiationDependentType()) { | ||||||
16006 | // It will be analyzed later. | ||||||
16007 | Vars.push_back(DE); | ||||||
16008 | SrcExprs.push_back(nullptr); | ||||||
16009 | DstExprs.push_back(nullptr); | ||||||
16010 | AssignmentOps.push_back(nullptr); | ||||||
16011 | continue; | ||||||
16012 | } | ||||||
16013 | |||||||
16014 | // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] | ||||||
16015 | // A list item that appears in a copyin clause must be threadprivate. | ||||||
16016 | if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isThreadPrivate(VD)) { | ||||||
16017 | Diag(ELoc, diag::err_omp_required_access) | ||||||
16018 | << getOpenMPClauseName(OMPC_copyin) | ||||||
16019 | << getOpenMPDirectiveName(OMPD_threadprivate); | ||||||
16020 | continue; | ||||||
16021 | } | ||||||
16022 | |||||||
16023 | // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] | ||||||
16024 | // A variable of class type (or array thereof) that appears in a | ||||||
16025 | // copyin clause requires an accessible, unambiguous copy assignment | ||||||
16026 | // operator for the class type. | ||||||
16027 | QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); | ||||||
16028 | VarDecl *SrcVD = | ||||||
16029 | buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), | ||||||
16030 | ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); | ||||||
16031 | DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( | ||||||
16032 | *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); | ||||||
16033 | VarDecl *DstVD = | ||||||
16034 | buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", | ||||||
16035 | VD->hasAttrs() ? &VD->getAttrs() : nullptr); | ||||||
16036 | DeclRefExpr *PseudoDstExpr = | ||||||
16037 | buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); | ||||||
16038 | // For arrays generate assignment operation for single element and replace | ||||||
16039 | // it by the original array element in CodeGen. | ||||||
16040 | ExprResult AssignmentOp = | ||||||
16041 | BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, | ||||||
16042 | PseudoSrcExpr); | ||||||
16043 | if (AssignmentOp.isInvalid()) | ||||||
16044 | continue; | ||||||
16045 | AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), | ||||||
16046 | /*DiscardedValue*/ false); | ||||||
16047 | if (AssignmentOp.isInvalid()) | ||||||
16048 | continue; | ||||||
16049 | |||||||
16050 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(VD, DE, OMPC_copyin); | ||||||
16051 | Vars.push_back(DE); | ||||||
16052 | SrcExprs.push_back(PseudoSrcExpr); | ||||||
16053 | DstExprs.push_back(PseudoDstExpr); | ||||||
16054 | AssignmentOps.push_back(AssignmentOp.get()); | ||||||
16055 | } | ||||||
16056 | |||||||
16057 | if (Vars.empty()) | ||||||
16058 | return nullptr; | ||||||
16059 | |||||||
16060 | return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, | ||||||
16061 | SrcExprs, DstExprs, AssignmentOps); | ||||||
16062 | } | ||||||
16063 | |||||||
16064 | OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, | ||||||
16065 | SourceLocation StartLoc, | ||||||
16066 | SourceLocation LParenLoc, | ||||||
16067 | SourceLocation EndLoc) { | ||||||
16068 | SmallVector<Expr *, 8> Vars; | ||||||
16069 | SmallVector<Expr *, 8> SrcExprs; | ||||||
16070 | SmallVector<Expr *, 8> DstExprs; | ||||||
16071 | SmallVector<Expr *, 8> AssignmentOps; | ||||||
16072 | for (Expr *RefExpr : VarList) { | ||||||
16073 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16073, __PRETTY_FUNCTION__)); | ||||||
16074 | SourceLocation ELoc; | ||||||
16075 | SourceRange ERange; | ||||||
16076 | Expr *SimpleRefExpr = RefExpr; | ||||||
16077 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||||
16078 | if (Res.second) { | ||||||
16079 | // It will be analyzed later. | ||||||
16080 | Vars.push_back(RefExpr); | ||||||
16081 | SrcExprs.push_back(nullptr); | ||||||
16082 | DstExprs.push_back(nullptr); | ||||||
16083 | AssignmentOps.push_back(nullptr); | ||||||
16084 | } | ||||||
16085 | ValueDecl *D = Res.first; | ||||||
16086 | if (!D) | ||||||
16087 | continue; | ||||||
16088 | |||||||
16089 | QualType Type = D->getType(); | ||||||
16090 | auto *VD = dyn_cast<VarDecl>(D); | ||||||
16091 | |||||||
16092 | // OpenMP [2.14.4.2, Restrictions, p.2] | ||||||
16093 | // A list item that appears in a copyprivate clause may not appear in a | ||||||
16094 | // private or firstprivate clause on the single construct. | ||||||
16095 | if (!VD || !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isThreadPrivate(VD)) { | ||||||
16096 | DSAStackTy::DSAVarData DVar = | ||||||
16097 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); | ||||||
16098 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && | ||||||
16099 | DVar.RefExpr) { | ||||||
16100 | Diag(ELoc, diag::err_omp_wrong_dsa) | ||||||
16101 | << getOpenMPClauseName(DVar.CKind) | ||||||
16102 | << getOpenMPClauseName(OMPC_copyprivate); | ||||||
16103 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||
16104 | continue; | ||||||
16105 | } | ||||||
16106 | |||||||
16107 | // OpenMP [2.11.4.2, Restrictions, p.1] | ||||||
16108 | // All list items that appear in a copyprivate clause must be either | ||||||
16109 | // threadprivate or private in the enclosing context. | ||||||
16110 | if (DVar.CKind == OMPC_unknown) { | ||||||
16111 | DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getImplicitDSA(D, false); | ||||||
16112 | if (DVar.CKind == OMPC_shared) { | ||||||
16113 | Diag(ELoc, diag::err_omp_required_access) | ||||||
16114 | << getOpenMPClauseName(OMPC_copyprivate) | ||||||
16115 | << "threadprivate or private in the enclosing context"; | ||||||
16116 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||
16117 | continue; | ||||||
16118 | } | ||||||
16119 | } | ||||||
16120 | } | ||||||
16121 | |||||||
16122 | // Variably modified types are not supported. | ||||||
16123 | if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { | ||||||
16124 | Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) | ||||||
16125 | << getOpenMPClauseName(OMPC_copyprivate) << Type | ||||||
16126 | << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()); | ||||||
16127 | bool IsDecl = | ||||||
16128 | !VD || | ||||||
16129 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||||
16130 | Diag(D->getLocation(), | ||||||
16131 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||||
16132 | << D; | ||||||
16133 | continue; | ||||||
16134 | } | ||||||
16135 | |||||||
16136 | // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] | ||||||
16137 | // A variable of class type (or array thereof) that appears in a | ||||||
16138 | // copyin clause requires an accessible, unambiguous copy assignment | ||||||
16139 | // operator for the class type. | ||||||
16140 | Type = Context.getBaseElementType(Type.getNonReferenceType()) | ||||||
16141 | .getUnqualifiedType(); | ||||||
16142 | VarDecl *SrcVD = | ||||||
16143 | buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", | ||||||
16144 | D->hasAttrs() ? &D->getAttrs() : nullptr); | ||||||
16145 | DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); | ||||||
16146 | VarDecl *DstVD = | ||||||
16147 | buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", | ||||||
16148 | D->hasAttrs() ? &D->getAttrs() : nullptr); | ||||||
16149 | DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); | ||||||
16150 | ExprResult AssignmentOp = BuildBinOp( | ||||||
16151 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); | ||||||
16152 | if (AssignmentOp.isInvalid()) | ||||||
16153 | continue; | ||||||
16154 | AssignmentOp = | ||||||
16155 | ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); | ||||||
16156 | if (AssignmentOp.isInvalid()) | ||||||
16157 | continue; | ||||||
16158 | |||||||
16159 | // No need to mark vars as copyprivate, they are already threadprivate or | ||||||
16160 | // implicitly private. | ||||||
16161 | assert(VD || isOpenMPCapturedDecl(D))((VD || isOpenMPCapturedDecl(D)) ? static_cast<void> (0 ) : __assert_fail ("VD || isOpenMPCapturedDecl(D)", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16161, __PRETTY_FUNCTION__)); | ||||||
16162 | Vars.push_back( | ||||||
16163 | VD ? RefExpr->IgnoreParens() | ||||||
16164 | : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); | ||||||
16165 | SrcExprs.push_back(PseudoSrcExpr); | ||||||
16166 | DstExprs.push_back(PseudoDstExpr); | ||||||
16167 | AssignmentOps.push_back(AssignmentOp.get()); | ||||||
16168 | } | ||||||
16169 | |||||||
16170 | if (Vars.empty()) | ||||||
16171 | return nullptr; | ||||||
16172 | |||||||
16173 | return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, | ||||||
16174 | Vars, SrcExprs, DstExprs, AssignmentOps); | ||||||
16175 | } | ||||||
16176 | |||||||
16177 | OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, | ||||||
16178 | SourceLocation StartLoc, | ||||||
16179 | SourceLocation LParenLoc, | ||||||
16180 | SourceLocation EndLoc) { | ||||||
16181 | if (VarList.empty()) | ||||||
16182 | return nullptr; | ||||||
16183 | |||||||
16184 | return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); | ||||||
16185 | } | ||||||
16186 | |||||||
16187 | /// Tries to find omp_depend_t. type. | ||||||
16188 | static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, | ||||||
16189 | bool Diagnose = true) { | ||||||
16190 | QualType OMPDependT = Stack->getOMPDependT(); | ||||||
16191 | if (!OMPDependT.isNull()) | ||||||
16192 | return true; | ||||||
16193 | IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t"); | ||||||
16194 | ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); | ||||||
16195 | if (!PT.getAsOpaquePtr() || PT.get().isNull()) { | ||||||
16196 | if (Diagnose) | ||||||
16197 | S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t"; | ||||||
16198 | return false; | ||||||
16199 | } | ||||||
16200 | Stack->setOMPDependT(PT.get()); | ||||||
16201 | return true; | ||||||
16202 | } | ||||||
16203 | |||||||
16204 | OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, | ||||||
16205 | SourceLocation LParenLoc, | ||||||
16206 | SourceLocation EndLoc) { | ||||||
16207 | if (!Depobj) | ||||||
16208 | return nullptr; | ||||||
16209 | |||||||
16210 | bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )); | ||||||
16211 | |||||||
16212 | // OpenMP 5.0, 2.17.10.1 depobj Construct | ||||||
16213 | // depobj is an lvalue expression of type omp_depend_t. | ||||||
16214 | if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() && | ||||||
16215 | !Depobj->isInstantiationDependent() && | ||||||
16216 | !Depobj->containsUnexpandedParameterPack() && | ||||||
16217 | (OMPDependTFound && | ||||||
16218 | !Context.typesAreCompatible(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPDependT(), Depobj->getType(), | ||||||
16219 | /*CompareUnqualified=*/true))) { | ||||||
16220 | Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) | ||||||
16221 | << 0 << Depobj->getType() << Depobj->getSourceRange(); | ||||||
16222 | } | ||||||
16223 | |||||||
16224 | if (!Depobj->isLValue()) { | ||||||
16225 | Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) | ||||||
16226 | << 1 << Depobj->getSourceRange(); | ||||||
16227 | } | ||||||
16228 | |||||||
16229 | return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj); | ||||||
16230 | } | ||||||
16231 | |||||||
16232 | OMPClause * | ||||||
16233 | Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, | ||||||
16234 | SourceLocation DepLoc, SourceLocation ColonLoc, | ||||||
16235 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, | ||||||
16236 | SourceLocation LParenLoc, SourceLocation EndLoc) { | ||||||
16237 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() == OMPD_ordered && | ||||||
16238 | DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { | ||||||
16239 | Diag(DepLoc, diag::err_omp_unexpected_clause_value) | ||||||
16240 | << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); | ||||||
16241 | return nullptr; | ||||||
16242 | } | ||||||
16243 | if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() != OMPD_ordered || | ||||||
16244 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() == OMPD_depobj) && | ||||||
16245 | (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || | ||||||
16246 | DepKind == OMPC_DEPEND_sink || | ||||||
16247 | ((LangOpts.OpenMP < 50 || | ||||||
16248 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() == OMPD_depobj) && | ||||||
16249 | DepKind == OMPC_DEPEND_depobj))) { | ||||||
16250 | SmallVector<unsigned, 3> Except; | ||||||
16251 | Except.push_back(OMPC_DEPEND_source); | ||||||
16252 | Except.push_back(OMPC_DEPEND_sink); | ||||||
16253 | if (LangOpts.OpenMP < 50 || DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() == OMPD_depobj) | ||||||
16254 | Except.push_back(OMPC_DEPEND_depobj); | ||||||
16255 | std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier) | ||||||
16256 | ? "depend modifier(iterator) or " | ||||||
16257 | : ""; | ||||||
16258 | Diag(DepLoc, diag::err_omp_unexpected_clause_value) | ||||||
16259 | << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0, | ||||||
16260 | /*Last=*/OMPC_DEPEND_unknown, | ||||||
16261 | Except) | ||||||
16262 | << getOpenMPClauseName(OMPC_depend); | ||||||
16263 | return nullptr; | ||||||
16264 | } | ||||||
16265 | if (DepModifier && | ||||||
16266 | (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) { | ||||||
16267 | Diag(DepModifier->getExprLoc(), | ||||||
16268 | diag::err_omp_depend_sink_source_with_modifier); | ||||||
16269 | return nullptr; | ||||||
16270 | } | ||||||
16271 | if (DepModifier && | ||||||
16272 | !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator)) | ||||||
16273 | Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator); | ||||||
16274 | |||||||
16275 | SmallVector<Expr *, 8> Vars; | ||||||
16276 | DSAStackTy::OperatorOffsetTy OpsOffs; | ||||||
16277 | llvm::APSInt DepCounter(/*BitWidth=*/32); | ||||||
16278 | llvm::APSInt TotalDepCount(/*BitWidth=*/32); | ||||||
16279 | if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { | ||||||
16280 | if (const Expr *OrderedCountExpr = | ||||||
16281 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentOrderedRegionParam().first) { | ||||||
16282 | TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); | ||||||
16283 | TotalDepCount.setIsUnsigned(/*Val=*/true); | ||||||
16284 | } | ||||||
16285 | } | ||||||
16286 | for (Expr *RefExpr : VarList) { | ||||||
16287 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16287, __PRETTY_FUNCTION__)); | ||||||
16288 | if (isa<DependentScopeDeclRefExpr>(RefExpr)) { | ||||||
16289 | // It will be analyzed later. | ||||||
16290 | Vars.push_back(RefExpr); | ||||||
16291 | continue; | ||||||
16292 | } | ||||||
16293 | |||||||
16294 | SourceLocation ELoc = RefExpr->getExprLoc(); | ||||||
16295 | Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); | ||||||
16296 | if (DepKind == OMPC_DEPEND_sink) { | ||||||
16297 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentOrderedRegionParam().first && | ||||||
16298 | DepCounter >= TotalDepCount) { | ||||||
16299 | Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); | ||||||
16300 | continue; | ||||||
16301 | } | ||||||
16302 | ++DepCounter; | ||||||
16303 | // OpenMP [2.13.9, Summary] | ||||||
16304 | // depend(dependence-type : vec), where dependence-type is: | ||||||
16305 | // 'sink' and where vec is the iteration vector, which has the form: | ||||||
16306 | // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] | ||||||
16307 | // where n is the value specified by the ordered clause in the loop | ||||||
16308 | // directive, xi denotes the loop iteration variable of the i-th nested | ||||||
16309 | // loop associated with the loop directive, and di is a constant | ||||||
16310 | // non-negative integer. | ||||||
16311 | if (CurContext->isDependentContext()) { | ||||||
16312 | // It will be analyzed later. | ||||||
16313 | Vars.push_back(RefExpr); | ||||||
16314 | continue; | ||||||
16315 | } | ||||||
16316 | SimpleExpr = SimpleExpr->IgnoreImplicit(); | ||||||
16317 | OverloadedOperatorKind OOK = OO_None; | ||||||
16318 | SourceLocation OOLoc; | ||||||
16319 | Expr *LHS = SimpleExpr; | ||||||
16320 | Expr *RHS = nullptr; | ||||||
16321 | if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { | ||||||
16322 | OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); | ||||||
16323 | OOLoc = BO->getOperatorLoc(); | ||||||
16324 | LHS = BO->getLHS()->IgnoreParenImpCasts(); | ||||||
16325 | RHS = BO->getRHS()->IgnoreParenImpCasts(); | ||||||
16326 | } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { | ||||||
16327 | OOK = OCE->getOperator(); | ||||||
16328 | OOLoc = OCE->getOperatorLoc(); | ||||||
16329 | LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); | ||||||
16330 | RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); | ||||||
16331 | } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { | ||||||
16332 | OOK = MCE->getMethodDecl() | ||||||
16333 | ->getNameInfo() | ||||||
16334 | .getName() | ||||||
16335 | .getCXXOverloadedOperator(); | ||||||
16336 | OOLoc = MCE->getCallee()->getExprLoc(); | ||||||
16337 | LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); | ||||||
16338 | RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); | ||||||
16339 | } | ||||||
16340 | SourceLocation ELoc; | ||||||
16341 | SourceRange ERange; | ||||||
16342 | auto Res = getPrivateItem(*this, LHS, ELoc, ERange); | ||||||
16343 | if (Res.second) { | ||||||
16344 | // It will be analyzed later. | ||||||
16345 | Vars.push_back(RefExpr); | ||||||
16346 | } | ||||||
16347 | ValueDecl *D = Res.first; | ||||||
16348 | if (!D) | ||||||
16349 | continue; | ||||||
16350 | |||||||
16351 | if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { | ||||||
16352 | Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); | ||||||
16353 | continue; | ||||||
16354 | } | ||||||
16355 | if (RHS) { | ||||||
16356 | ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( | ||||||
16357 | RHS, OMPC_depend, /*StrictlyPositive=*/false); | ||||||
16358 | if (RHSRes.isInvalid()) | ||||||
16359 | continue; | ||||||
16360 | } | ||||||
16361 | if (!CurContext->isDependentContext() && | ||||||
16362 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentOrderedRegionParam().first && | ||||||
16363 | DepCounter != DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isParentLoopControlVariable(D).first) { | ||||||
16364 | const ValueDecl *VD = | ||||||
16365 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentLoopControlVariable(DepCounter.getZExtValue()); | ||||||
16366 | if (VD) | ||||||
16367 | Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) | ||||||
16368 | << 1 << VD; | ||||||
16369 | else | ||||||
16370 | Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; | ||||||
16371 | continue; | ||||||
16372 | } | ||||||
16373 | OpsOffs.emplace_back(RHS, OOK); | ||||||
16374 | } else { | ||||||
16375 | bool OMPDependTFound = LangOpts.OpenMP >= 50; | ||||||
16376 | if (OMPDependTFound) | ||||||
16377 | OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), | ||||||
16378 | DepKind == OMPC_DEPEND_depobj); | ||||||
16379 | if (DepKind == OMPC_DEPEND_depobj) { | ||||||
16380 | // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ | ||||||
16381 | // List items used in depend clauses with the depobj dependence type | ||||||
16382 | // must be expressions of the omp_depend_t type. | ||||||
16383 | if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && | ||||||
16384 | !RefExpr->isInstantiationDependent() && | ||||||
16385 | !RefExpr->containsUnexpandedParameterPack() && | ||||||
16386 | (OMPDependTFound && | ||||||
16387 | !Context.hasSameUnqualifiedType(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPDependT(), | ||||||
16388 | RefExpr->getType()))) { | ||||||
16389 | Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) | ||||||
16390 | << 0 << RefExpr->getType() << RefExpr->getSourceRange(); | ||||||
16391 | continue; | ||||||
16392 | } | ||||||
16393 | if (!RefExpr->isLValue()) { | ||||||
16394 | Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) | ||||||
16395 | << 1 << RefExpr->getType() << RefExpr->getSourceRange(); | ||||||
16396 | continue; | ||||||
16397 | } | ||||||
16398 | } else { | ||||||
16399 | // OpenMP 5.0 [2.17.11, Restrictions] | ||||||
16400 | // List items used in depend clauses cannot be zero-length array | ||||||
16401 | // sections. | ||||||
16402 | QualType ExprTy = RefExpr->getType().getNonReferenceType(); | ||||||
16403 | const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); | ||||||
16404 | if (OASE) { | ||||||
16405 | QualType BaseType = | ||||||
16406 | OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); | ||||||
16407 | if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) | ||||||
16408 | ExprTy = ATy->getElementType(); | ||||||
16409 | else | ||||||
16410 | ExprTy = BaseType->getPointeeType(); | ||||||
16411 | ExprTy = ExprTy.getNonReferenceType(); | ||||||
16412 | const Expr *Length = OASE->getLength(); | ||||||
16413 | Expr::EvalResult Result; | ||||||
16414 | if (Length && !Length->isValueDependent() && | ||||||
16415 | Length->EvaluateAsInt(Result, Context) && | ||||||
16416 | Result.Val.getInt().isNullValue()) { | ||||||
16417 | Diag(ELoc, | ||||||
16418 | diag::err_omp_depend_zero_length_array_section_not_allowed) | ||||||
16419 | << SimpleExpr->getSourceRange(); | ||||||
16420 | continue; | ||||||
16421 | } | ||||||
16422 | } | ||||||
16423 | |||||||
16424 | // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ | ||||||
16425 | // List items used in depend clauses with the in, out, inout or | ||||||
16426 | // mutexinoutset dependence types cannot be expressions of the | ||||||
16427 | // omp_depend_t type. | ||||||
16428 | if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && | ||||||
16429 | !RefExpr->isInstantiationDependent() && | ||||||
16430 | !RefExpr->containsUnexpandedParameterPack() && | ||||||
16431 | (OMPDependTFound && | ||||||
16432 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) { | ||||||
16433 | Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) | ||||||
16434 | << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1 | ||||||
16435 | << RefExpr->getSourceRange(); | ||||||
16436 | continue; | ||||||
16437 | } | ||||||
16438 | |||||||
16439 | auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); | ||||||
16440 | if (!RefExpr->IgnoreParenImpCasts()->isLValue() || | ||||||
16441 | (ASE && !ASE->getBase()->isTypeDependent() && | ||||||
16442 | !ASE->getBase() | ||||||
16443 | ->getType() | ||||||
16444 | .getNonReferenceType() | ||||||
16445 | ->isPointerType() && | ||||||
16446 | !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { | ||||||
16447 | Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) | ||||||
16448 | << (LangOpts.OpenMP >= 50 ? 1 : 0) | ||||||
16449 | << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); | ||||||
16450 | continue; | ||||||
16451 | } | ||||||
16452 | |||||||
16453 | ExprResult Res; | ||||||
16454 | { | ||||||
16455 | Sema::TentativeAnalysisScope Trap(*this); | ||||||
16456 | Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, | ||||||
16457 | RefExpr->IgnoreParenImpCasts()); | ||||||
16458 | } | ||||||
16459 | if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && | ||||||
16460 | !isa<OMPArrayShapingExpr>(SimpleExpr)) { | ||||||
16461 | Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) | ||||||
16462 | << (LangOpts.OpenMP >= 50 ? 1 : 0) | ||||||
16463 | << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); | ||||||
16464 | continue; | ||||||
16465 | } | ||||||
16466 | } | ||||||
16467 | } | ||||||
16468 | Vars.push_back(RefExpr->IgnoreParenImpCasts()); | ||||||
16469 | } | ||||||
16470 | |||||||
16471 | if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && | ||||||
16472 | TotalDepCount > VarList.size() && | ||||||
16473 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentOrderedRegionParam().first && | ||||||
16474 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentLoopControlVariable(VarList.size() + 1)) { | ||||||
16475 | Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) | ||||||
16476 | << 1 << DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentLoopControlVariable(VarList.size() + 1); | ||||||
16477 | } | ||||||
16478 | if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && | ||||||
16479 | Vars.empty()) | ||||||
16480 | return nullptr; | ||||||
16481 | |||||||
16482 | auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, | ||||||
16483 | DepModifier, DepKind, DepLoc, ColonLoc, | ||||||
16484 | Vars, TotalDepCount.getZExtValue()); | ||||||
16485 | if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && | ||||||
16486 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isParentOrderedRegion()) | ||||||
16487 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDoacrossDependClause(C, OpsOffs); | ||||||
16488 | return C; | ||||||
16489 | } | ||||||
16490 | |||||||
16491 | OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, | ||||||
16492 | Expr *Device, SourceLocation StartLoc, | ||||||
16493 | SourceLocation LParenLoc, | ||||||
16494 | SourceLocation ModifierLoc, | ||||||
16495 | SourceLocation EndLoc) { | ||||||
16496 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16497, __PRETTY_FUNCTION__)) | ||||||
16497 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16497, __PRETTY_FUNCTION__)); | ||||||
16498 | |||||||
16499 | bool ErrorFound = false; | ||||||
16500 | if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) { | ||||||
16501 | std::string Values = | ||||||
16502 | getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown); | ||||||
16503 | Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) | ||||||
16504 | << Values << getOpenMPClauseName(OMPC_device); | ||||||
16505 | ErrorFound = true; | ||||||
16506 | } | ||||||
16507 | |||||||
16508 | Expr *ValExpr = Device; | ||||||
16509 | Stmt *HelperValStmt = nullptr; | ||||||
16510 | |||||||
16511 | // OpenMP [2.9.1, Restrictions] | ||||||
16512 | // The device expression must evaluate to a non-negative integer value. | ||||||
16513 | ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, | ||||||
16514 | /*StrictlyPositive=*/false) || | ||||||
16515 | ErrorFound; | ||||||
16516 | if (ErrorFound) | ||||||
16517 | return nullptr; | ||||||
16518 | |||||||
16519 | OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); | ||||||
16520 | OpenMPDirectiveKind CaptureRegion = | ||||||
16521 | getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); | ||||||
16522 | if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { | ||||||
16523 | ValExpr = MakeFullExpr(ValExpr).get(); | ||||||
16524 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; | ||||||
16525 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); | ||||||
16526 | HelperValStmt = buildPreInits(Context, Captures); | ||||||
16527 | } | ||||||
16528 | |||||||
16529 | return new (Context) | ||||||
16530 | OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, | ||||||
16531 | LParenLoc, ModifierLoc, EndLoc); | ||||||
16532 | } | ||||||
16533 | |||||||
16534 | static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, | ||||||
16535 | DSAStackTy *Stack, QualType QTy, | ||||||
16536 | bool FullCheck = true) { | ||||||
16537 | NamedDecl *ND; | ||||||
16538 | if (QTy->isIncompleteType(&ND)) { | ||||||
16539 | SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; | ||||||
16540 | return false; | ||||||
16541 | } | ||||||
16542 | if (FullCheck && !SemaRef.CurContext->isDependentContext() && | ||||||
16543 | !QTy.isTriviallyCopyableType(SemaRef.Context)) | ||||||
16544 | SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; | ||||||
16545 | return true; | ||||||
16546 | } | ||||||
16547 | |||||||
16548 | /// Return true if it can be proven that the provided array expression | ||||||
16549 | /// (array section or array subscript) does NOT specify the whole size of the | ||||||
16550 | /// array whose base type is \a BaseQTy. | ||||||
16551 | static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, | ||||||
16552 | const Expr *E, | ||||||
16553 | QualType BaseQTy) { | ||||||
16554 | const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); | ||||||
16555 | |||||||
16556 | // If this is an array subscript, it refers to the whole size if the size of | ||||||
16557 | // the dimension is constant and equals 1. Also, an array section assumes the | ||||||
16558 | // format of an array subscript if no colon is used. | ||||||
16559 | if (isa<ArraySubscriptExpr>(E) || | ||||||
16560 | (OASE && OASE->getColonLocFirst().isInvalid())) { | ||||||
16561 | if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) | ||||||
16562 | return ATy->getSize().getSExtValue() != 1; | ||||||
16563 | // Size can't be evaluated statically. | ||||||
16564 | return false; | ||||||
16565 | } | ||||||
16566 | |||||||
16567 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16567, __PRETTY_FUNCTION__)); | ||||||
16568 | const Expr *LowerBound = OASE->getLowerBound(); | ||||||
16569 | const Expr *Length = OASE->getLength(); | ||||||
16570 | |||||||
16571 | // If there is a lower bound that does not evaluates to zero, we are not | ||||||
16572 | // covering the whole dimension. | ||||||
16573 | if (LowerBound) { | ||||||
16574 | Expr::EvalResult Result; | ||||||
16575 | if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) | ||||||
16576 | return false; // Can't get the integer value as a constant. | ||||||
16577 | |||||||
16578 | llvm::APSInt ConstLowerBound = Result.Val.getInt(); | ||||||
16579 | if (ConstLowerBound.getSExtValue()) | ||||||
16580 | return true; | ||||||
16581 | } | ||||||
16582 | |||||||
16583 | // If we don't have a length we covering the whole dimension. | ||||||
16584 | if (!Length) | ||||||
16585 | return false; | ||||||
16586 | |||||||
16587 | // If the base is a pointer, we don't have a way to get the size of the | ||||||
16588 | // pointee. | ||||||
16589 | if (BaseQTy->isPointerType()) | ||||||
16590 | return false; | ||||||
16591 | |||||||
16592 | // We can only check if the length is the same as the size of the dimension | ||||||
16593 | // if we have a constant array. | ||||||
16594 | const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); | ||||||
16595 | if (!CATy) | ||||||
16596 | return false; | ||||||
16597 | |||||||
16598 | Expr::EvalResult Result; | ||||||
16599 | if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) | ||||||
16600 | return false; // Can't get the integer value as a constant. | ||||||
16601 | |||||||
16602 | llvm::APSInt ConstLength = Result.Val.getInt(); | ||||||
16603 | return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); | ||||||
16604 | } | ||||||
16605 | |||||||
16606 | // Return true if it can be proven that the provided array expression (array | ||||||
16607 | // section or array subscript) does NOT specify a single element of the array | ||||||
16608 | // whose base type is \a BaseQTy. | ||||||
16609 | static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, | ||||||
16610 | const Expr *E, | ||||||
16611 | QualType BaseQTy) { | ||||||
16612 | const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); | ||||||
16613 | |||||||
16614 | // An array subscript always refer to a single element. Also, an array section | ||||||
16615 | // assumes the format of an array subscript if no colon is used. | ||||||
16616 | if (isa<ArraySubscriptExpr>(E) || | ||||||
16617 | (OASE && OASE->getColonLocFirst().isInvalid())) | ||||||
16618 | return false; | ||||||
16619 | |||||||
16620 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16620, __PRETTY_FUNCTION__)); | ||||||
16621 | const Expr *Length = OASE->getLength(); | ||||||
16622 | |||||||
16623 | // If we don't have a length we have to check if the array has unitary size | ||||||
16624 | // for this dimension. Also, we should always expect a length if the base type | ||||||
16625 | // is pointer. | ||||||
16626 | if (!Length) { | ||||||
16627 | if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) | ||||||
16628 | return ATy->getSize().getSExtValue() != 1; | ||||||
16629 | // We cannot assume anything. | ||||||
16630 | return false; | ||||||
16631 | } | ||||||
16632 | |||||||
16633 | // Check if the length evaluates to 1. | ||||||
16634 | Expr::EvalResult Result; | ||||||
16635 | if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) | ||||||
16636 | return false; // Can't get the integer value as a constant. | ||||||
16637 | |||||||
16638 | llvm::APSInt ConstLength = Result.Val.getInt(); | ||||||
16639 | return ConstLength.getSExtValue() != 1; | ||||||
16640 | } | ||||||
16641 | |||||||
16642 | // The base of elements of list in a map clause have to be either: | ||||||
16643 | // - a reference to variable or field. | ||||||
16644 | // - a member expression. | ||||||
16645 | // - an array expression. | ||||||
16646 | // | ||||||
16647 | // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the | ||||||
16648 | // reference to 'r'. | ||||||
16649 | // | ||||||
16650 | // If we have: | ||||||
16651 | // | ||||||
16652 | // struct SS { | ||||||
16653 | // Bla S; | ||||||
16654 | // foo() { | ||||||
16655 | // #pragma omp target map (S.Arr[:12]); | ||||||
16656 | // } | ||||||
16657 | // } | ||||||
16658 | // | ||||||
16659 | // We want to retrieve the member expression 'this->S'; | ||||||
16660 | |||||||
16661 | // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2] | ||||||
16662 | // If a list item is an array section, it must specify contiguous storage. | ||||||
16663 | // | ||||||
16664 | // For this restriction it is sufficient that we make sure only references | ||||||
16665 | // to variables or fields and array expressions, and that no array sections | ||||||
16666 | // exist except in the rightmost expression (unless they cover the whole | ||||||
16667 | // dimension of the array). E.g. these would be invalid: | ||||||
16668 | // | ||||||
16669 | // r.ArrS[3:5].Arr[6:7] | ||||||
16670 | // | ||||||
16671 | // r.ArrS[3:5].x | ||||||
16672 | // | ||||||
16673 | // but these would be valid: | ||||||
16674 | // r.ArrS[3].Arr[6:7] | ||||||
16675 | // | ||||||
16676 | // r.ArrS[3].x | ||||||
16677 | namespace { | ||||||
16678 | class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> { | ||||||
16679 | Sema &SemaRef; | ||||||
16680 | OpenMPClauseKind CKind = OMPC_unknown; | ||||||
16681 | OMPClauseMappableExprCommon::MappableExprComponentList &Components; | ||||||
16682 | bool NoDiagnose = false; | ||||||
16683 | const Expr *RelevantExpr = nullptr; | ||||||
16684 | bool AllowUnitySizeArraySection = true; | ||||||
16685 | bool AllowWholeSizeArraySection = true; | ||||||
16686 | SourceLocation ELoc; | ||||||
16687 | SourceRange ERange; | ||||||
16688 | |||||||
16689 | void emitErrorMsg() { | ||||||
16690 | // If nothing else worked, this is not a valid map clause expression. | ||||||
16691 | if (SemaRef.getLangOpts().OpenMP < 50) { | ||||||
16692 | SemaRef.Diag(ELoc, | ||||||
16693 | diag::err_omp_expected_named_var_member_or_array_expression) | ||||||
16694 | << ERange; | ||||||
16695 | } else { | ||||||
16696 | SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) | ||||||
16697 | << getOpenMPClauseName(CKind) << ERange; | ||||||
16698 | } | ||||||
16699 | } | ||||||
16700 | |||||||
16701 | public: | ||||||
16702 | bool VisitDeclRefExpr(DeclRefExpr *DRE) { | ||||||
16703 | if (!isa<VarDecl>(DRE->getDecl())) { | ||||||
16704 | emitErrorMsg(); | ||||||
16705 | return false; | ||||||
16706 | } | ||||||
16707 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16707, __PRETTY_FUNCTION__)); | ||||||
16708 | RelevantExpr = DRE; | ||||||
16709 | // Record the component. | ||||||
16710 | Components.emplace_back(DRE, DRE->getDecl()); | ||||||
16711 | return true; | ||||||
16712 | } | ||||||
16713 | |||||||
16714 | bool VisitMemberExpr(MemberExpr *ME) { | ||||||
16715 | Expr *E = ME; | ||||||
16716 | Expr *BaseE = ME->getBase()->IgnoreParenCasts(); | ||||||
16717 | |||||||
16718 | if (isa<CXXThisExpr>(BaseE)) { | ||||||
16719 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16719, __PRETTY_FUNCTION__)); | ||||||
16720 | // We found a base expression: this->Val. | ||||||
16721 | RelevantExpr = ME; | ||||||
16722 | } else { | ||||||
16723 | E = BaseE; | ||||||
16724 | } | ||||||
16725 | |||||||
16726 | if (!isa<FieldDecl>(ME->getMemberDecl())) { | ||||||
16727 | if (!NoDiagnose) { | ||||||
16728 | SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) | ||||||
16729 | << ME->getSourceRange(); | ||||||
16730 | return false; | ||||||
16731 | } | ||||||
16732 | if (RelevantExpr) | ||||||
16733 | return false; | ||||||
16734 | return Visit(E); | ||||||
16735 | } | ||||||
16736 | |||||||
16737 | auto *FD = cast<FieldDecl>(ME->getMemberDecl()); | ||||||
16738 | |||||||
16739 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] | ||||||
16740 | // A bit-field cannot appear in a map clause. | ||||||
16741 | // | ||||||
16742 | if (FD->isBitField()) { | ||||||
16743 | if (!NoDiagnose) { | ||||||
16744 | SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) | ||||||
16745 | << ME->getSourceRange() << getOpenMPClauseName(CKind); | ||||||
16746 | return false; | ||||||
16747 | } | ||||||
16748 | if (RelevantExpr) | ||||||
16749 | return false; | ||||||
16750 | return Visit(E); | ||||||
16751 | } | ||||||
16752 | |||||||
16753 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] | ||||||
16754 | // If the type of a list item is a reference to a type T then the type | ||||||
16755 | // will be considered to be T for all purposes of this clause. | ||||||
16756 | QualType CurType = BaseE->getType().getNonReferenceType(); | ||||||
16757 | |||||||
16758 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] | ||||||
16759 | // A list item cannot be a variable that is a member of a structure with | ||||||
16760 | // a union type. | ||||||
16761 | // | ||||||
16762 | if (CurType->isUnionType()) { | ||||||
16763 | if (!NoDiagnose) { | ||||||
16764 | SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) | ||||||
16765 | << ME->getSourceRange(); | ||||||
16766 | return false; | ||||||
16767 | } | ||||||
16768 | return RelevantExpr || Visit(E); | ||||||
16769 | } | ||||||
16770 | |||||||
16771 | // If we got a member expression, we should not expect any array section | ||||||
16772 | // before that: | ||||||
16773 | // | ||||||
16774 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] | ||||||
16775 | // If a list item is an element of a structure, only the rightmost symbol | ||||||
16776 | // of the variable reference can be an array section. | ||||||
16777 | // | ||||||
16778 | AllowUnitySizeArraySection = false; | ||||||
16779 | AllowWholeSizeArraySection = false; | ||||||
16780 | |||||||
16781 | // Record the component. | ||||||
16782 | Components.emplace_back(ME, FD); | ||||||
16783 | return RelevantExpr || Visit(E); | ||||||
16784 | } | ||||||
16785 | |||||||
16786 | bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) { | ||||||
16787 | Expr *E = AE->getBase()->IgnoreParenImpCasts(); | ||||||
16788 | |||||||
16789 | if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { | ||||||
16790 | if (!NoDiagnose) { | ||||||
16791 | SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) | ||||||
16792 | << 0 << AE->getSourceRange(); | ||||||
16793 | return false; | ||||||
16794 | } | ||||||
16795 | return RelevantExpr || Visit(E); | ||||||
16796 | } | ||||||
16797 | |||||||
16798 | // If we got an array subscript that express the whole dimension we | ||||||
16799 | // can have any array expressions before. If it only expressing part of | ||||||
16800 | // the dimension, we can only have unitary-size array expressions. | ||||||
16801 | if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, | ||||||
16802 | E->getType())) | ||||||
16803 | AllowWholeSizeArraySection = false; | ||||||
16804 | |||||||
16805 | if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) { | ||||||
16806 | Expr::EvalResult Result; | ||||||
16807 | if (!AE->getIdx()->isValueDependent() && | ||||||
16808 | AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) && | ||||||
16809 | !Result.Val.getInt().isNullValue()) { | ||||||
16810 | SemaRef.Diag(AE->getIdx()->getExprLoc(), | ||||||
16811 | diag::err_omp_invalid_map_this_expr); | ||||||
16812 | SemaRef.Diag(AE->getIdx()->getExprLoc(), | ||||||
16813 | diag::note_omp_invalid_subscript_on_this_ptr_map); | ||||||
16814 | } | ||||||
16815 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16815, __PRETTY_FUNCTION__)); | ||||||
16816 | RelevantExpr = TE; | ||||||
16817 | } | ||||||
16818 | |||||||
16819 | // Record the component - we don't have any declaration associated. | ||||||
16820 | Components.emplace_back(AE, nullptr); | ||||||
16821 | |||||||
16822 | return RelevantExpr || Visit(E); | ||||||
16823 | } | ||||||
16824 | |||||||
16825 | bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) { | ||||||
16826 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16826, __PRETTY_FUNCTION__)); | ||||||
16827 | Expr *E = OASE->getBase()->IgnoreParenImpCasts(); | ||||||
16828 | QualType CurType = | ||||||
16829 | OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); | ||||||
16830 | |||||||
16831 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] | ||||||
16832 | // If the type of a list item is a reference to a type T then the type | ||||||
16833 | // will be considered to be T for all purposes of this clause. | ||||||
16834 | if (CurType->isReferenceType()) | ||||||
16835 | CurType = CurType->getPointeeType(); | ||||||
16836 | |||||||
16837 | bool IsPointer = CurType->isAnyPointerType(); | ||||||
16838 | |||||||
16839 | if (!IsPointer && !CurType->isArrayType()) { | ||||||
16840 | SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) | ||||||
16841 | << 0 << OASE->getSourceRange(); | ||||||
16842 | return false; | ||||||
16843 | } | ||||||
16844 | |||||||
16845 | bool NotWhole = | ||||||
16846 | checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType); | ||||||
16847 | bool NotUnity = | ||||||
16848 | checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType); | ||||||
16849 | |||||||
16850 | if (AllowWholeSizeArraySection) { | ||||||
16851 | // Any array section is currently allowed. Allowing a whole size array | ||||||
16852 | // section implies allowing a unity array section as well. | ||||||
16853 | // | ||||||
16854 | // If this array section refers to the whole dimension we can still | ||||||
16855 | // accept other array sections before this one, except if the base is a | ||||||
16856 | // pointer. Otherwise, only unitary sections are accepted. | ||||||
16857 | if (NotWhole || IsPointer) | ||||||
16858 | AllowWholeSizeArraySection = false; | ||||||
16859 | } else if (AllowUnitySizeArraySection && NotUnity) { | ||||||
16860 | // A unity or whole array section is not allowed and that is not | ||||||
16861 | // compatible with the properties of the current array section. | ||||||
16862 | SemaRef.Diag( | ||||||
16863 | ELoc, diag::err_array_section_does_not_specify_contiguous_storage) | ||||||
16864 | << OASE->getSourceRange(); | ||||||
16865 | return false; | ||||||
16866 | } | ||||||
16867 | |||||||
16868 | if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { | ||||||
16869 | Expr::EvalResult ResultR; | ||||||
16870 | Expr::EvalResult ResultL; | ||||||
16871 | if (!OASE->getLength()->isValueDependent() && | ||||||
16872 | OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) && | ||||||
16873 | !ResultR.Val.getInt().isOneValue()) { | ||||||
16874 | SemaRef.Diag(OASE->getLength()->getExprLoc(), | ||||||
16875 | diag::err_omp_invalid_map_this_expr); | ||||||
16876 | SemaRef.Diag(OASE->getLength()->getExprLoc(), | ||||||
16877 | diag::note_omp_invalid_length_on_this_ptr_mapping); | ||||||
16878 | } | ||||||
16879 | if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() && | ||||||
16880 | OASE->getLowerBound()->EvaluateAsInt(ResultL, | ||||||
16881 | SemaRef.getASTContext()) && | ||||||
16882 | !ResultL.Val.getInt().isNullValue()) { | ||||||
16883 | SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), | ||||||
16884 | diag::err_omp_invalid_map_this_expr); | ||||||
16885 | SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), | ||||||
16886 | diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); | ||||||
16887 | } | ||||||
16888 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16888, __PRETTY_FUNCTION__)); | ||||||
16889 | RelevantExpr = TE; | ||||||
16890 | } | ||||||
16891 | |||||||
16892 | // Record the component - we don't have any declaration associated. | ||||||
16893 | Components.emplace_back(OASE, nullptr); | ||||||
16894 | return RelevantExpr || Visit(E); | ||||||
16895 | } | ||||||
16896 | bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { | ||||||
16897 | Expr *Base = E->getBase(); | ||||||
16898 | |||||||
16899 | // Record the component - we don't have any declaration associated. | ||||||
16900 | Components.emplace_back(E, nullptr); | ||||||
16901 | |||||||
16902 | return Visit(Base->IgnoreParenImpCasts()); | ||||||
16903 | } | ||||||
16904 | |||||||
16905 | bool VisitUnaryOperator(UnaryOperator *UO) { | ||||||
16906 | if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() || | ||||||
16907 | UO->getOpcode() != UO_Deref) { | ||||||
16908 | emitErrorMsg(); | ||||||
16909 | return false; | ||||||
16910 | } | ||||||
16911 | if (!RelevantExpr) { | ||||||
16912 | // Record the component if haven't found base decl. | ||||||
16913 | Components.emplace_back(UO, nullptr); | ||||||
16914 | } | ||||||
16915 | return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts()); | ||||||
16916 | } | ||||||
16917 | bool VisitBinaryOperator(BinaryOperator *BO) { | ||||||
16918 | if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) { | ||||||
16919 | emitErrorMsg(); | ||||||
16920 | return false; | ||||||
16921 | } | ||||||
16922 | |||||||
16923 | // Pointer arithmetic is the only thing we expect to happen here so after we | ||||||
16924 | // make sure the binary operator is a pointer type, the we only thing need | ||||||
16925 | // to to is to visit the subtree that has the same type as root (so that we | ||||||
16926 | // know the other subtree is just an offset) | ||||||
16927 | Expr *LE = BO->getLHS()->IgnoreParenImpCasts(); | ||||||
16928 | Expr *RE = BO->getRHS()->IgnoreParenImpCasts(); | ||||||
16929 | Components.emplace_back(BO, nullptr); | ||||||
16930 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16932, __PRETTY_FUNCTION__)) | ||||||
16931 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16932, __PRETTY_FUNCTION__)) | ||||||
16932 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16932, __PRETTY_FUNCTION__)); | ||||||
16933 | if (BO->getType().getTypePtr() == LE->getType().getTypePtr()) | ||||||
16934 | return RelevantExpr || Visit(LE); | ||||||
16935 | return RelevantExpr || Visit(RE); | ||||||
16936 | } | ||||||
16937 | bool VisitCXXThisExpr(CXXThisExpr *CTE) { | ||||||
16938 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16938, __PRETTY_FUNCTION__)); | ||||||
16939 | RelevantExpr = CTE; | ||||||
16940 | Components.emplace_back(CTE, nullptr); | ||||||
16941 | return true; | ||||||
16942 | } | ||||||
16943 | bool VisitStmt(Stmt *) { | ||||||
16944 | emitErrorMsg(); | ||||||
16945 | return false; | ||||||
16946 | } | ||||||
16947 | const Expr *getFoundBase() const { | ||||||
16948 | return RelevantExpr; | ||||||
16949 | } | ||||||
16950 | explicit MapBaseChecker( | ||||||
16951 | Sema &SemaRef, OpenMPClauseKind CKind, | ||||||
16952 | OMPClauseMappableExprCommon::MappableExprComponentList &Components, | ||||||
16953 | bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange) | ||||||
16954 | : SemaRef(SemaRef), CKind(CKind), Components(Components), | ||||||
16955 | NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {} | ||||||
16956 | }; | ||||||
16957 | } // namespace | ||||||
16958 | |||||||
16959 | /// Return the expression of the base of the mappable expression or null if it | ||||||
16960 | /// cannot be determined and do all the necessary checks to see if the expression | ||||||
16961 | /// is valid as a standalone mappable expression. In the process, record all the | ||||||
16962 | /// components of the expression. | ||||||
16963 | static const Expr *checkMapClauseExpressionBase( | ||||||
16964 | Sema &SemaRef, Expr *E, | ||||||
16965 | OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, | ||||||
16966 | OpenMPClauseKind CKind, bool NoDiagnose) { | ||||||
16967 | SourceLocation ELoc = E->getExprLoc(); | ||||||
16968 | SourceRange ERange = E->getSourceRange(); | ||||||
16969 | MapBaseChecker Checker(SemaRef, CKind, CurComponents, NoDiagnose, ELoc, | ||||||
16970 | ERange); | ||||||
16971 | if (Checker.Visit(E->IgnoreParens())) | ||||||
16972 | return Checker.getFoundBase(); | ||||||
16973 | return nullptr; | ||||||
16974 | } | ||||||
16975 | |||||||
16976 | // Return true if expression E associated with value VD has conflicts with other | ||||||
16977 | // map information. | ||||||
16978 | static bool checkMapConflicts( | ||||||
16979 | Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, | ||||||
16980 | bool CurrentRegionOnly, | ||||||
16981 | OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, | ||||||
16982 | OpenMPClauseKind CKind) { | ||||||
16983 | assert(VD && E)((VD && E) ? static_cast<void> (0) : __assert_fail ("VD && E", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16983, __PRETTY_FUNCTION__)); | ||||||
16984 | SourceLocation ELoc = E->getExprLoc(); | ||||||
16985 | SourceRange ERange = E->getSourceRange(); | ||||||
16986 | |||||||
16987 | // In order to easily check the conflicts we need to match each component of | ||||||
16988 | // the expression under test with the components of the expressions that are | ||||||
16989 | // already in the stack. | ||||||
16990 | |||||||
16991 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16991, __PRETTY_FUNCTION__)); | ||||||
16992 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16993, __PRETTY_FUNCTION__)) | ||||||
16993 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16993, __PRETTY_FUNCTION__)); | ||||||
16994 | |||||||
16995 | // Variables to help detecting enclosing problems in data environment nests. | ||||||
16996 | bool IsEnclosedByDataEnvironmentExpr = false; | ||||||
16997 | const Expr *EnclosingExpr = nullptr; | ||||||
16998 | |||||||
16999 | bool FoundError = DSAS->checkMappableExprComponentListsForDecl( | ||||||
17000 | VD, CurrentRegionOnly, | ||||||
17001 | [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, | ||||||
17002 | ERange, CKind, &EnclosingExpr, | ||||||
17003 | CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef | ||||||
17004 | StackComponents, | ||||||
17005 | OpenMPClauseKind) { | ||||||
17006 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17007, __PRETTY_FUNCTION__)) | ||||||
17007 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17007, __PRETTY_FUNCTION__)); | ||||||
17008 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17009, __PRETTY_FUNCTION__)) | ||||||
17009 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17009, __PRETTY_FUNCTION__)); | ||||||
17010 | (void)VD; | ||||||
17011 | |||||||
17012 | // The whole expression in the stack. | ||||||
17013 | const Expr *RE = StackComponents.front().getAssociatedExpression(); | ||||||
17014 | |||||||
17015 | // Expressions must start from the same base. Here we detect at which | ||||||
17016 | // point both expressions diverge from each other and see if we can | ||||||
17017 | // detect if the memory referred to both expressions is contiguous and | ||||||
17018 | // do not overlap. | ||||||
17019 | auto CI = CurComponents.rbegin(); | ||||||
17020 | auto CE = CurComponents.rend(); | ||||||
17021 | auto SI = StackComponents.rbegin(); | ||||||
17022 | auto SE = StackComponents.rend(); | ||||||
17023 | for (; CI != CE && SI != SE; ++CI, ++SI) { | ||||||
17024 | |||||||
17025 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] | ||||||
17026 | // At most one list item can be an array item derived from a given | ||||||
17027 | // variable in map clauses of the same construct. | ||||||
17028 | if (CurrentRegionOnly && | ||||||
17029 | (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || | ||||||
17030 | isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) || | ||||||
17031 | isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) && | ||||||
17032 | (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || | ||||||
17033 | isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) || | ||||||
17034 | isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) { | ||||||
17035 | SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), | ||||||
17036 | diag::err_omp_multiple_array_items_in_map_clause) | ||||||
17037 | << CI->getAssociatedExpression()->getSourceRange(); | ||||||
17038 | SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), | ||||||
17039 | diag::note_used_here) | ||||||
17040 | << SI->getAssociatedExpression()->getSourceRange(); | ||||||
17041 | return true; | ||||||
17042 | } | ||||||
17043 | |||||||
17044 | // Do both expressions have the same kind? | ||||||
17045 | if (CI->getAssociatedExpression()->getStmtClass() != | ||||||
17046 | SI->getAssociatedExpression()->getStmtClass()) | ||||||
17047 | break; | ||||||
17048 | |||||||
17049 | // Are we dealing with different variables/fields? | ||||||
17050 | if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) | ||||||
17051 | break; | ||||||
17052 | } | ||||||
17053 | // Check if the extra components of the expressions in the enclosing | ||||||
17054 | // data environment are redundant for the current base declaration. | ||||||
17055 | // If they are, the maps completely overlap, which is legal. | ||||||
17056 | for (; SI != SE; ++SI) { | ||||||
17057 | QualType Type; | ||||||
17058 | if (const auto *ASE = | ||||||
17059 | dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { | ||||||
17060 | Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); | ||||||
17061 | } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( | ||||||
17062 | SI->getAssociatedExpression())) { | ||||||
17063 | const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); | ||||||
17064 | Type = | ||||||
17065 | OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); | ||||||
17066 | } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>( | ||||||
17067 | SI->getAssociatedExpression())) { | ||||||
17068 | Type = OASE->getBase()->getType()->getPointeeType(); | ||||||
17069 | } | ||||||
17070 | if (Type.isNull() || Type->isAnyPointerType() || | ||||||
17071 | checkArrayExpressionDoesNotReferToWholeSize( | ||||||
17072 | SemaRef, SI->getAssociatedExpression(), Type)) | ||||||
17073 | break; | ||||||
17074 | } | ||||||
17075 | |||||||
17076 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] | ||||||
17077 | // List items of map clauses in the same construct must not share | ||||||
17078 | // original storage. | ||||||
17079 | // | ||||||
17080 | // If the expressions are exactly the same or one is a subset of the | ||||||
17081 | // other, it means they are sharing storage. | ||||||
17082 | if (CI == CE && SI == SE) { | ||||||
17083 | if (CurrentRegionOnly) { | ||||||
17084 | if (CKind == OMPC_map) { | ||||||
17085 | SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; | ||||||
17086 | } else { | ||||||
17087 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17087, __PRETTY_FUNCTION__)); | ||||||
17088 | SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) | ||||||
17089 | << ERange; | ||||||
17090 | } | ||||||
17091 | SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) | ||||||
17092 | << RE->getSourceRange(); | ||||||
17093 | return true; | ||||||
17094 | } | ||||||
17095 | // If we find the same expression in the enclosing data environment, | ||||||
17096 | // that is legal. | ||||||
17097 | IsEnclosedByDataEnvironmentExpr = true; | ||||||
17098 | return false; | ||||||
17099 | } | ||||||
17100 | |||||||
17101 | QualType DerivedType = | ||||||
17102 | std::prev(CI)->getAssociatedDeclaration()->getType(); | ||||||
17103 | SourceLocation DerivedLoc = | ||||||
17104 | std::prev(CI)->getAssociatedExpression()->getExprLoc(); | ||||||
17105 | |||||||
17106 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] | ||||||
17107 | // If the type of a list item is a reference to a type T then the type | ||||||
17108 | // will be considered to be T for all purposes of this clause. | ||||||
17109 | DerivedType = DerivedType.getNonReferenceType(); | ||||||
17110 | |||||||
17111 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] | ||||||
17112 | // A variable for which the type is pointer and an array section | ||||||
17113 | // derived from that variable must not appear as list items of map | ||||||
17114 | // clauses of the same construct. | ||||||
17115 | // | ||||||
17116 | // Also, cover one of the cases in: | ||||||
17117 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] | ||||||
17118 | // If any part of the original storage of a list item has corresponding | ||||||
17119 | // storage in the device data environment, all of the original storage | ||||||
17120 | // must have corresponding storage in the device data environment. | ||||||
17121 | // | ||||||
17122 | if (DerivedType->isAnyPointerType()) { | ||||||
17123 | if (CI == CE || SI == SE) { | ||||||
17124 | SemaRef.Diag( | ||||||
17125 | DerivedLoc, | ||||||
17126 | diag::err_omp_pointer_mapped_along_with_derived_section) | ||||||
17127 | << DerivedLoc; | ||||||
17128 | SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) | ||||||
17129 | << RE->getSourceRange(); | ||||||
17130 | return true; | ||||||
17131 | } | ||||||
17132 | if (CI->getAssociatedExpression()->getStmtClass() != | ||||||
17133 | SI->getAssociatedExpression()->getStmtClass() || | ||||||
17134 | CI->getAssociatedDeclaration()->getCanonicalDecl() == | ||||||
17135 | SI->getAssociatedDeclaration()->getCanonicalDecl()) { | ||||||
17136 | assert(CI != CE && SI != SE)((CI != CE && SI != SE) ? static_cast<void> (0) : __assert_fail ("CI != CE && SI != SE", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17136, __PRETTY_FUNCTION__)); | ||||||
17137 | SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) | ||||||
17138 | << DerivedLoc; | ||||||
17139 | SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) | ||||||
17140 | << RE->getSourceRange(); | ||||||
17141 | return true; | ||||||
17142 | } | ||||||
17143 | } | ||||||
17144 | |||||||
17145 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] | ||||||
17146 | // List items of map clauses in the same construct must not share | ||||||
17147 | // original storage. | ||||||
17148 | // | ||||||
17149 | // An expression is a subset of the other. | ||||||
17150 | if (CurrentRegionOnly && (CI == CE || SI == SE)) { | ||||||
17151 | if (CKind == OMPC_map) { | ||||||
17152 | if (CI != CE || SI != SE) { | ||||||
17153 | // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is | ||||||
17154 | // a pointer. | ||||||
17155 | auto Begin = | ||||||
17156 | CI != CE ? CurComponents.begin() : StackComponents.begin(); | ||||||
17157 | auto End = CI != CE ? CurComponents.end() : StackComponents.end(); | ||||||
17158 | auto It = Begin; | ||||||
17159 | while (It != End && !It->getAssociatedDeclaration()) | ||||||
17160 | std::advance(It, 1); | ||||||
17161 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17162, __PRETTY_FUNCTION__)) | ||||||
17162 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17162, __PRETTY_FUNCTION__)); | ||||||
17163 | if (It != Begin && It->getAssociatedDeclaration() | ||||||
17164 | ->getType() | ||||||
17165 | .getCanonicalType() | ||||||
17166 | ->isAnyPointerType()) { | ||||||
17167 | IsEnclosedByDataEnvironmentExpr = false; | ||||||
17168 | EnclosingExpr = nullptr; | ||||||
17169 | return false; | ||||||
17170 | } | ||||||
17171 | } | ||||||
17172 | SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; | ||||||
17173 | } else { | ||||||
17174 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17174, __PRETTY_FUNCTION__)); | ||||||
17175 | SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) | ||||||
17176 | << ERange; | ||||||
17177 | } | ||||||
17178 | SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) | ||||||
17179 | << RE->getSourceRange(); | ||||||
17180 | return true; | ||||||
17181 | } | ||||||
17182 | |||||||
17183 | // The current expression uses the same base as other expression in the | ||||||
17184 | // data environment but does not contain it completely. | ||||||
17185 | if (!CurrentRegionOnly && SI != SE) | ||||||
17186 | EnclosingExpr = RE; | ||||||
17187 | |||||||
17188 | // The current expression is a subset of the expression in the data | ||||||
17189 | // environment. | ||||||
17190 | IsEnclosedByDataEnvironmentExpr |= | ||||||
17191 | (!CurrentRegionOnly && CI != CE && SI == SE); | ||||||
17192 | |||||||
17193 | return false; | ||||||
17194 | }); | ||||||
17195 | |||||||
17196 | if (CurrentRegionOnly) | ||||||
17197 | return FoundError; | ||||||
17198 | |||||||
17199 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] | ||||||
17200 | // If any part of the original storage of a list item has corresponding | ||||||
17201 | // storage in the device data environment, all of the original storage must | ||||||
17202 | // have corresponding storage in the device data environment. | ||||||
17203 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] | ||||||
17204 | // If a list item is an element of a structure, and a different element of | ||||||
17205 | // the structure has a corresponding list item in the device data environment | ||||||
17206 | // prior to a task encountering the construct associated with the map clause, | ||||||
17207 | // then the list item must also have a corresponding list item in the device | ||||||
17208 | // data environment prior to the task encountering the construct. | ||||||
17209 | // | ||||||
17210 | if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { | ||||||
17211 | SemaRef.Diag(ELoc, | ||||||
17212 | diag::err_omp_original_storage_is_shared_and_does_not_contain) | ||||||
17213 | << ERange; | ||||||
17214 | SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) | ||||||
17215 | << EnclosingExpr->getSourceRange(); | ||||||
17216 | return true; | ||||||
17217 | } | ||||||
17218 | |||||||
17219 | return FoundError; | ||||||
17220 | } | ||||||
17221 | |||||||
17222 | // Look up the user-defined mapper given the mapper name and mapped type, and | ||||||
17223 | // build a reference to it. | ||||||
17224 | static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, | ||||||
17225 | CXXScopeSpec &MapperIdScopeSpec, | ||||||
17226 | const DeclarationNameInfo &MapperId, | ||||||
17227 | QualType Type, | ||||||
17228 | Expr *UnresolvedMapper) { | ||||||
17229 | if (MapperIdScopeSpec.isInvalid()) | ||||||
17230 | return ExprError(); | ||||||
17231 | // Get the actual type for the array type. | ||||||
17232 | if (Type->isArrayType()) { | ||||||
17233 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17233, __PRETTY_FUNCTION__)); | ||||||
17234 | Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); | ||||||
17235 | } | ||||||
17236 | // Find all user-defined mappers with the given MapperId. | ||||||
17237 | SmallVector<UnresolvedSet<8>, 4> Lookups; | ||||||
17238 | LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); | ||||||
17239 | Lookup.suppressDiagnostics(); | ||||||
17240 | if (S) { | ||||||
17241 | while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { | ||||||
17242 | NamedDecl *D = Lookup.getRepresentativeDecl(); | ||||||
17243 | while (S && !S->isDeclScope(D)) | ||||||
17244 | S = S->getParent(); | ||||||
17245 | if (S) | ||||||
17246 | S = S->getParent(); | ||||||
17247 | Lookups.emplace_back(); | ||||||
17248 | Lookups.back().append(Lookup.begin(), Lookup.end()); | ||||||
17249 | Lookup.clear(); | ||||||
17250 | } | ||||||
17251 | } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { | ||||||
17252 | // Extract the user-defined mappers with the given MapperId. | ||||||
17253 | Lookups.push_back(UnresolvedSet<8>()); | ||||||
17254 | for (NamedDecl *D : ULE->decls()) { | ||||||
17255 | auto *DMD = cast<OMPDeclareMapperDecl>(D); | ||||||
17256 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17256, __PRETTY_FUNCTION__)); | ||||||
17257 | Lookups.back().addDecl(DMD); | ||||||
17258 | } | ||||||
17259 | } | ||||||
17260 | // Defer the lookup for dependent types. The results will be passed through | ||||||
17261 | // UnresolvedMapper on instantiation. | ||||||
17262 | if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || | ||||||
17263 | Type->isInstantiationDependentType() || | ||||||
17264 | Type->containsUnexpandedParameterPack() || | ||||||
17265 | filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { | ||||||
17266 | return !D->isInvalidDecl() && | ||||||
17267 | (D->getType()->isDependentType() || | ||||||
17268 | D->getType()->isInstantiationDependentType() || | ||||||
17269 | D->getType()->containsUnexpandedParameterPack()); | ||||||
17270 | })) { | ||||||
17271 | UnresolvedSet<8> URS; | ||||||
17272 | for (const UnresolvedSet<8> &Set : Lookups) { | ||||||
17273 | if (Set.empty()) | ||||||
17274 | continue; | ||||||
17275 | URS.append(Set.begin(), Set.end()); | ||||||
17276 | } | ||||||
17277 | return UnresolvedLookupExpr::Create( | ||||||
17278 | SemaRef.Context, /*NamingClass=*/nullptr, | ||||||
17279 | MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, | ||||||
17280 | /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); | ||||||
17281 | } | ||||||
17282 | SourceLocation Loc = MapperId.getLoc(); | ||||||
17283 | // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions | ||||||
17284 | // The type must be of struct, union or class type in C and C++ | ||||||
17285 | if (!Type->isStructureOrClassType() && !Type->isUnionType() && | ||||||
17286 | (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { | ||||||
17287 | SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); | ||||||
17288 | return ExprError(); | ||||||
17289 | } | ||||||
17290 | // Perform argument dependent lookup. | ||||||
17291 | if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) | ||||||
17292 | argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); | ||||||
17293 | // Return the first user-defined mapper with the desired type. | ||||||
17294 | if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( | ||||||
17295 | Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { | ||||||
17296 | if (!D->isInvalidDecl() && | ||||||
17297 | SemaRef.Context.hasSameType(D->getType(), Type)) | ||||||
17298 | return D; | ||||||
17299 | return nullptr; | ||||||
17300 | })) | ||||||
17301 | return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); | ||||||
17302 | // Find the first user-defined mapper with a type derived from the desired | ||||||
17303 | // type. | ||||||
17304 | if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( | ||||||
17305 | Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { | ||||||
17306 | if (!D->isInvalidDecl() && | ||||||
17307 | SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && | ||||||
17308 | !Type.isMoreQualifiedThan(D->getType())) | ||||||
17309 | return D; | ||||||
17310 | return nullptr; | ||||||
17311 | })) { | ||||||
17312 | CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, | ||||||
17313 | /*DetectVirtual=*/false); | ||||||
17314 | if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { | ||||||
17315 | if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( | ||||||
17316 | VD->getType().getUnqualifiedType()))) { | ||||||
17317 | if (SemaRef.CheckBaseClassAccess( | ||||||
17318 | Loc, VD->getType(), Type, Paths.front(), | ||||||
17319 | /*DiagID=*/0) != Sema::AR_inaccessible) { | ||||||
17320 | return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); | ||||||
17321 | } | ||||||
17322 | } | ||||||
17323 | } | ||||||
17324 | } | ||||||
17325 | // Report error if a mapper is specified, but cannot be found. | ||||||
17326 | if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { | ||||||
17327 | SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) | ||||||
17328 | << Type << MapperId.getName(); | ||||||
17329 | return ExprError(); | ||||||
17330 | } | ||||||
17331 | return ExprEmpty(); | ||||||
17332 | } | ||||||
17333 | |||||||
17334 | namespace { | ||||||
17335 | // Utility struct that gathers all the related lists associated with a mappable | ||||||
17336 | // expression. | ||||||
17337 | struct MappableVarListInfo { | ||||||
17338 | // The list of expressions. | ||||||
17339 | ArrayRef<Expr *> VarList; | ||||||
17340 | // The list of processed expressions. | ||||||
17341 | SmallVector<Expr *, 16> ProcessedVarList; | ||||||
17342 | // The mappble components for each expression. | ||||||
17343 | OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; | ||||||
17344 | // The base declaration of the variable. | ||||||
17345 | SmallVector<ValueDecl *, 16> VarBaseDeclarations; | ||||||
17346 | // The reference to the user-defined mapper associated with every expression. | ||||||
17347 | SmallVector<Expr *, 16> UDMapperList; | ||||||
17348 | |||||||
17349 | MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { | ||||||
17350 | // We have a list of components and base declarations for each entry in the | ||||||
17351 | // variable list. | ||||||
17352 | VarComponents.reserve(VarList.size()); | ||||||
17353 | VarBaseDeclarations.reserve(VarList.size()); | ||||||
17354 | } | ||||||
17355 | }; | ||||||
17356 | } | ||||||
17357 | |||||||
17358 | // Check the validity of the provided variable list for the provided clause kind | ||||||
17359 | // \a CKind. In the check process the valid expressions, mappable expression | ||||||
17360 | // components, variables, and user-defined mappers are extracted and used to | ||||||
17361 | // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a | ||||||
17362 | // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, | ||||||
17363 | // and \a MapperId are expected to be valid if the clause kind is 'map'. | ||||||
17364 | static void checkMappableExpressionList( | ||||||
17365 | Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, | ||||||
17366 | MappableVarListInfo &MVLI, SourceLocation StartLoc, | ||||||
17367 | CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, | ||||||
17368 | ArrayRef<Expr *> UnresolvedMappers, | ||||||
17369 | OpenMPMapClauseKind MapType = OMPC_MAP_unknown, | ||||||
17370 | bool IsMapTypeImplicit = false) { | ||||||
17371 | // We only expect mappable expressions in 'to', 'from', and 'map' clauses. | ||||||
17372 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17373, __PRETTY_FUNCTION__)) | ||||||
17373 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17373, __PRETTY_FUNCTION__)); | ||||||
17374 | |||||||
17375 | // If the identifier of user-defined mapper is not specified, it is "default". | ||||||
17376 | // We do not change the actual name in this clause to distinguish whether a | ||||||
17377 | // mapper is specified explicitly, i.e., it is not explicitly specified when | ||||||
17378 | // MapperId.getName() is empty. | ||||||
17379 | if (!MapperId.getName() || MapperId.getName().isEmpty()) { | ||||||
17380 | auto &DeclNames = SemaRef.getASTContext().DeclarationNames; | ||||||
17381 | MapperId.setName(DeclNames.getIdentifier( | ||||||
17382 | &SemaRef.getASTContext().Idents.get("default"))); | ||||||
17383 | } | ||||||
17384 | |||||||
17385 | // Iterators to find the current unresolved mapper expression. | ||||||
17386 | auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); | ||||||
17387 | bool UpdateUMIt = false; | ||||||
17388 | Expr *UnresolvedMapper = nullptr; | ||||||
17389 | |||||||
17390 | // Keep track of the mappable components and base declarations in this clause. | ||||||
17391 | // Each entry in the list is going to have a list of components associated. We | ||||||
17392 | // record each set of the components so that we can build the clause later on. | ||||||
17393 | // In the end we should have the same amount of declarations and component | ||||||
17394 | // lists. | ||||||
17395 | |||||||
17396 | for (Expr *RE : MVLI.VarList) { | ||||||
17397 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17397, __PRETTY_FUNCTION__)); | ||||||
17398 | SourceLocation ELoc = RE->getExprLoc(); | ||||||
17399 | |||||||
17400 | // Find the current unresolved mapper expression. | ||||||
17401 | if (UpdateUMIt && UMIt != UMEnd) { | ||||||
17402 | UMIt++; | ||||||
17403 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17405, __PRETTY_FUNCTION__)) | ||||||
17404 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17405, __PRETTY_FUNCTION__)) | ||||||
17405 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17405, __PRETTY_FUNCTION__)); | ||||||
17406 | } | ||||||
17407 | UpdateUMIt = true; | ||||||
17408 | if (UMIt != UMEnd) | ||||||
17409 | UnresolvedMapper = *UMIt; | ||||||
17410 | |||||||
17411 | const Expr *VE = RE->IgnoreParenLValueCasts(); | ||||||
17412 | |||||||
17413 | if (VE->isValueDependent() || VE->isTypeDependent() || | ||||||
17414 | VE->isInstantiationDependent() || | ||||||
17415 | VE->containsUnexpandedParameterPack()) { | ||||||
17416 | // Try to find the associated user-defined mapper. | ||||||
17417 | ExprResult ER = buildUserDefinedMapperRef( | ||||||
17418 | SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, | ||||||
17419 | VE->getType().getCanonicalType(), UnresolvedMapper); | ||||||
17420 | if (ER.isInvalid()) | ||||||
17421 | continue; | ||||||
17422 | MVLI.UDMapperList.push_back(ER.get()); | ||||||
17423 | // We can only analyze this information once the missing information is | ||||||
17424 | // resolved. | ||||||
17425 | MVLI.ProcessedVarList.push_back(RE); | ||||||
17426 | continue; | ||||||
17427 | } | ||||||
17428 | |||||||
17429 | Expr *SimpleExpr = RE->IgnoreParenCasts(); | ||||||
17430 | |||||||
17431 | if (!RE->isLValue()) { | ||||||
17432 | if (SemaRef.getLangOpts().OpenMP < 50) { | ||||||
17433 | SemaRef.Diag( | ||||||
17434 | ELoc, diag::err_omp_expected_named_var_member_or_array_expression) | ||||||
17435 | << RE->getSourceRange(); | ||||||
17436 | } else { | ||||||
17437 | SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) | ||||||
17438 | << getOpenMPClauseName(CKind) << RE->getSourceRange(); | ||||||
17439 | } | ||||||
17440 | continue; | ||||||
17441 | } | ||||||
17442 | |||||||
17443 | OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; | ||||||
17444 | ValueDecl *CurDeclaration = nullptr; | ||||||
17445 | |||||||
17446 | // Obtain the array or member expression bases if required. Also, fill the | ||||||
17447 | // components array with all the components identified in the process. | ||||||
17448 | const Expr *BE = checkMapClauseExpressionBase( | ||||||
17449 | SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); | ||||||
17450 | if (!BE) | ||||||
17451 | continue; | ||||||
17452 | |||||||
17453 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17454, __PRETTY_FUNCTION__)) | ||||||
17454 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17454, __PRETTY_FUNCTION__)); | ||||||
17455 | |||||||
17456 | if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { | ||||||
17457 | // Add store "this" pointer to class in DSAStackTy for future checking | ||||||
17458 | DSAS->addMappedClassesQualTypes(TE->getType()); | ||||||
17459 | // Try to find the associated user-defined mapper. | ||||||
17460 | ExprResult ER = buildUserDefinedMapperRef( | ||||||
17461 | SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, | ||||||
17462 | VE->getType().getCanonicalType(), UnresolvedMapper); | ||||||
17463 | if (ER.isInvalid()) | ||||||
17464 | continue; | ||||||
17465 | MVLI.UDMapperList.push_back(ER.get()); | ||||||
17466 | // Skip restriction checking for variable or field declarations | ||||||
17467 | MVLI.ProcessedVarList.push_back(RE); | ||||||
17468 | MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); | ||||||
17469 | MVLI.VarComponents.back().append(CurComponents.begin(), | ||||||
17470 | CurComponents.end()); | ||||||
17471 | MVLI.VarBaseDeclarations.push_back(nullptr); | ||||||
17472 | continue; | ||||||
17473 | } | ||||||
17474 | |||||||
17475 | // For the following checks, we rely on the base declaration which is | ||||||
17476 | // expected to be associated with the last component. The declaration is | ||||||
17477 | // expected to be a variable or a field (if 'this' is being mapped). | ||||||
17478 | CurDeclaration = CurComponents.back().getAssociatedDeclaration(); | ||||||
17479 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17479, __PRETTY_FUNCTION__)); | ||||||
17480 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17482, __PRETTY_FUNCTION__)) | ||||||
17481 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17482, __PRETTY_FUNCTION__)) | ||||||
17482 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17482, __PRETTY_FUNCTION__)); | ||||||
17483 | |||||||
17484 | auto *VD = dyn_cast<VarDecl>(CurDeclaration); | ||||||
17485 | const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); | ||||||
17486 | |||||||
17487 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17487, __PRETTY_FUNCTION__)); | ||||||
17488 | (void)FD; | ||||||
17489 | |||||||
17490 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] | ||||||
17491 | // threadprivate variables cannot appear in a map clause. | ||||||
17492 | // OpenMP 4.5 [2.10.5, target update Construct] | ||||||
17493 | // threadprivate variables cannot appear in a from clause. | ||||||
17494 | if (VD && DSAS->isThreadPrivate(VD)) { | ||||||
17495 | DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); | ||||||
17496 | SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) | ||||||
17497 | << getOpenMPClauseName(CKind); | ||||||
17498 | reportOriginalDsa(SemaRef, DSAS, VD, DVar); | ||||||
17499 | continue; | ||||||
17500 | } | ||||||
17501 | |||||||
17502 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] | ||||||
17503 | // A list item cannot appear in both a map clause and a data-sharing | ||||||
17504 | // attribute clause on the same construct. | ||||||
17505 | |||||||
17506 | // Check conflicts with other map clause expressions. We check the conflicts | ||||||
17507 | // with the current construct separately from the enclosing data | ||||||
17508 | // environment, because the restrictions are different. We only have to | ||||||
17509 | // check conflicts across regions for the map clauses. | ||||||
17510 | if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, | ||||||
17511 | /*CurrentRegionOnly=*/true, CurComponents, CKind)) | ||||||
17512 | break; | ||||||
17513 | if (CKind == OMPC_map && | ||||||
17514 | (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) && | ||||||
17515 | checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, | ||||||
17516 | /*CurrentRegionOnly=*/false, CurComponents, CKind)) | ||||||
17517 | break; | ||||||
17518 | |||||||
17519 | // OpenMP 4.5 [2.10.5, target update Construct] | ||||||
17520 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] | ||||||
17521 | // If the type of a list item is a reference to a type T then the type will | ||||||
17522 | // be considered to be T for all purposes of this clause. | ||||||
17523 | auto I = llvm::find_if( | ||||||
17524 | CurComponents, | ||||||
17525 | [](const OMPClauseMappableExprCommon::MappableComponent &MC) { | ||||||
17526 | return MC.getAssociatedDeclaration(); | ||||||
17527 | }); | ||||||
17528 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17528, __PRETTY_FUNCTION__)); | ||||||
17529 | QualType Type; | ||||||
17530 | auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); | ||||||
17531 | auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); | ||||||
17532 | auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens()); | ||||||
17533 | if (ASE) { | ||||||
17534 | Type = ASE->getType().getNonReferenceType(); | ||||||
17535 | } else if (OASE) { | ||||||
17536 | QualType BaseType = | ||||||
17537 | OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); | ||||||
17538 | if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) | ||||||
17539 | Type = ATy->getElementType(); | ||||||
17540 | else | ||||||
17541 | Type = BaseType->getPointeeType(); | ||||||
17542 | Type = Type.getNonReferenceType(); | ||||||
17543 | } else if (OAShE) { | ||||||
17544 | Type = OAShE->getBase()->getType()->getPointeeType(); | ||||||
17545 | } else { | ||||||
17546 | Type = VE->getType(); | ||||||
17547 | } | ||||||
17548 | |||||||
17549 | // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] | ||||||
17550 | // A list item in a to or from clause must have a mappable type. | ||||||
17551 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] | ||||||
17552 | // A list item must have a mappable type. | ||||||
17553 | if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, | ||||||
17554 | DSAS, Type)) | ||||||
17555 | continue; | ||||||
17556 | |||||||
17557 | Type = I->getAssociatedDeclaration()->getType().getNonReferenceType(); | ||||||
17558 | |||||||
17559 | if (CKind == OMPC_map) { | ||||||
17560 | // target enter data | ||||||
17561 | // OpenMP [2.10.2, Restrictions, p. 99] | ||||||
17562 | // A map-type must be specified in all map clauses and must be either | ||||||
17563 | // to or alloc. | ||||||
17564 | OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); | ||||||
17565 | if (DKind == OMPD_target_enter_data && | ||||||
17566 | !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { | ||||||
17567 | SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) | ||||||
17568 | << (IsMapTypeImplicit ? 1 : 0) | ||||||
17569 | << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) | ||||||
17570 | << getOpenMPDirectiveName(DKind); | ||||||
17571 | continue; | ||||||
17572 | } | ||||||
17573 | |||||||
17574 | // target exit_data | ||||||
17575 | // OpenMP [2.10.3, Restrictions, p. 102] | ||||||
17576 | // A map-type must be specified in all map clauses and must be either | ||||||
17577 | // from, release, or delete. | ||||||
17578 | if (DKind == OMPD_target_exit_data && | ||||||
17579 | !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || | ||||||
17580 | MapType == OMPC_MAP_delete)) { | ||||||
17581 | SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) | ||||||
17582 | << (IsMapTypeImplicit ? 1 : 0) | ||||||
17583 | << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) | ||||||
17584 | << getOpenMPDirectiveName(DKind); | ||||||
17585 | continue; | ||||||
17586 | } | ||||||
17587 | |||||||
17588 | // target, target data | ||||||
17589 | // OpenMP 5.0 [2.12.2, Restrictions, p. 163] | ||||||
17590 | // OpenMP 5.0 [2.12.5, Restrictions, p. 174] | ||||||
17591 | // A map-type in a map clause must be to, from, tofrom or alloc | ||||||
17592 | if ((DKind == OMPD_target_data || | ||||||
17593 | isOpenMPTargetExecutionDirective(DKind)) && | ||||||
17594 | !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from || | ||||||
17595 | MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) { | ||||||
17596 | SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) | ||||||
17597 | << (IsMapTypeImplicit ? 1 : 0) | ||||||
17598 | << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) | ||||||
17599 | << getOpenMPDirectiveName(DKind); | ||||||
17600 | continue; | ||||||
17601 | } | ||||||
17602 | |||||||
17603 | // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] | ||||||
17604 | // A list item cannot appear in both a map clause and a data-sharing | ||||||
17605 | // attribute clause on the same construct | ||||||
17606 | // | ||||||
17607 | // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] | ||||||
17608 | // A list item cannot appear in both a map clause and a data-sharing | ||||||
17609 | // attribute clause on the same construct unless the construct is a | ||||||
17610 | // combined construct. | ||||||
17611 | if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && | ||||||
17612 | isOpenMPTargetExecutionDirective(DKind)) || | ||||||
17613 | DKind == OMPD_target)) { | ||||||
17614 | DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); | ||||||
17615 | if (isOpenMPPrivate(DVar.CKind)) { | ||||||
17616 | SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) | ||||||
17617 | << getOpenMPClauseName(DVar.CKind) | ||||||
17618 | << getOpenMPClauseName(OMPC_map) | ||||||
17619 | << getOpenMPDirectiveName(DSAS->getCurrentDirective()); | ||||||
17620 | reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); | ||||||
17621 | continue; | ||||||
17622 | } | ||||||
17623 | } | ||||||
17624 | } | ||||||
17625 | |||||||
17626 | // Try to find the associated user-defined mapper. | ||||||
17627 | ExprResult ER = buildUserDefinedMapperRef( | ||||||
17628 | SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, | ||||||
17629 | Type.getCanonicalType(), UnresolvedMapper); | ||||||
17630 | if (ER.isInvalid()) | ||||||
17631 | continue; | ||||||
17632 | MVLI.UDMapperList.push_back(ER.get()); | ||||||
17633 | |||||||
17634 | // Save the current expression. | ||||||
17635 | MVLI.ProcessedVarList.push_back(RE); | ||||||
17636 | |||||||
17637 | // Store the components in the stack so that they can be used to check | ||||||
17638 | // against other clauses later on. | ||||||
17639 | DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, | ||||||
17640 | /*WhereFoundClauseKind=*/OMPC_map); | ||||||
17641 | |||||||
17642 | // Save the components and declaration to create the clause. For purposes of | ||||||
17643 | // the clause creation, any component list that has has base 'this' uses | ||||||
17644 | // null as base declaration. | ||||||
17645 | MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); | ||||||
17646 | MVLI.VarComponents.back().append(CurComponents.begin(), | ||||||
17647 | CurComponents.end()); | ||||||
17648 | MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr | ||||||
17649 | : CurDeclaration); | ||||||
17650 | } | ||||||
17651 | } | ||||||
17652 | |||||||
17653 | OMPClause *Sema::ActOnOpenMPMapClause( | ||||||
17654 | ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, | ||||||
17655 | ArrayRef<SourceLocation> MapTypeModifiersLoc, | ||||||
17656 | CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, | ||||||
17657 | OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, | ||||||
17658 | SourceLocation ColonLoc, ArrayRef<Expr *> VarList, | ||||||
17659 | const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { | ||||||
17660 | OpenMPMapModifierKind Modifiers[] = { | ||||||
17661 | OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, | ||||||
17662 | OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown}; | ||||||
17663 | SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers]; | ||||||
17664 | |||||||
17665 | // Process map-type-modifiers, flag errors for duplicate modifiers. | ||||||
17666 | unsigned Count = 0; | ||||||
17667 | for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { | ||||||
17668 | if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && | ||||||
17669 | llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { | ||||||
17670 | Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); | ||||||
17671 | continue; | ||||||
17672 | } | ||||||
17673 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17674, __PRETTY_FUNCTION__)) | ||||||
17674 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17674, __PRETTY_FUNCTION__)); | ||||||
17675 | Modifiers[Count] = MapTypeModifiers[I]; | ||||||
17676 | ModifiersLoc[Count] = MapTypeModifiersLoc[I]; | ||||||
17677 | ++Count; | ||||||
17678 | } | ||||||
17679 | |||||||
17680 | MappableVarListInfo MVLI(VarList); | ||||||
17681 | checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), OMPC_map, MVLI, Locs.StartLoc, | ||||||
17682 | MapperIdScopeSpec, MapperId, UnresolvedMappers, | ||||||
17683 | MapType, IsMapTypeImplicit); | ||||||
17684 | |||||||
17685 | // We need to produce a map clause even if we don't have variables so that | ||||||
17686 | // other diagnostics related with non-existing map clauses are accurate. | ||||||
17687 | return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, | ||||||
17688 | MVLI.VarBaseDeclarations, MVLI.VarComponents, | ||||||
17689 | MVLI.UDMapperList, Modifiers, ModifiersLoc, | ||||||
17690 | MapperIdScopeSpec.getWithLocInContext(Context), | ||||||
17691 | MapperId, MapType, IsMapTypeImplicit, MapLoc); | ||||||
17692 | } | ||||||
17693 | |||||||
17694 | QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, | ||||||
17695 | TypeResult ParsedType) { | ||||||
17696 | assert(ParsedType.isUsable())((ParsedType.isUsable()) ? static_cast<void> (0) : __assert_fail ("ParsedType.isUsable()", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17696, __PRETTY_FUNCTION__)); | ||||||
17697 | |||||||
17698 | QualType ReductionType = GetTypeFromParser(ParsedType.get()); | ||||||
17699 | if (ReductionType.isNull()) | ||||||
17700 | return QualType(); | ||||||
17701 | |||||||
17702 | // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ | ||||||
17703 | // A type name in a declare reduction directive cannot be a function type, an | ||||||
17704 | // array type, a reference type, or a type qualified with const, volatile or | ||||||
17705 | // restrict. | ||||||
17706 | if (ReductionType.hasQualifiers()) { | ||||||
17707 | Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; | ||||||
17708 | return QualType(); | ||||||
17709 | } | ||||||
17710 | |||||||
17711 | if (ReductionType->isFunctionType()) { | ||||||
17712 | Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; | ||||||
17713 | return QualType(); | ||||||
17714 | } | ||||||
17715 | if (ReductionType->isReferenceType()) { | ||||||
17716 | Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; | ||||||
17717 | return QualType(); | ||||||
17718 | } | ||||||
17719 | if (ReductionType->isArrayType()) { | ||||||
17720 | Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; | ||||||
17721 | return QualType(); | ||||||
17722 | } | ||||||
17723 | return ReductionType; | ||||||
17724 | } | ||||||
17725 | |||||||
17726 | Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( | ||||||
17727 | Scope *S, DeclContext *DC, DeclarationName Name, | ||||||
17728 | ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, | ||||||
17729 | AccessSpecifier AS, Decl *PrevDeclInScope) { | ||||||
17730 | SmallVector<Decl *, 8> Decls; | ||||||
17731 | Decls.reserve(ReductionTypes.size()); | ||||||
17732 | |||||||
17733 | LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, | ||||||
17734 | forRedeclarationInCurContext()); | ||||||
17735 | // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions | ||||||
17736 | // A reduction-identifier may not be re-declared in the current scope for the | ||||||
17737 | // same type or for a type that is compatible according to the base language | ||||||
17738 | // rules. | ||||||
17739 | llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; | ||||||
17740 | OMPDeclareReductionDecl *PrevDRD = nullptr; | ||||||
17741 | bool InCompoundScope = true; | ||||||
17742 | if (S != nullptr) { | ||||||
17743 | // Find previous declaration with the same name not referenced in other | ||||||
17744 | // declarations. | ||||||
17745 | FunctionScopeInfo *ParentFn = getEnclosingFunction(); | ||||||
17746 | InCompoundScope = | ||||||
17747 | (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); | ||||||
17748 | LookupName(Lookup, S); | ||||||
17749 | FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, | ||||||
17750 | /*AllowInlineNamespace=*/false); | ||||||
17751 | llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; | ||||||
17752 | LookupResult::Filter Filter = Lookup.makeFilter(); | ||||||
17753 | while (Filter.hasNext()) { | ||||||
17754 | auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); | ||||||
17755 | if (InCompoundScope) { | ||||||
17756 | auto I = UsedAsPrevious.find(PrevDecl); | ||||||
17757 | if (I == UsedAsPrevious.end()) | ||||||
17758 | UsedAsPrevious[PrevDecl] = false; | ||||||
17759 | if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) | ||||||
17760 | UsedAsPrevious[D] = true; | ||||||
17761 | } | ||||||
17762 | PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = | ||||||
17763 | PrevDecl->getLocation(); | ||||||
17764 | } | ||||||
17765 | Filter.done(); | ||||||
17766 | if (InCompoundScope) { | ||||||
17767 | for (const auto &PrevData : UsedAsPrevious) { | ||||||
17768 | if (!PrevData.second) { | ||||||
17769 | PrevDRD = PrevData.first; | ||||||
17770 | break; | ||||||
17771 | } | ||||||
17772 | } | ||||||
17773 | } | ||||||
17774 | } else if (PrevDeclInScope != nullptr) { | ||||||
17775 | auto *PrevDRDInScope = PrevDRD = | ||||||
17776 | cast<OMPDeclareReductionDecl>(PrevDeclInScope); | ||||||
17777 | do { | ||||||
17778 | PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = | ||||||
17779 | PrevDRDInScope->getLocation(); | ||||||
17780 | PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); | ||||||
17781 | } while (PrevDRDInScope != nullptr); | ||||||
17782 | } | ||||||
17783 | for (const auto &TyData : ReductionTypes) { | ||||||
17784 | const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); | ||||||
17785 | bool Invalid = false; | ||||||
17786 | if (I != PreviousRedeclTypes.end()) { | ||||||
17787 | Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) | ||||||
17788 | << TyData.first; | ||||||
17789 | Diag(I->second, diag::note_previous_definition); | ||||||
17790 | Invalid = true; | ||||||
17791 | } | ||||||
17792 | PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; | ||||||
17793 | auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, | ||||||
17794 | Name, TyData.first, PrevDRD); | ||||||
17795 | DC->addDecl(DRD); | ||||||
17796 | DRD->setAccess(AS); | ||||||
17797 | Decls.push_back(DRD); | ||||||
17798 | if (Invalid) | ||||||
17799 | DRD->setInvalidDecl(); | ||||||
17800 | else | ||||||
17801 | PrevDRD = DRD; | ||||||
17802 | } | ||||||
17803 | |||||||
17804 | return DeclGroupPtrTy::make( | ||||||
17805 | DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); | ||||||
17806 | } | ||||||
17807 | |||||||
17808 | void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { | ||||||
17809 | auto *DRD = cast<OMPDeclareReductionDecl>(D); | ||||||
17810 | |||||||
17811 | // Enter new function scope. | ||||||
17812 | PushFunctionScope(); | ||||||
17813 | setFunctionHasBranchProtectedScope(); | ||||||
17814 | getCurFunction()->setHasOMPDeclareReductionCombiner(); | ||||||
17815 | |||||||
17816 | if (S != nullptr) | ||||||
17817 | PushDeclContext(S, DRD); | ||||||
17818 | else | ||||||
17819 | CurContext = DRD; | ||||||
17820 | |||||||
17821 | PushExpressionEvaluationContext( | ||||||
17822 | ExpressionEvaluationContext::PotentiallyEvaluated); | ||||||
17823 | |||||||
17824 | QualType ReductionType = DRD->getType(); | ||||||
17825 | // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will | ||||||
17826 | // be replaced by '*omp_parm' during codegen. This required because 'omp_in' | ||||||
17827 | // uses semantics of argument handles by value, but it should be passed by | ||||||
17828 | // reference. C lang does not support references, so pass all parameters as | ||||||
17829 | // pointers. | ||||||
17830 | // Create 'T omp_in;' variable. | ||||||
17831 | VarDecl *OmpInParm = | ||||||
17832 | buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); | ||||||
17833 | // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will | ||||||
17834 | // be replaced by '*omp_parm' during codegen. This required because 'omp_out' | ||||||
17835 | // uses semantics of argument handles by value, but it should be passed by | ||||||
17836 | // reference. C lang does not support references, so pass all parameters as | ||||||
17837 | // pointers. | ||||||
17838 | // Create 'T omp_out;' variable. | ||||||
17839 | VarDecl *OmpOutParm = | ||||||
17840 | buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); | ||||||
17841 | if (S != nullptr) { | ||||||
17842 | PushOnScopeChains(OmpInParm, S); | ||||||
17843 | PushOnScopeChains(OmpOutParm, S); | ||||||
17844 | } else { | ||||||
17845 | DRD->addDecl(OmpInParm); | ||||||
17846 | DRD->addDecl(OmpOutParm); | ||||||
17847 | } | ||||||
17848 | Expr *InE = | ||||||
17849 | ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); | ||||||
17850 | Expr *OutE = | ||||||
17851 | ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); | ||||||
17852 | DRD->setCombinerData(InE, OutE); | ||||||
17853 | } | ||||||
17854 | |||||||
17855 | void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { | ||||||
17856 | auto *DRD = cast<OMPDeclareReductionDecl>(D); | ||||||
17857 | DiscardCleanupsInEvaluationContext(); | ||||||
17858 | PopExpressionEvaluationContext(); | ||||||
17859 | |||||||
17860 | PopDeclContext(); | ||||||
17861 | PopFunctionScopeInfo(); | ||||||
17862 | |||||||
17863 | if (Combiner != nullptr) | ||||||
17864 | DRD->setCombiner(Combiner); | ||||||
17865 | else | ||||||
17866 | DRD->setInvalidDecl(); | ||||||
17867 | } | ||||||
17868 | |||||||
17869 | VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { | ||||||
17870 | auto *DRD = cast<OMPDeclareReductionDecl>(D); | ||||||
17871 | |||||||
17872 | // Enter new function scope. | ||||||
17873 | PushFunctionScope(); | ||||||
17874 | setFunctionHasBranchProtectedScope(); | ||||||
17875 | |||||||
17876 | if (S != nullptr) | ||||||
17877 | PushDeclContext(S, DRD); | ||||||
17878 | else | ||||||
17879 | CurContext = DRD; | ||||||
17880 | |||||||
17881 | PushExpressionEvaluationContext( | ||||||
17882 | ExpressionEvaluationContext::PotentiallyEvaluated); | ||||||
17883 | |||||||
17884 | QualType ReductionType = DRD->getType(); | ||||||
17885 | // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will | ||||||
17886 | // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' | ||||||
17887 | // uses semantics of argument handles by value, but it should be passed by | ||||||
17888 | // reference. C lang does not support references, so pass all parameters as | ||||||
17889 | // pointers. | ||||||
17890 | // Create 'T omp_priv;' variable. | ||||||
17891 | VarDecl *OmpPrivParm = | ||||||
17892 | buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); | ||||||
17893 | // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will | ||||||
17894 | // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' | ||||||
17895 | // uses semantics of argument handles by value, but it should be passed by | ||||||
17896 | // reference. C lang does not support references, so pass all parameters as | ||||||
17897 | // pointers. | ||||||
17898 | // Create 'T omp_orig;' variable. | ||||||
17899 | VarDecl *OmpOrigParm = | ||||||
17900 | buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); | ||||||
17901 | if (S != nullptr) { | ||||||
17902 | PushOnScopeChains(OmpPrivParm, S); | ||||||
17903 | PushOnScopeChains(OmpOrigParm, S); | ||||||
17904 | } else { | ||||||
17905 | DRD->addDecl(OmpPrivParm); | ||||||
17906 | DRD->addDecl(OmpOrigParm); | ||||||
17907 | } | ||||||
17908 | Expr *OrigE = | ||||||
17909 | ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); | ||||||
17910 | Expr *PrivE = | ||||||
17911 | ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); | ||||||
17912 | DRD->setInitializerData(OrigE, PrivE); | ||||||
17913 | return OmpPrivParm; | ||||||
17914 | } | ||||||
17915 | |||||||
17916 | void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, | ||||||
17917 | VarDecl *OmpPrivParm) { | ||||||
17918 | auto *DRD = cast<OMPDeclareReductionDecl>(D); | ||||||
17919 | DiscardCleanupsInEvaluationContext(); | ||||||
17920 | PopExpressionEvaluationContext(); | ||||||
17921 | |||||||
17922 | PopDeclContext(); | ||||||
17923 | PopFunctionScopeInfo(); | ||||||
17924 | |||||||
17925 | if (Initializer != nullptr) { | ||||||
17926 | DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); | ||||||
17927 | } else if (OmpPrivParm->hasInit()) { | ||||||
17928 | DRD->setInitializer(OmpPrivParm->getInit(), | ||||||
17929 | OmpPrivParm->isDirectInit() | ||||||
17930 | ? OMPDeclareReductionDecl::DirectInit | ||||||
17931 | : OMPDeclareReductionDecl::CopyInit); | ||||||
17932 | } else { | ||||||
17933 | DRD->setInvalidDecl(); | ||||||
17934 | } | ||||||
17935 | } | ||||||
17936 | |||||||
17937 | Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( | ||||||
17938 | Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { | ||||||
17939 | for (Decl *D : DeclReductions.get()) { | ||||||
17940 | if (IsValid) { | ||||||
17941 | if (S) | ||||||
17942 | PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, | ||||||
17943 | /*AddToContext=*/false); | ||||||
17944 | } else { | ||||||
17945 | D->setInvalidDecl(); | ||||||
17946 | } | ||||||
17947 | } | ||||||
17948 | return DeclReductions; | ||||||
17949 | } | ||||||
17950 | |||||||
17951 | TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { | ||||||
17952 | TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); | ||||||
17953 | QualType T = TInfo->getType(); | ||||||
17954 | if (D.isInvalidType()) | ||||||
17955 | return true; | ||||||
17956 | |||||||
17957 | if (getLangOpts().CPlusPlus) { | ||||||
17958 | // Check that there are no default arguments (C++ only). | ||||||
17959 | CheckExtraCXXDefaultArguments(D); | ||||||
17960 | } | ||||||
17961 | |||||||
17962 | return CreateParsedType(T, TInfo); | ||||||
17963 | } | ||||||
17964 | |||||||
17965 | QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, | ||||||
17966 | TypeResult ParsedType) { | ||||||
17967 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17967, __PRETTY_FUNCTION__)); | ||||||
17968 | |||||||
17969 | QualType MapperType = GetTypeFromParser(ParsedType.get()); | ||||||
17970 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17970, __PRETTY_FUNCTION__)); | ||||||
17971 | |||||||
17972 | // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions | ||||||
17973 | // The type must be of struct, union or class type in C and C++ | ||||||
17974 | if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { | ||||||
17975 | Diag(TyLoc, diag::err_omp_mapper_wrong_type); | ||||||
17976 | return QualType(); | ||||||
17977 | } | ||||||
17978 | return MapperType; | ||||||
17979 | } | ||||||
17980 | |||||||
17981 | OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( | ||||||
17982 | Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, | ||||||
17983 | SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, | ||||||
17984 | Decl *PrevDeclInScope) { | ||||||
17985 | LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, | ||||||
17986 | forRedeclarationInCurContext()); | ||||||
17987 | // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions | ||||||
17988 | // A mapper-identifier may not be redeclared in the current scope for the | ||||||
17989 | // same type or for a type that is compatible according to the base language | ||||||
17990 | // rules. | ||||||
17991 | llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; | ||||||
17992 | OMPDeclareMapperDecl *PrevDMD = nullptr; | ||||||
17993 | bool InCompoundScope = true; | ||||||
17994 | if (S != nullptr) { | ||||||
17995 | // Find previous declaration with the same name not referenced in other | ||||||
17996 | // declarations. | ||||||
17997 | FunctionScopeInfo *ParentFn = getEnclosingFunction(); | ||||||
17998 | InCompoundScope = | ||||||
17999 | (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); | ||||||
18000 | LookupName(Lookup, S); | ||||||
18001 | FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, | ||||||
18002 | /*AllowInlineNamespace=*/false); | ||||||
18003 | llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; | ||||||
18004 | LookupResult::Filter Filter = Lookup.makeFilter(); | ||||||
18005 | while (Filter.hasNext()) { | ||||||
18006 | auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); | ||||||
18007 | if (InCompoundScope) { | ||||||
18008 | auto I = UsedAsPrevious.find(PrevDecl); | ||||||
18009 | if (I == UsedAsPrevious.end()) | ||||||
18010 | UsedAsPrevious[PrevDecl] = false; | ||||||
18011 | if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) | ||||||
18012 | UsedAsPrevious[D] = true; | ||||||
18013 | } | ||||||
18014 | PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = | ||||||
18015 | PrevDecl->getLocation(); | ||||||
18016 | } | ||||||
18017 | Filter.done(); | ||||||
18018 | if (InCompoundScope) { | ||||||
18019 | for (const auto &PrevData : UsedAsPrevious) { | ||||||
18020 | if (!PrevData.second) { | ||||||
18021 | PrevDMD = PrevData.first; | ||||||
18022 | break; | ||||||
18023 | } | ||||||
18024 | } | ||||||
18025 | } | ||||||
18026 | } else if (PrevDeclInScope) { | ||||||
18027 | auto *PrevDMDInScope = PrevDMD = | ||||||
18028 | cast<OMPDeclareMapperDecl>(PrevDeclInScope); | ||||||
18029 | do { | ||||||
18030 | PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = | ||||||
18031 | PrevDMDInScope->getLocation(); | ||||||
18032 | PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); | ||||||
18033 | } while (PrevDMDInScope != nullptr); | ||||||
18034 | } | ||||||
18035 | const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); | ||||||
18036 | bool Invalid = false; | ||||||
18037 | if (I != PreviousRedeclTypes.end()) { | ||||||
18038 | Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) | ||||||
18039 | << MapperType << Name; | ||||||
18040 | Diag(I->second, diag::note_previous_definition); | ||||||
18041 | Invalid = true; | ||||||
18042 | } | ||||||
18043 | auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, | ||||||
18044 | MapperType, VN, PrevDMD); | ||||||
18045 | DC->addDecl(DMD); | ||||||
18046 | DMD->setAccess(AS); | ||||||
18047 | if (Invalid) | ||||||
18048 | DMD->setInvalidDecl(); | ||||||
18049 | |||||||
18050 | // Enter new function scope. | ||||||
18051 | PushFunctionScope(); | ||||||
18052 | setFunctionHasBranchProtectedScope(); | ||||||
18053 | |||||||
18054 | CurContext = DMD; | ||||||
18055 | |||||||
18056 | return DMD; | ||||||
18057 | } | ||||||
18058 | |||||||
18059 | void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, | ||||||
18060 | Scope *S, | ||||||
18061 | QualType MapperType, | ||||||
18062 | SourceLocation StartLoc, | ||||||
18063 | DeclarationName VN) { | ||||||
18064 | VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); | ||||||
18065 | if (S) | ||||||
18066 | PushOnScopeChains(VD, S); | ||||||
18067 | else | ||||||
18068 | DMD->addDecl(VD); | ||||||
18069 | Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); | ||||||
18070 | DMD->setMapperVarRef(MapperVarRefExpr); | ||||||
18071 | } | ||||||
18072 | |||||||
18073 | Sema::DeclGroupPtrTy | ||||||
18074 | Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, | ||||||
18075 | ArrayRef<OMPClause *> ClauseList) { | ||||||
18076 | PopDeclContext(); | ||||||
18077 | PopFunctionScopeInfo(); | ||||||
18078 | |||||||
18079 | if (D) { | ||||||
18080 | if (S) | ||||||
18081 | PushOnScopeChains(D, S, /*AddToContext=*/false); | ||||||
18082 | D->CreateClauses(Context, ClauseList); | ||||||
18083 | } | ||||||
18084 | |||||||
18085 | return DeclGroupPtrTy::make(DeclGroupRef(D)); | ||||||
18086 | } | ||||||
18087 | |||||||
18088 | OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, | ||||||
18089 | SourceLocation StartLoc, | ||||||
18090 | SourceLocation LParenLoc, | ||||||
18091 | SourceLocation EndLoc) { | ||||||
18092 | Expr *ValExpr = NumTeams; | ||||||
18093 | Stmt *HelperValStmt = nullptr; | ||||||
18094 | |||||||
18095 | // OpenMP [teams Constrcut, Restrictions] | ||||||
18096 | // The num_teams expression must evaluate to a positive integer value. | ||||||
18097 | if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, | ||||||
18098 | /*StrictlyPositive=*/true)) | ||||||
18099 | return nullptr; | ||||||
18100 | |||||||
18101 | OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); | ||||||
18102 | OpenMPDirectiveKind CaptureRegion = | ||||||
18103 | getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); | ||||||
18104 | if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { | ||||||
18105 | ValExpr = MakeFullExpr(ValExpr).get(); | ||||||
18106 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; | ||||||
18107 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); | ||||||
18108 | HelperValStmt = buildPreInits(Context, Captures); | ||||||
18109 | } | ||||||
18110 | |||||||
18111 | return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, | ||||||
18112 | StartLoc, LParenLoc, EndLoc); | ||||||
18113 | } | ||||||
18114 | |||||||
18115 | OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, | ||||||
18116 | SourceLocation StartLoc, | ||||||
18117 | SourceLocation LParenLoc, | ||||||
18118 | SourceLocation EndLoc) { | ||||||
18119 | Expr *ValExpr = ThreadLimit; | ||||||
18120 | Stmt *HelperValStmt = nullptr; | ||||||
18121 | |||||||
18122 | // OpenMP [teams Constrcut, Restrictions] | ||||||
18123 | // The thread_limit expression must evaluate to a positive integer value. | ||||||
18124 | if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, | ||||||
18125 | /*StrictlyPositive=*/true)) | ||||||
18126 | return nullptr; | ||||||
18127 | |||||||
18128 | OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); | ||||||
18129 | OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( | ||||||
18130 | DKind, OMPC_thread_limit, LangOpts.OpenMP); | ||||||
18131 | if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { | ||||||
18132 | ValExpr = MakeFullExpr(ValExpr).get(); | ||||||
18133 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; | ||||||
18134 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); | ||||||
18135 | HelperValStmt = buildPreInits(Context, Captures); | ||||||
18136 | } | ||||||
18137 | |||||||
18138 | return new (Context) OMPThreadLimitClause( | ||||||
18139 | ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); | ||||||
18140 | } | ||||||
18141 | |||||||
18142 | OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, | ||||||
18143 | SourceLocation StartLoc, | ||||||
18144 | SourceLocation LParenLoc, | ||||||
18145 | SourceLocation EndLoc) { | ||||||
18146 | Expr *ValExpr = Priority; | ||||||
18147 | Stmt *HelperValStmt = nullptr; | ||||||
18148 | OpenMPDirectiveKind CaptureRegion = OMPD_unknown; | ||||||
18149 | |||||||
18150 | // OpenMP [2.9.1, task Constrcut] | ||||||
18151 | // The priority-value is a non-negative numerical scalar expression. | ||||||
18152 | if (!isNonNegativeIntegerValue( | ||||||
18153 | ValExpr, *this, OMPC_priority, | ||||||
18154 | /*StrictlyPositive=*/false, /*BuildCapture=*/true, | ||||||
18155 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) | ||||||
18156 | return nullptr; | ||||||
18157 | |||||||
18158 | return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, | ||||||
18159 | StartLoc, LParenLoc, EndLoc); | ||||||
18160 | } | ||||||
18161 | |||||||
18162 | OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, | ||||||
18163 | SourceLocation StartLoc, | ||||||
18164 | SourceLocation LParenLoc, | ||||||
18165 | SourceLocation EndLoc) { | ||||||
18166 | Expr *ValExpr = Grainsize; | ||||||
18167 | Stmt *HelperValStmt = nullptr; | ||||||
18168 | OpenMPDirectiveKind CaptureRegion = OMPD_unknown; | ||||||
18169 | |||||||
18170 | // OpenMP [2.9.2, taskloop Constrcut] | ||||||
18171 | // The parameter of the grainsize clause must be a positive integer | ||||||
18172 | // expression. | ||||||
18173 | if (!isNonNegativeIntegerValue( | ||||||
18174 | ValExpr, *this, OMPC_grainsize, | ||||||
18175 | /*StrictlyPositive=*/true, /*BuildCapture=*/true, | ||||||
18176 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) | ||||||
18177 | return nullptr; | ||||||
18178 | |||||||
18179 | return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, | ||||||
18180 | StartLoc, LParenLoc, EndLoc); | ||||||
18181 | } | ||||||
18182 | |||||||
18183 | OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, | ||||||
18184 | SourceLocation StartLoc, | ||||||
18185 | SourceLocation LParenLoc, | ||||||
18186 | SourceLocation EndLoc) { | ||||||
18187 | Expr *ValExpr = NumTasks; | ||||||
18188 | Stmt *HelperValStmt = nullptr; | ||||||
18189 | OpenMPDirectiveKind CaptureRegion = OMPD_unknown; | ||||||
18190 | |||||||
18191 | // OpenMP [2.9.2, taskloop Constrcut] | ||||||
18192 | // The parameter of the num_tasks clause must be a positive integer | ||||||
18193 | // expression. | ||||||
18194 | if (!isNonNegativeIntegerValue( | ||||||
18195 | ValExpr, *this, OMPC_num_tasks, | ||||||
18196 | /*StrictlyPositive=*/true, /*BuildCapture=*/true, | ||||||
18197 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) | ||||||
18198 | return nullptr; | ||||||
18199 | |||||||
18200 | return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, | ||||||
18201 | StartLoc, LParenLoc, EndLoc); | ||||||
18202 | } | ||||||
18203 | |||||||
18204 | OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, | ||||||
18205 | SourceLocation LParenLoc, | ||||||
18206 | SourceLocation EndLoc) { | ||||||
18207 | // OpenMP [2.13.2, critical construct, Description] | ||||||
18208 | // ... where hint-expression is an integer constant expression that evaluates | ||||||
18209 | // to a valid lock hint. | ||||||
18210 | ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); | ||||||
18211 | if (HintExpr.isInvalid()) | ||||||
18212 | return nullptr; | ||||||
18213 | return new (Context) | ||||||
18214 | OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); | ||||||
18215 | } | ||||||
18216 | |||||||
18217 | /// Tries to find omp_event_handle_t type. | ||||||
18218 | static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, | ||||||
18219 | DSAStackTy *Stack) { | ||||||
18220 | QualType OMPEventHandleT = Stack->getOMPEventHandleT(); | ||||||
18221 | if (!OMPEventHandleT.isNull()) | ||||||
18222 | return true; | ||||||
18223 | IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t"); | ||||||
18224 | ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); | ||||||
18225 | if (!PT.getAsOpaquePtr() || PT.get().isNull()) { | ||||||
18226 | S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t"; | ||||||
18227 | return false; | ||||||
18228 | } | ||||||
18229 | Stack->setOMPEventHandleT(PT.get()); | ||||||
18230 | return true; | ||||||
18231 | } | ||||||
18232 | |||||||
18233 | OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, | ||||||
18234 | SourceLocation LParenLoc, | ||||||
18235 | SourceLocation EndLoc) { | ||||||
18236 | if (!Evt->isValueDependent() && !Evt->isTypeDependent() && | ||||||
18237 | !Evt->isInstantiationDependent() && | ||||||
18238 | !Evt->containsUnexpandedParameterPack()) { | ||||||
18239 | if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||
18240 | return nullptr; | ||||||
18241 | // OpenMP 5.0, 2.10.1 task Construct. | ||||||
18242 | // event-handle is a variable of the omp_event_handle_t type. | ||||||
18243 | auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts()); | ||||||
18244 | if (!Ref) { | ||||||
18245 | Diag(Evt->getExprLoc(), diag::err_omp_var_expected) | ||||||
18246 | << "omp_event_handle_t" << 0 << Evt->getSourceRange(); | ||||||
18247 | return nullptr; | ||||||
18248 | } | ||||||
18249 | auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl()); | ||||||
18250 | if (!VD) { | ||||||
18251 | Diag(Evt->getExprLoc(), diag::err_omp_var_expected) | ||||||
18252 | << "omp_event_handle_t" << 0 << Evt->getSourceRange(); | ||||||
18253 | return nullptr; | ||||||
18254 | } | ||||||
18255 | if (!Context.hasSameUnqualifiedType(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPEventHandleT(), | ||||||
18256 | VD->getType()) || | ||||||
18257 | VD->getType().isConstant(Context)) { | ||||||
18258 | Diag(Evt->getExprLoc(), diag::err_omp_var_expected) | ||||||
18259 | << "omp_event_handle_t" << 1 << VD->getType() | ||||||
18260 | << Evt->getSourceRange(); | ||||||
18261 | return nullptr; | ||||||
18262 | } | ||||||
18263 | // OpenMP 5.0, 2.10.1 task Construct | ||||||
18264 | // [detach clause]... The event-handle will be considered as if it was | ||||||
18265 | // specified on a firstprivate clause. | ||||||
18266 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(VD, /*FromParent=*/false); | ||||||
18267 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && | ||||||
18268 | DVar.RefExpr) { | ||||||
18269 | Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa) | ||||||
18270 | << getOpenMPClauseName(DVar.CKind) | ||||||
18271 | << getOpenMPClauseName(OMPC_firstprivate); | ||||||
18272 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VD, DVar); | ||||||
18273 | return nullptr; | ||||||
18274 | } | ||||||
18275 | } | ||||||
18276 | |||||||
18277 | return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc); | ||||||
18278 | } | ||||||
18279 | |||||||
18280 | OMPClause *Sema::ActOnOpenMPDistScheduleClause( | ||||||
18281 | OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, | ||||||
18282 | SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, | ||||||
18283 | SourceLocation EndLoc) { | ||||||
18284 | if (Kind == OMPC_DIST_SCHEDULE_unknown) { | ||||||
18285 | std::string Values; | ||||||
18286 | Values += "'"; | ||||||
18287 | Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); | ||||||
18288 | Values += "'"; | ||||||
18289 | Diag(KindLoc, diag::err_omp_unexpected_clause_value) | ||||||
18290 | << Values << getOpenMPClauseName(OMPC_dist_schedule); | ||||||
18291 | return nullptr; | ||||||
18292 | } | ||||||
18293 | Expr *ValExpr = ChunkSize; | ||||||
18294 | Stmt *HelperValStmt = nullptr; | ||||||
18295 | if (ChunkSize) { | ||||||
18296 | if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && | ||||||
18297 | !ChunkSize->isInstantiationDependent() && | ||||||
18298 | !ChunkSize->containsUnexpandedParameterPack()) { | ||||||
18299 | SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); | ||||||
18300 | ExprResult Val = | ||||||
18301 | PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); | ||||||
18302 | if (Val.isInvalid()) | ||||||
18303 | return nullptr; | ||||||
18304 | |||||||
18305 | ValExpr = Val.get(); | ||||||
18306 | |||||||
18307 | // OpenMP [2.7.1, Restrictions] | ||||||
18308 | // chunk_size must be a loop invariant integer expression with a positive | ||||||
18309 | // value. | ||||||
18310 | if (Optional<llvm::APSInt> Result = | ||||||
18311 | ValExpr->getIntegerConstantExpr(Context)) { | ||||||
18312 | if (Result->isSigned() && !Result->isStrictlyPositive()) { | ||||||
18313 | Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) | ||||||
18314 | << "dist_schedule" << ChunkSize->getSourceRange(); | ||||||
18315 | return nullptr; | ||||||
18316 | } | ||||||
18317 | } else if (getOpenMPCaptureRegionForClause( | ||||||
18318 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(), OMPC_dist_schedule, | ||||||
18319 | LangOpts.OpenMP) != OMPD_unknown && | ||||||
18320 | !CurContext->isDependentContext()) { | ||||||
18321 | ValExpr = MakeFullExpr(ValExpr).get(); | ||||||
18322 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; | ||||||
18323 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); | ||||||
18324 | HelperValStmt = buildPreInits(Context, Captures); | ||||||
18325 | } | ||||||
18326 | } | ||||||
18327 | } | ||||||
18328 | |||||||
18329 | return new (Context) | ||||||
18330 | OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, | ||||||
18331 | Kind, ValExpr, HelperValStmt); | ||||||
18332 | } | ||||||
18333 | |||||||
18334 | OMPClause *Sema::ActOnOpenMPDefaultmapClause( | ||||||
18335 | OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, | ||||||
18336 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, | ||||||
18337 | SourceLocation KindLoc, SourceLocation EndLoc) { | ||||||
18338 | if (getLangOpts().OpenMP < 50) { | ||||||
18339 | if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || | ||||||
18340 | Kind != OMPC_DEFAULTMAP_scalar) { | ||||||
18341 | std::string Value; | ||||||
18342 | SourceLocation Loc; | ||||||
18343 | Value += "'"; | ||||||
18344 | if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { | ||||||
18345 | Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, | ||||||
18346 | OMPC_DEFAULTMAP_MODIFIER_tofrom); | ||||||
18347 | Loc = MLoc; | ||||||
18348 | } else { | ||||||
18349 | Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, | ||||||
18350 | OMPC_DEFAULTMAP_scalar); | ||||||
18351 | Loc = KindLoc; | ||||||
18352 | } | ||||||
18353 | Value += "'"; | ||||||
18354 | Diag(Loc, diag::err_omp_unexpected_clause_value) | ||||||
18355 | << Value << getOpenMPClauseName(OMPC_defaultmap); | ||||||
18356 | return nullptr; | ||||||
18357 | } | ||||||
18358 | } else { | ||||||
18359 | bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); | ||||||
18360 | bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) || | ||||||
18361 | (LangOpts.OpenMP >= 50 && KindLoc.isInvalid()); | ||||||
18362 | if (!isDefaultmapKind || !isDefaultmapModifier) { | ||||||
18363 | std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', " | ||||||
18364 | "'firstprivate', 'none', 'default'"; | ||||||
18365 | std::string KindValue = "'scalar', 'aggregate', 'pointer'"; | ||||||
18366 | if (!isDefaultmapKind && isDefaultmapModifier) { | ||||||
18367 | Diag(KindLoc, diag::err_omp_unexpected_clause_value) | ||||||
18368 | << KindValue << getOpenMPClauseName(OMPC_defaultmap); | ||||||
18369 | } else if (isDefaultmapKind && !isDefaultmapModifier) { | ||||||
18370 | Diag(MLoc, diag::err_omp_unexpected_clause_value) | ||||||
18371 | << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); | ||||||
18372 | } else { | ||||||
18373 | Diag(MLoc, diag::err_omp_unexpected_clause_value) | ||||||
18374 | << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); | ||||||
18375 | Diag(KindLoc, diag::err_omp_unexpected_clause_value) | ||||||
18376 | << KindValue << getOpenMPClauseName(OMPC_defaultmap); | ||||||
18377 | } | ||||||
18378 | return nullptr; | ||||||
18379 | } | ||||||
18380 | |||||||
18381 | // OpenMP [5.0, 2.12.5, Restrictions, p. 174] | ||||||
18382 | // At most one defaultmap clause for each category can appear on the | ||||||
18383 | // directive. | ||||||
18384 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->checkDefaultmapCategory(Kind)) { | ||||||
18385 | Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); | ||||||
18386 | return nullptr; | ||||||
18387 | } | ||||||
18388 | } | ||||||
18389 | if (Kind == OMPC_DEFAULTMAP_unknown) { | ||||||
18390 | // Variable category is not specified - mark all categories. | ||||||
18391 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc); | ||||||
18392 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc); | ||||||
18393 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc); | ||||||
18394 | } else { | ||||||
18395 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setDefaultDMAAttr(M, Kind, StartLoc); | ||||||
18396 | } | ||||||
18397 | |||||||
18398 | return new (Context) | ||||||
18399 | OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); | ||||||
18400 | } | ||||||
18401 | |||||||
18402 | bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { | ||||||
18403 | DeclContext *CurLexicalContext = getCurLexicalContext(); | ||||||
18404 | if (!CurLexicalContext->isFileContext() && | ||||||
18405 | !CurLexicalContext->isExternCContext() && | ||||||
18406 | !CurLexicalContext->isExternCXXContext() && | ||||||
18407 | !isa<CXXRecordDecl>(CurLexicalContext) && | ||||||
18408 | !isa<ClassTemplateDecl>(CurLexicalContext) && | ||||||
18409 | !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && | ||||||
18410 | !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { | ||||||
18411 | Diag(Loc, diag::err_omp_region_not_file_context); | ||||||
18412 | return false; | ||||||
18413 | } | ||||||
18414 | ++DeclareTargetNestingLevel; | ||||||
18415 | return true; | ||||||
18416 | } | ||||||
18417 | |||||||
18418 | void Sema::ActOnFinishOpenMPDeclareTargetDirective() { | ||||||
18419 | assert(DeclareTargetNestingLevel > 0 &&((DeclareTargetNestingLevel > 0 && "Unexpected ActOnFinishOpenMPDeclareTargetDirective" ) ? static_cast<void> (0) : __assert_fail ("DeclareTargetNestingLevel > 0 && \"Unexpected ActOnFinishOpenMPDeclareTargetDirective\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18420, __PRETTY_FUNCTION__)) | ||||||
18420 | "Unexpected ActOnFinishOpenMPDeclareTargetDirective")((DeclareTargetNestingLevel > 0 && "Unexpected ActOnFinishOpenMPDeclareTargetDirective" ) ? static_cast<void> (0) : __assert_fail ("DeclareTargetNestingLevel > 0 && \"Unexpected ActOnFinishOpenMPDeclareTargetDirective\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18420, __PRETTY_FUNCTION__)); | ||||||
18421 | --DeclareTargetNestingLevel; | ||||||
18422 | } | ||||||
18423 | |||||||
18424 | NamedDecl * | ||||||
18425 | Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, | ||||||
18426 | const DeclarationNameInfo &Id, | ||||||
18427 | NamedDeclSetType &SameDirectiveDecls) { | ||||||
18428 | LookupResult Lookup(*this, Id, LookupOrdinaryName); | ||||||
18429 | LookupParsedName(Lookup, CurScope, &ScopeSpec, true); | ||||||
18430 | |||||||
18431 | if (Lookup.isAmbiguous()) | ||||||
18432 | return nullptr; | ||||||
18433 | Lookup.suppressDiagnostics(); | ||||||
18434 | |||||||
18435 | if (!Lookup.isSingleResult()) { | ||||||
18436 | VarOrFuncDeclFilterCCC CCC(*this); | ||||||
18437 | if (TypoCorrection Corrected = | ||||||
18438 | CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, | ||||||
18439 | CTK_ErrorRecovery)) { | ||||||
18440 | diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) | ||||||
18441 | << Id.getName()); | ||||||
18442 | checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); | ||||||
18443 | return nullptr; | ||||||
18444 | } | ||||||
18445 | |||||||
18446 | Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); | ||||||
18447 | return nullptr; | ||||||
18448 | } | ||||||
18449 | |||||||
18450 | NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); | ||||||
18451 | if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && | ||||||
18452 | !isa<FunctionTemplateDecl>(ND)) { | ||||||
18453 | Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); | ||||||
18454 | return nullptr; | ||||||
18455 | } | ||||||
18456 | if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) | ||||||
18457 | Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); | ||||||
18458 | return ND; | ||||||
18459 | } | ||||||
18460 | |||||||
18461 | void Sema::ActOnOpenMPDeclareTargetName( | ||||||
18462 | NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, | ||||||
18463 | OMPDeclareTargetDeclAttr::DevTypeTy DT) { | ||||||
18464 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18466, __PRETTY_FUNCTION__)) | ||||||
18465 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18466, __PRETTY_FUNCTION__)) | ||||||
18466 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18466, __PRETTY_FUNCTION__)); | ||||||
18467 | |||||||
18468 | // Diagnose marking after use as it may lead to incorrect diagnosis and | ||||||
18469 | // codegen. | ||||||
18470 | if (LangOpts.OpenMP >= 50 && | ||||||
18471 | (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) | ||||||
18472 | Diag(Loc, diag::warn_omp_declare_target_after_first_use); | ||||||
18473 | |||||||
18474 | Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = | ||||||
18475 | OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); | ||||||
18476 | if (DevTy.hasValue() && *DevTy != DT) { | ||||||
18477 | Diag(Loc, diag::err_omp_device_type_mismatch) | ||||||
18478 | << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) | ||||||
18479 | << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); | ||||||
18480 | return; | ||||||
18481 | } | ||||||
18482 | Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = | ||||||
18483 | OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); | ||||||
18484 | if (!Res) { | ||||||
18485 | auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, | ||||||
18486 | SourceRange(Loc, Loc)); | ||||||
18487 | ND->addAttr(A); | ||||||
18488 | if (ASTMutationListener *ML = Context.getASTMutationListener()) | ||||||
18489 | ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); | ||||||
18490 | checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); | ||||||
18491 | } else if (*Res != MT) { | ||||||
18492 | Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; | ||||||
18493 | } | ||||||
18494 | } | ||||||
18495 | |||||||
18496 | static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, | ||||||
18497 | Sema &SemaRef, Decl *D) { | ||||||
18498 | if (!D || !isa<VarDecl>(D)) | ||||||
18499 | return; | ||||||
18500 | auto *VD = cast<VarDecl>(D); | ||||||
18501 | Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = | ||||||
18502 | OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); | ||||||
18503 | if (SemaRef.LangOpts.OpenMP >= 50 && | ||||||
18504 | (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || | ||||||
18505 | SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && | ||||||
18506 | VD->hasGlobalStorage()) { | ||||||
18507 | llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = | ||||||
18508 | OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); | ||||||
18509 | if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { | ||||||
18510 | // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions | ||||||
18511 | // If a lambda declaration and definition appears between a | ||||||
18512 | // declare target directive and the matching end declare target | ||||||
18513 | // directive, all variables that are captured by the lambda | ||||||
18514 | // expression must also appear in a to clause. | ||||||
18515 | SemaRef.Diag(VD->getLocation(), | ||||||
18516 | diag::err_omp_lambda_capture_in_declare_target_not_to); | ||||||
18517 | SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) | ||||||
18518 | << VD << 0 << SR; | ||||||
18519 | return; | ||||||
18520 | } | ||||||
18521 | } | ||||||
18522 | if (MapTy.hasValue()) | ||||||
18523 | return; | ||||||
18524 | SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); | ||||||
18525 | SemaRef.Diag(SL, diag::note_used_here) << SR; | ||||||
18526 | } | ||||||
18527 | |||||||
18528 | static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, | ||||||
18529 | Sema &SemaRef, DSAStackTy *Stack, | ||||||
18530 | ValueDecl *VD) { | ||||||
18531 | return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || | ||||||
18532 | checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), | ||||||
18533 | /*FullCheck=*/false); | ||||||
18534 | } | ||||||
18535 | |||||||
18536 | void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, | ||||||
18537 | SourceLocation IdLoc) { | ||||||
18538 | if (!D || D->isInvalidDecl()) | ||||||
18539 | return; | ||||||
18540 | SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); | ||||||
18541 | SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); | ||||||
18542 | if (auto *VD = dyn_cast<VarDecl>(D)) { | ||||||
18543 | // Only global variables can be marked as declare target. | ||||||
18544 | if (!VD->isFileVarDecl() && !VD->isStaticLocal() && | ||||||
18545 | !VD->isStaticDataMember()) | ||||||
18546 | return; | ||||||
18547 | // 2.10.6: threadprivate variable cannot appear in a declare target | ||||||
18548 | // directive. | ||||||
18549 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isThreadPrivate(VD)) { | ||||||
18550 | Diag(SL, diag::err_omp_threadprivate_in_target); | ||||||
18551 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VD, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(VD, false)); | ||||||
18552 | return; | ||||||
18553 | } | ||||||
18554 | } | ||||||
18555 | if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) | ||||||
18556 | D = FTD->getTemplatedDecl(); | ||||||
18557 | if (auto *FD = dyn_cast<FunctionDecl>(D)) { | ||||||
18558 | llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = | ||||||
18559 | OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); | ||||||
18560 | if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { | ||||||
18561 | Diag(IdLoc, diag::err_omp_function_in_link_clause); | ||||||
18562 | Diag(FD->getLocation(), diag::note_defined_here) << FD; | ||||||
18563 | return; | ||||||
18564 | } | ||||||
18565 | } | ||||||
18566 | if (auto *VD = dyn_cast<ValueDecl>(D)) { | ||||||
18567 | // Problem if any with var declared with incomplete type will be reported | ||||||
18568 | // as normal, so no need to check it here. | ||||||
18569 | if ((E || !VD->getType()->isIncompleteType()) && | ||||||
18570 | !checkValueDeclInTarget(SL, SR, *this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VD)) | ||||||
18571 | return; | ||||||
18572 | if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { | ||||||
18573 | // Checking declaration inside declare target region. | ||||||
18574 | if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || | ||||||
18575 | isa<FunctionTemplateDecl>(D)) { | ||||||
18576 | auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( | ||||||
18577 | Context, OMPDeclareTargetDeclAttr::MT_To, | ||||||
18578 | OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); | ||||||
18579 | D->addAttr(A); | ||||||
18580 | if (ASTMutationListener *ML = Context.getASTMutationListener()) | ||||||
18581 | ML->DeclarationMarkedOpenMPDeclareTarget(D, A); | ||||||
18582 | } | ||||||
18583 | return; | ||||||
18584 | } | ||||||
18585 | } | ||||||
18586 | if (!E) | ||||||
18587 | return; | ||||||
18588 | checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); | ||||||
18589 | } | ||||||
18590 | |||||||
18591 | OMPClause *Sema::ActOnOpenMPToClause( | ||||||
18592 | ArrayRef<OpenMPMotionModifierKind> MotionModifiers, | ||||||
18593 | ArrayRef<SourceLocation> MotionModifiersLoc, | ||||||
18594 | CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, | ||||||
18595 | SourceLocation ColonLoc, ArrayRef<Expr *> VarList, | ||||||
18596 | const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { | ||||||
18597 | OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, | ||||||
18598 | OMPC_MOTION_MODIFIER_unknown}; | ||||||
18599 | SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; | ||||||
18600 | |||||||
18601 | // Process motion-modifiers, flag errors for duplicate modifiers. | ||||||
18602 | unsigned Count = 0; | ||||||
18603 | for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { | ||||||
18604 | if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && | ||||||
18605 | llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) { | ||||||
18606 | Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); | ||||||
18607 | continue; | ||||||
18608 | } | ||||||
18609 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18610, __PRETTY_FUNCTION__)) | ||||||
18610 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18610, __PRETTY_FUNCTION__)); | ||||||
18611 | Modifiers[Count] = MotionModifiers[I]; | ||||||
18612 | ModifiersLoc[Count] = MotionModifiersLoc[I]; | ||||||
18613 | ++Count; | ||||||
18614 | } | ||||||
18615 | |||||||
18616 | MappableVarListInfo MVLI(VarList); | ||||||
18617 | checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), OMPC_to, MVLI, Locs.StartLoc, | ||||||
18618 | MapperIdScopeSpec, MapperId, UnresolvedMappers); | ||||||
18619 | if (MVLI.ProcessedVarList.empty()) | ||||||
18620 | return nullptr; | ||||||
18621 | |||||||
18622 | return OMPToClause::Create( | ||||||
18623 | Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, | ||||||
18624 | MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, | ||||||
18625 | MapperIdScopeSpec.getWithLocInContext(Context), MapperId); | ||||||
18626 | } | ||||||
18627 | |||||||
18628 | OMPClause *Sema::ActOnOpenMPFromClause( | ||||||
18629 | ArrayRef<OpenMPMotionModifierKind> MotionModifiers, | ||||||
18630 | ArrayRef<SourceLocation> MotionModifiersLoc, | ||||||
18631 | CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, | ||||||
18632 | SourceLocation ColonLoc, ArrayRef<Expr *> VarList, | ||||||
18633 | const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { | ||||||
18634 | OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, | ||||||
18635 | OMPC_MOTION_MODIFIER_unknown}; | ||||||
18636 | SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; | ||||||
18637 | |||||||
18638 | // Process motion-modifiers, flag errors for duplicate modifiers. | ||||||
18639 | unsigned Count = 0; | ||||||
18640 | for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { | ||||||
18641 | if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && | ||||||
18642 | llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) { | ||||||
18643 | Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); | ||||||
18644 | continue; | ||||||
18645 | } | ||||||
18646 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18647, __PRETTY_FUNCTION__)) | ||||||
18647 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18647, __PRETTY_FUNCTION__)); | ||||||
18648 | Modifiers[Count] = MotionModifiers[I]; | ||||||
18649 | ModifiersLoc[Count] = MotionModifiersLoc[I]; | ||||||
18650 | ++Count; | ||||||
18651 | } | ||||||
18652 | |||||||
18653 | MappableVarListInfo MVLI(VarList); | ||||||
18654 | checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), OMPC_from, MVLI, Locs.StartLoc, | ||||||
18655 | MapperIdScopeSpec, MapperId, UnresolvedMappers); | ||||||
18656 | if (MVLI.ProcessedVarList.empty()) | ||||||
18657 | return nullptr; | ||||||
18658 | |||||||
18659 | return OMPFromClause::Create( | ||||||
18660 | Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, | ||||||
18661 | MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, | ||||||
18662 | MapperIdScopeSpec.getWithLocInContext(Context), MapperId); | ||||||
18663 | } | ||||||
18664 | |||||||
18665 | OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, | ||||||
18666 | const OMPVarListLocTy &Locs) { | ||||||
18667 | MappableVarListInfo MVLI(VarList); | ||||||
18668 | SmallVector<Expr *, 8> PrivateCopies; | ||||||
18669 | SmallVector<Expr *, 8> Inits; | ||||||
18670 | |||||||
18671 | for (Expr *RefExpr : VarList) { | ||||||
18672 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18672, __PRETTY_FUNCTION__)); | ||||||
18673 | SourceLocation ELoc; | ||||||
18674 | SourceRange ERange; | ||||||
18675 | Expr *SimpleRefExpr = RefExpr; | ||||||
18676 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||||
18677 | if (Res.second) { | ||||||
18678 | // It will be analyzed later. | ||||||
18679 | MVLI.ProcessedVarList.push_back(RefExpr); | ||||||
18680 | PrivateCopies.push_back(nullptr); | ||||||
18681 | Inits.push_back(nullptr); | ||||||
18682 | } | ||||||
18683 | ValueDecl *D = Res.first; | ||||||
18684 | if (!D) | ||||||
18685 | continue; | ||||||
18686 | |||||||
18687 | QualType Type = D->getType(); | ||||||
18688 | Type = Type.getNonReferenceType().getUnqualifiedType(); | ||||||
18689 | |||||||
18690 | auto *VD = dyn_cast<VarDecl>(D); | ||||||
18691 | |||||||
18692 | // Item should be a pointer or reference to pointer. | ||||||
18693 | if (!Type->isPointerType()) { | ||||||
18694 | Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) | ||||||
18695 | << 0 << RefExpr->getSourceRange(); | ||||||
18696 | continue; | ||||||
18697 | } | ||||||
18698 | |||||||
18699 | // Build the private variable and the expression that refers to it. | ||||||
18700 | auto VDPrivate = | ||||||
18701 | buildVarDecl(*this, ELoc, Type, D->getName(), | ||||||
18702 | D->hasAttrs() ? &D->getAttrs() : nullptr, | ||||||
18703 | VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); | ||||||
18704 | if (VDPrivate->isInvalidDecl()) | ||||||
18705 | continue; | ||||||
18706 | |||||||
18707 | CurContext->addDecl(VDPrivate); | ||||||
18708 | DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( | ||||||
18709 | *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); | ||||||
18710 | |||||||
18711 | // Add temporary variable to initialize the private copy of the pointer. | ||||||
18712 | VarDecl *VDInit = | ||||||
18713 | buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); | ||||||
18714 | DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( | ||||||
18715 | *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); | ||||||
18716 | AddInitializerToDecl(VDPrivate, | ||||||
18717 | DefaultLvalueConversion(VDInitRefExpr).get(), | ||||||
18718 | /*DirectInit=*/false); | ||||||
18719 | |||||||
18720 | // If required, build a capture to implement the privatization initialized | ||||||
18721 | // with the current list item value. | ||||||
18722 | DeclRefExpr *Ref = nullptr; | ||||||
18723 | if (!VD) | ||||||
18724 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); | ||||||
18725 | MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); | ||||||
18726 | PrivateCopies.push_back(VDPrivateRefExpr); | ||||||
18727 | Inits.push_back(VDInitRefExpr); | ||||||
18728 | |||||||
18729 | // We need to add a data sharing attribute for this variable to make sure it | ||||||
18730 | // is correctly captured. A variable that shows up in a use_device_ptr has | ||||||
18731 | // similar properties of a first private variable. | ||||||
18732 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); | ||||||
18733 | |||||||
18734 | // Create a mappable component for the list item. List items in this clause | ||||||
18735 | // only need a component. | ||||||
18736 | MVLI.VarBaseDeclarations.push_back(D); | ||||||
18737 | MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); | ||||||
18738 | MVLI.VarComponents.back().push_back( | ||||||
18739 | OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); | ||||||
18740 | } | ||||||
18741 | |||||||
18742 | if (MVLI.ProcessedVarList.empty()) | ||||||
18743 | return nullptr; | ||||||
18744 | |||||||
18745 | return OMPUseDevicePtrClause::Create( | ||||||
18746 | Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, | ||||||
18747 | MVLI.VarBaseDeclarations, MVLI.VarComponents); | ||||||
18748 | } | ||||||
18749 | |||||||
18750 | OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList, | ||||||
18751 | const OMPVarListLocTy &Locs) { | ||||||
18752 | MappableVarListInfo MVLI(VarList); | ||||||
18753 | |||||||
18754 | for (Expr *RefExpr : VarList) { | ||||||
18755 | 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~++20200806111125+5446ec85070/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 | /*AllowArraySection=*/true); | ||||||
18761 | if (Res.second) { | ||||||
18762 | // It will be analyzed later. | ||||||
18763 | MVLI.ProcessedVarList.push_back(RefExpr); | ||||||
18764 | } | ||||||
18765 | ValueDecl *D = Res.first; | ||||||
18766 | if (!D) | ||||||
18767 | continue; | ||||||
18768 | auto *VD = dyn_cast<VarDecl>(D); | ||||||
18769 | |||||||
18770 | // If required, build a capture to implement the privatization initialized | ||||||
18771 | // with the current list item value. | ||||||
18772 | DeclRefExpr *Ref = nullptr; | ||||||
18773 | if (!VD) | ||||||
18774 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); | ||||||
18775 | MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); | ||||||
18776 | |||||||
18777 | // We need to add a data sharing attribute for this variable to make sure it | ||||||
18778 | // is correctly captured. A variable that shows up in a use_device_addr has | ||||||
18779 | // similar properties of a first private variable. | ||||||
18780 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); | ||||||
18781 | |||||||
18782 | // Create a mappable component for the list item. List items in this clause | ||||||
18783 | // only need a component. | ||||||
18784 | MVLI.VarBaseDeclarations.push_back(D); | ||||||
18785 | MVLI.VarComponents.emplace_back(); | ||||||
18786 | Expr *Component = SimpleRefExpr; | ||||||
18787 | if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) || | ||||||
18788 | isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts()))) | ||||||
18789 | Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get(); | ||||||
18790 | MVLI.VarComponents.back().push_back( | ||||||
18791 | OMPClauseMappableExprCommon::MappableComponent(Component, D)); | ||||||
18792 | } | ||||||
18793 | |||||||
18794 | if (MVLI.ProcessedVarList.empty()) | ||||||
18795 | return nullptr; | ||||||
18796 | |||||||
18797 | return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList, | ||||||
18798 | MVLI.VarBaseDeclarations, | ||||||
18799 | MVLI.VarComponents); | ||||||
18800 | } | ||||||
18801 | |||||||
18802 | OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, | ||||||
18803 | const OMPVarListLocTy &Locs) { | ||||||
18804 | MappableVarListInfo MVLI(VarList); | ||||||
18805 | for (Expr *RefExpr : VarList) { | ||||||
18806 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18806, __PRETTY_FUNCTION__)); | ||||||
18807 | SourceLocation ELoc; | ||||||
18808 | SourceRange ERange; | ||||||
18809 | Expr *SimpleRefExpr = RefExpr; | ||||||
18810 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||||
18811 | if (Res.second) { | ||||||
18812 | // It will be analyzed later. | ||||||
18813 | MVLI.ProcessedVarList.push_back(RefExpr); | ||||||
18814 | } | ||||||
18815 | ValueDecl *D = Res.first; | ||||||
18816 | if (!D) | ||||||
18817 | continue; | ||||||
18818 | |||||||
18819 | QualType Type = D->getType(); | ||||||
18820 | // item should be a pointer or array or reference to pointer or array | ||||||
18821 | if (!Type.getNonReferenceType()->isPointerType() && | ||||||
18822 | !Type.getNonReferenceType()->isArrayType()) { | ||||||
18823 | Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) | ||||||
18824 | << 0 << RefExpr->getSourceRange(); | ||||||
18825 | continue; | ||||||
18826 | } | ||||||
18827 | |||||||
18828 | // Check if the declaration in the clause does not show up in any data | ||||||
18829 | // sharing attribute. | ||||||
18830 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); | ||||||
18831 | if (isOpenMPPrivate(DVar.CKind)) { | ||||||
18832 | Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) | ||||||
18833 | << getOpenMPClauseName(DVar.CKind) | ||||||
18834 | << getOpenMPClauseName(OMPC_is_device_ptr) | ||||||
18835 | << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()); | ||||||
18836 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); | ||||||
18837 | continue; | ||||||
18838 | } | ||||||
18839 | |||||||
18840 | const Expr *ConflictExpr; | ||||||
18841 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->checkMappableExprComponentListsForDecl( | ||||||
18842 | D, /*CurrentRegionOnly=*/true, | ||||||
18843 | [&ConflictExpr]( | ||||||
18844 | OMPClauseMappableExprCommon::MappableExprComponentListRef R, | ||||||
18845 | OpenMPClauseKind) -> bool { | ||||||
18846 | ConflictExpr = R.front().getAssociatedExpression(); | ||||||
18847 | return true; | ||||||
18848 | })) { | ||||||
18849 | Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); | ||||||
18850 | Diag(ConflictExpr->getExprLoc(), diag::note_used_here) | ||||||
18851 | << ConflictExpr->getSourceRange(); | ||||||
18852 | continue; | ||||||
18853 | } | ||||||
18854 | |||||||
18855 | // Store the components in the stack so that they can be used to check | ||||||
18856 | // against other clauses later on. | ||||||
18857 | OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); | ||||||
18858 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addMappableExpressionComponents( | ||||||
18859 | D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); | ||||||
18860 | |||||||
18861 | // Record the expression we've just processed. | ||||||
18862 | MVLI.ProcessedVarList.push_back(SimpleRefExpr); | ||||||
18863 | |||||||
18864 | // Create a mappable component for the list item. List items in this clause | ||||||
18865 | // only need a component. We use a null declaration to signal fields in | ||||||
18866 | // 'this'. | ||||||
18867 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18869, __PRETTY_FUNCTION__)) | ||||||
18868 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18869, __PRETTY_FUNCTION__)) | ||||||
18869 | "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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18869, __PRETTY_FUNCTION__)); | ||||||
18870 | MVLI.VarBaseDeclarations.push_back( | ||||||
18871 | isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); | ||||||
18872 | MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); | ||||||
18873 | MVLI.VarComponents.back().push_back(MC); | ||||||
18874 | } | ||||||
18875 | |||||||
18876 | if (MVLI.ProcessedVarList.empty()) | ||||||
18877 | return nullptr; | ||||||
18878 | |||||||
18879 | return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, | ||||||
18880 | MVLI.VarBaseDeclarations, | ||||||
18881 | MVLI.VarComponents); | ||||||
18882 | } | ||||||
18883 | |||||||
18884 | OMPClause *Sema::ActOnOpenMPAllocateClause( | ||||||
18885 | Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, | ||||||
18886 | SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { | ||||||
18887 | if (Allocator) { | ||||||
18888 | // OpenMP [2.11.4 allocate Clause, Description] | ||||||
18889 | // allocator is an expression of omp_allocator_handle_t type. | ||||||
18890 | if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||
18891 | return nullptr; | ||||||
18892 | |||||||
18893 | ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); | ||||||
18894 | if (AllocatorRes.isInvalid()) | ||||||
18895 | return nullptr; | ||||||
18896 | AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), | ||||||
18897 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPAllocatorHandleT(), | ||||||
18898 | Sema::AA_Initializing, | ||||||
18899 | /*AllowExplicit=*/true); | ||||||
18900 | if (AllocatorRes.isInvalid()) | ||||||
18901 | return nullptr; | ||||||
18902 | Allocator = AllocatorRes.get(); | ||||||
18903 | } else { | ||||||
18904 | // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. | ||||||
18905 | // allocate clauses that appear on a target construct or on constructs in a | ||||||
18906 | // target region must specify an allocator expression unless a requires | ||||||
18907 | // directive with the dynamic_allocators clause is present in the same | ||||||
18908 | // compilation unit. | ||||||
18909 | if (LangOpts.OpenMPIsDevice && | ||||||
18910 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) | ||||||
18911 | targetDiag(StartLoc, diag::err_expected_allocator_expression); | ||||||
18912 | } | ||||||
18913 | // Analyze and build list of variables. | ||||||
18914 | SmallVector<Expr *, 8> Vars; | ||||||
18915 | for (Expr *RefExpr : VarList) { | ||||||
18916 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18916, __PRETTY_FUNCTION__)); | ||||||
18917 | SourceLocation ELoc; | ||||||
18918 | SourceRange ERange; | ||||||
18919 | Expr *SimpleRefExpr = RefExpr; | ||||||
18920 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||||
18921 | if (Res.second) { | ||||||
18922 | // It will be analyzed later. | ||||||
18923 | Vars.push_back(RefExpr); | ||||||
18924 | } | ||||||
18925 | ValueDecl *D = Res.first; | ||||||
18926 | if (!D) | ||||||
18927 | continue; | ||||||
18928 | |||||||
18929 | auto *VD = dyn_cast<VarDecl>(D); | ||||||
18930 | DeclRefExpr *Ref = nullptr; | ||||||
18931 | if (!VD && !CurContext->isDependentContext()) | ||||||
18932 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); | ||||||
18933 | Vars.push_back((VD || CurContext->isDependentContext()) | ||||||
18934 | ? RefExpr->IgnoreParens() | ||||||
18935 | : Ref); | ||||||
18936 | } | ||||||
18937 | |||||||
18938 | if (Vars.empty()) | ||||||
18939 | return nullptr; | ||||||
18940 | |||||||
18941 | if (Allocator) | ||||||
18942 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addInnerAllocatorExpr(Allocator); | ||||||
18943 | return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, | ||||||
18944 | ColonLoc, EndLoc, Vars); | ||||||
18945 | } | ||||||
18946 | |||||||
18947 | OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, | ||||||
18948 | SourceLocation StartLoc, | ||||||
18949 | SourceLocation LParenLoc, | ||||||
18950 | SourceLocation EndLoc) { | ||||||
18951 | SmallVector<Expr *, 8> Vars; | ||||||
18952 | for (Expr *RefExpr : VarList) { | ||||||
18953 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18953, __PRETTY_FUNCTION__)); | ||||||
18954 | SourceLocation ELoc; | ||||||
18955 | SourceRange ERange; | ||||||
18956 | Expr *SimpleRefExpr = RefExpr; | ||||||
18957 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||||
18958 | if (Res.second) | ||||||
18959 | // It will be analyzed later. | ||||||
18960 | Vars.push_back(RefExpr); | ||||||
18961 | ValueDecl *D = Res.first; | ||||||
18962 | if (!D) | ||||||
18963 | continue; | ||||||
18964 | |||||||
18965 | // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. | ||||||
18966 | // A list-item cannot appear in more than one nontemporal clause. | ||||||
18967 | if (const Expr *PrevRef = | ||||||
18968 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addUniqueNontemporal(D, SimpleRefExpr)) { | ||||||
18969 | Diag(ELoc, diag::err_omp_used_in_clause_twice) | ||||||
18970 | << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; | ||||||
18971 | Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) | ||||||
18972 | << getOpenMPClauseName(OMPC_nontemporal); | ||||||
18973 | continue; | ||||||
18974 | } | ||||||
18975 | |||||||
18976 | Vars.push_back(RefExpr); | ||||||
18977 | } | ||||||
18978 | |||||||
18979 | if (Vars.empty()) | ||||||
18980 | return nullptr; | ||||||
18981 | |||||||
18982 | return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, | ||||||
18983 | Vars); | ||||||
18984 | } | ||||||
18985 | |||||||
18986 | OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, | ||||||
18987 | SourceLocation StartLoc, | ||||||
18988 | SourceLocation LParenLoc, | ||||||
18989 | SourceLocation EndLoc) { | ||||||
18990 | SmallVector<Expr *, 8> Vars; | ||||||
18991 | for (Expr *RefExpr : VarList) { | ||||||
18992 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18992, __PRETTY_FUNCTION__)); | ||||||
18993 | SourceLocation ELoc; | ||||||
18994 | SourceRange ERange; | ||||||
18995 | Expr *SimpleRefExpr = RefExpr; | ||||||
18996 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, | ||||||
18997 | /*AllowArraySection=*/true); | ||||||
18998 | if (Res.second) | ||||||
18999 | // It will be analyzed later. | ||||||
19000 | Vars.push_back(RefExpr); | ||||||
19001 | ValueDecl *D = Res.first; | ||||||
19002 | if (!D) | ||||||
19003 | continue; | ||||||
19004 | |||||||
19005 | const DSAStackTy::DSAVarData DVar = | ||||||
19006 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/true); | ||||||
19007 | // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. | ||||||
19008 | // A list item that appears in the inclusive or exclusive clause must appear | ||||||
19009 | // in a reduction clause with the inscan modifier on the enclosing | ||||||
19010 | // worksharing-loop, worksharing-loop SIMD, or simd construct. | ||||||
19011 | if (DVar.CKind != OMPC_reduction || | ||||||
19012 | DVar.Modifier != OMPC_REDUCTION_inscan) | ||||||
19013 | Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) | ||||||
19014 | << RefExpr->getSourceRange(); | ||||||
19015 | |||||||
19016 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentDirective() != OMPD_unknown) | ||||||
19017 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->markDeclAsUsedInScanDirective(D); | ||||||
19018 | Vars.push_back(RefExpr); | ||||||
19019 | } | ||||||
19020 | |||||||
19021 | if (Vars.empty()) | ||||||
19022 | return nullptr; | ||||||
19023 | |||||||
19024 | return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); | ||||||
19025 | } | ||||||
19026 | |||||||
19027 | OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList, | ||||||
19028 | SourceLocation StartLoc, | ||||||
19029 | SourceLocation LParenLoc, | ||||||
19030 | SourceLocation EndLoc) { | ||||||
19031 | SmallVector<Expr *, 8> Vars; | ||||||
19032 | for (Expr *RefExpr : VarList) { | ||||||
19033 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 19033, __PRETTY_FUNCTION__)); | ||||||
19034 | SourceLocation ELoc; | ||||||
19035 | SourceRange ERange; | ||||||
19036 | Expr *SimpleRefExpr = RefExpr; | ||||||
19037 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, | ||||||
19038 | /*AllowArraySection=*/true); | ||||||
19039 | if (Res.second) | ||||||
19040 | // It will be analyzed later. | ||||||
19041 | Vars.push_back(RefExpr); | ||||||
19042 | ValueDecl *D = Res.first; | ||||||
19043 | if (!D) | ||||||
19044 | continue; | ||||||
19045 | |||||||
19046 | OpenMPDirectiveKind ParentDirective = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentDirective(); | ||||||
19047 | DSAStackTy::DSAVarData DVar; | ||||||
19048 | if (ParentDirective != OMPD_unknown) | ||||||
19049 | DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/true); | ||||||
19050 | // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. | ||||||
19051 | // A list item that appears in the inclusive or exclusive clause must appear | ||||||
19052 | // in a reduction clause with the inscan modifier on the enclosing | ||||||
19053 | // worksharing-loop, worksharing-loop SIMD, or simd construct. | ||||||
19054 | if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction || | ||||||
19055 | DVar.Modifier != OMPC_REDUCTION_inscan) { | ||||||
19056 | Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) | ||||||
19057 | << RefExpr->getSourceRange(); | ||||||
19058 | } else { | ||||||
19059 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->markDeclAsUsedInScanDirective(D); | ||||||
19060 | } | ||||||
19061 | Vars.push_back(RefExpr); | ||||||
19062 | } | ||||||
19063 | |||||||
19064 | if (Vars.empty()) | ||||||
19065 | return nullptr; | ||||||
19066 | |||||||
19067 | return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); | ||||||
19068 | } | ||||||
19069 | |||||||
19070 | /// Tries to find omp_alloctrait_t type. | ||||||
19071 | static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) { | ||||||
19072 | QualType OMPAlloctraitT = Stack->getOMPAlloctraitT(); | ||||||
19073 | if (!OMPAlloctraitT.isNull()) | ||||||
19074 | return true; | ||||||
19075 | IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t"); | ||||||
19076 | ParsedType PT = S.getTypeName(II, Loc, S.getCurScope()); | ||||||
19077 | if (!PT.getAsOpaquePtr() || PT.get().isNull()) { | ||||||
19078 | S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t"; | ||||||
19079 | return false; | ||||||
19080 | } | ||||||
19081 | Stack->setOMPAlloctraitT(PT.get()); | ||||||
19082 | return true; | ||||||
19083 | } | ||||||
19084 | |||||||
19085 | OMPClause *Sema::ActOnOpenMPUsesAllocatorClause( | ||||||
19086 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, | ||||||
19087 | ArrayRef<UsesAllocatorsData> Data) { | ||||||
19088 | // OpenMP [2.12.5, target Construct] | ||||||
19089 | // allocator is an identifier of omp_allocator_handle_t type. | ||||||
19090 | if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||
19091 | return nullptr; | ||||||
19092 | // OpenMP [2.12.5, target Construct] | ||||||
19093 | // allocator-traits-array is an identifier of const omp_alloctrait_t * type. | ||||||
19094 | if (llvm::any_of( | ||||||
19095 | Data, | ||||||
19096 | [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) && | ||||||
19097 | !findOMPAlloctraitT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) | ||||||
19098 | return nullptr; | ||||||
19099 | llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators; | ||||||
19100 | for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { | ||||||
19101 | auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); | ||||||
19102 | StringRef Allocator = | ||||||
19103 | OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); | ||||||
19104 | DeclarationName AllocatorName = &Context.Idents.get(Allocator); | ||||||
19105 | PredefinedAllocators.insert(LookupSingleName( | ||||||
19106 | TUScope, AllocatorName, StartLoc, Sema::LookupAnyName)); | ||||||
19107 | } | ||||||
19108 | |||||||
19109 | SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData; | ||||||
19110 | for (const UsesAllocatorsData &D : Data) { | ||||||
19111 | Expr *AllocatorExpr = nullptr; | ||||||
19112 | // Check allocator expression. | ||||||
19113 | if (D.Allocator->isTypeDependent()) { | ||||||
19114 | AllocatorExpr = D.Allocator; | ||||||
19115 | } else { | ||||||
19116 | // Traits were specified - need to assign new allocator to the specified | ||||||
19117 | // allocator, so it must be an lvalue. | ||||||
19118 | AllocatorExpr = D.Allocator->IgnoreParenImpCasts(); | ||||||
19119 | auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr); | ||||||
19120 | bool IsPredefinedAllocator = false; | ||||||
19121 | if (DRE) | ||||||
19122 | IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl()); | ||||||
19123 | if (!DRE || | ||||||
19124 | !(Context.hasSameUnqualifiedType( | ||||||
19125 | AllocatorExpr->getType(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPAllocatorHandleT()) || | ||||||
19126 | Context.typesAreCompatible(AllocatorExpr->getType(), | ||||||
19127 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPAllocatorHandleT(), | ||||||
19128 | /*CompareUnqualified=*/true)) || | ||||||
19129 | (!IsPredefinedAllocator && | ||||||
19130 | (AllocatorExpr->getType().isConstant(Context) || | ||||||
19131 | !AllocatorExpr->isLValue()))) { | ||||||
19132 | Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected) | ||||||
19133 | << "omp_allocator_handle_t" << (DRE ? 1 : 0) | ||||||
19134 | << AllocatorExpr->getType() << D.Allocator->getSourceRange(); | ||||||
19135 | continue; | ||||||
19136 | } | ||||||
19137 | // OpenMP [2.12.5, target Construct] | ||||||
19138 | // Predefined allocators appearing in a uses_allocators clause cannot have | ||||||
19139 | // traits specified. | ||||||
19140 | if (IsPredefinedAllocator && D.AllocatorTraits) { | ||||||
19141 | Diag(D.AllocatorTraits->getExprLoc(), | ||||||
19142 | diag::err_omp_predefined_allocator_with_traits) | ||||||
19143 | << D.AllocatorTraits->getSourceRange(); | ||||||
19144 | Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator) | ||||||
19145 | << cast<NamedDecl>(DRE->getDecl())->getName() | ||||||
19146 | << D.Allocator->getSourceRange(); | ||||||
19147 | continue; | ||||||
19148 | } | ||||||
19149 | // OpenMP [2.12.5, target Construct] | ||||||
19150 | // Non-predefined allocators appearing in a uses_allocators clause must | ||||||
19151 | // have traits specified. | ||||||
19152 | if (!IsPredefinedAllocator && !D.AllocatorTraits) { | ||||||
19153 | Diag(D.Allocator->getExprLoc(), | ||||||
19154 | diag::err_omp_nonpredefined_allocator_without_traits); | ||||||
19155 | continue; | ||||||
19156 | } | ||||||
19157 | // No allocator traits - just convert it to rvalue. | ||||||
19158 | if (!D.AllocatorTraits) | ||||||
19159 | AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get(); | ||||||
19160 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addUsesAllocatorsDecl( | ||||||
19161 | DRE->getDecl(), | ||||||
19162 | IsPredefinedAllocator | ||||||
19163 | ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator | ||||||
19164 | : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator); | ||||||
19165 | } | ||||||
19166 | Expr *AllocatorTraitsExpr = nullptr; | ||||||
19167 | if (D.AllocatorTraits) { | ||||||
19168 | if (D.AllocatorTraits->isTypeDependent()) { | ||||||
19169 | AllocatorTraitsExpr = D.AllocatorTraits; | ||||||
19170 | } else { | ||||||
19171 | // OpenMP [2.12.5, target Construct] | ||||||
19172 | // Arrays that contain allocator traits that appear in a uses_allocators | ||||||
19173 | // clause must be constant arrays, have constant values and be defined | ||||||
19174 | // in the same scope as the construct in which the clause appears. | ||||||
19175 | AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts(); | ||||||
19176 | // Check that traits expr is a constant array. | ||||||
19177 | QualType TraitTy; | ||||||
19178 | if (const ArrayType *Ty = | ||||||
19179 | AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe()) | ||||||
19180 | if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty)) | ||||||
19181 | TraitTy = ConstArrayTy->getElementType(); | ||||||
19182 | if (TraitTy.isNull() || | ||||||
19183 | !(Context.hasSameUnqualifiedType(TraitTy, | ||||||
19184 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPAlloctraitT()) || | ||||||
19185 | Context.typesAreCompatible(TraitTy, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPAlloctraitT(), | ||||||
19186 | /*CompareUnqualified=*/true))) { | ||||||
19187 | Diag(D.AllocatorTraits->getExprLoc(), | ||||||
19188 | diag::err_omp_expected_array_alloctraits) | ||||||
19189 | << AllocatorTraitsExpr->getType(); | ||||||
19190 | continue; | ||||||
19191 | } | ||||||
19192 | // Do not map by default allocator traits if it is a standalone | ||||||
19193 | // variable. | ||||||
19194 | if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr)) | ||||||
19195 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addUsesAllocatorsDecl( | ||||||
19196 | DRE->getDecl(), | ||||||
19197 | DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait); | ||||||
19198 | } | ||||||
19199 | } | ||||||
19200 | OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back(); | ||||||
19201 | NewD.Allocator = AllocatorExpr; | ||||||
19202 | NewD.AllocatorTraits = AllocatorTraitsExpr; | ||||||
19203 | NewD.LParenLoc = D.LParenLoc; | ||||||
19204 | NewD.RParenLoc = D.RParenLoc; | ||||||
19205 | } | ||||||
19206 | return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc, | ||||||
19207 | NewData); | ||||||
19208 | } | ||||||
19209 | |||||||
19210 | OMPClause *Sema::ActOnOpenMPAffinityClause( | ||||||
19211 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, | ||||||
19212 | SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) { | ||||||
19213 | SmallVector<Expr *, 8> Vars; | ||||||
19214 | for (Expr *RefExpr : Locators) { | ||||||
19215 | 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~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 19215, __PRETTY_FUNCTION__)); | ||||||
19216 | if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) { | ||||||
19217 | // It will be analyzed later. | ||||||
19218 | Vars.push_back(RefExpr); | ||||||
19219 | continue; | ||||||
19220 | } | ||||||
19221 | |||||||
19222 | SourceLocation ELoc = RefExpr->getExprLoc(); | ||||||
19223 | Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts(); | ||||||
19224 | |||||||
19225 | if (!SimpleExpr->isLValue()) { | ||||||
19226 | Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) | ||||||
19227 | << 1 << 0 << RefExpr->getSourceRange(); | ||||||
19228 | continue; | ||||||
19229 | } | ||||||
19230 | |||||||
19231 | ExprResult Res; | ||||||
19232 | { | ||||||
19233 | Sema::TentativeAnalysisScope Trap(*this); | ||||||
19234 | Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr); | ||||||
19235 | } | ||||||
19236 | if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && | ||||||
19237 | !isa<OMPArrayShapingExpr>(SimpleExpr)) { | ||||||
19238 | Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) | ||||||
19239 | << 1 << 0 << RefExpr->getSourceRange(); | ||||||
19240 | continue; | ||||||
19241 | } | ||||||
19242 | Vars.push_back(SimpleExpr); | ||||||
19243 | } | ||||||
19244 | |||||||
19245 | return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc, | ||||||
19246 | EndLoc, Modifier, Vars); | ||||||
19247 | } |
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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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::storage_type> FpPragmaStack; |
591 | FPOptionsOverride CurFPFeatureOverrides() { |
592 | FPOptionsOverride result; |
593 | if (!FpPragmaStack.hasValue()) { |
594 | result = FPOptionsOverride(); |
595 | } else { |
596 | result = FPOptionsOverride(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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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::storage_type getOverrides() { return OldOverrides; } |
1409 | |
1410 | private: |
1411 | Sema& S; |
1412 | FPOptions OldFPFeaturesState; |
1413 | FPOptionsOverride::storage_type 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~++20200806111125+5446ec85070/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 | /// Determine whether a declaration is visible to name lookup. |
1916 | bool isVisible(const NamedDecl *D) { |
1917 | return D->isUnconditionallyVisible() || isVisibleSlow(D); |
1918 | } |
1919 | |
1920 | /// Determine whether any declaration of an entity is visible. |
1921 | bool |
1922 | hasVisibleDeclaration(const NamedDecl *D, |
1923 | llvm::SmallVectorImpl<Module *> *Modules = nullptr) { |
1924 | return isVisible(D) || hasVisibleDeclarationSlow(D, Modules); |
1925 | } |
1926 | bool hasVisibleDeclarationSlow(const NamedDecl *D, |
1927 | llvm::SmallVectorImpl<Module *> *Modules); |
1928 | |
1929 | bool hasVisibleMergedDefinition(NamedDecl *Def); |
1930 | bool hasMergedDefinitionInCurrentModule(NamedDecl *Def); |
1931 | |
1932 | /// Determine if \p D and \p Suggested have a structurally compatible |
1933 | /// layout as described in C11 6.2.7/1. |
1934 | bool hasStructuralCompatLayout(Decl *D, Decl *Suggested); |
1935 | |
1936 | /// Determine if \p D has a visible definition. If not, suggest a declaration |
1937 | /// that should be made visible to expose the definition. |
1938 | bool hasVisibleDefinition(NamedDecl *D, NamedDecl **Suggested, |
1939 | bool OnlyNeedComplete = false); |
1940 | bool hasVisibleDefinition(const NamedDecl *D) { |
1941 | NamedDecl *Hidden; |
1942 | return hasVisibleDefinition(const_cast<NamedDecl*>(D), &Hidden); |
1943 | } |
1944 | |
1945 | /// Determine if the template parameter \p D has a visible default argument. |
1946 | bool |
1947 | hasVisibleDefaultArgument(const NamedDecl *D, |
1948 | llvm::SmallVectorImpl<Module *> *Modules = nullptr); |
1949 | |
1950 | /// Determine if there is a visible declaration of \p D that is an explicit |
1951 | /// specialization declaration for a specialization of a template. (For a |
1952 | /// member specialization, use hasVisibleMemberSpecialization.) |
1953 | bool hasVisibleExplicitSpecialization( |
1954 | const NamedDecl *D, llvm::SmallVectorImpl<Module *> *Modules = nullptr); |
1955 | |
1956 | /// Determine if there is a visible declaration of \p D that is a member |
1957 | /// specialization declaration (as opposed to an instantiated declaration). |
1958 | bool hasVisibleMemberSpecialization( |
1959 | const NamedDecl *D, llvm::SmallVectorImpl<Module *> *Modules = nullptr); |
1960 | |
1961 | /// Determine if \p A and \p B are equivalent internal linkage declarations |
1962 | /// from different modules, and thus an ambiguity error can be downgraded to |
1963 | /// an extension warning. |
1964 | bool isEquivalentInternalLinkageDeclaration(const NamedDecl *A, |
1965 | const NamedDecl *B); |
1966 | void diagnoseEquivalentInternalLinkageDeclarations( |
1967 | SourceLocation Loc, const NamedDecl *D, |
1968 | ArrayRef<const NamedDecl *> Equiv); |
1969 | |
1970 | bool isUsualDeallocationFunction(const CXXMethodDecl *FD); |
1971 | |
1972 | bool isCompleteType(SourceLocation Loc, QualType T, |
1973 | CompleteTypeKind Kind = CompleteTypeKind::Default) { |
1974 | return !RequireCompleteTypeImpl(Loc, T, Kind, nullptr); |
1975 | } |
1976 | bool RequireCompleteType(SourceLocation Loc, QualType T, |
1977 | CompleteTypeKind Kind, TypeDiagnoser &Diagnoser); |
1978 | bool RequireCompleteType(SourceLocation Loc, QualType T, |
1979 | CompleteTypeKind Kind, unsigned DiagID); |
1980 | |
1981 | bool RequireCompleteType(SourceLocation Loc, QualType T, |
1982 | TypeDiagnoser &Diagnoser) { |
1983 | return RequireCompleteType(Loc, T, CompleteTypeKind::Default, Diagnoser); |
1984 | } |
1985 | bool RequireCompleteType(SourceLocation Loc, QualType T, unsigned DiagID) { |
1986 | return RequireCompleteType(Loc, T, CompleteTypeKind::Default, DiagID); |
1987 | } |
1988 | |
1989 | template <typename... Ts> |
1990 | bool RequireCompleteType(SourceLocation Loc, QualType T, unsigned DiagID, |
1991 | const Ts &...Args) { |
1992 | BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...); |
1993 | return RequireCompleteType(Loc, T, Diagnoser); |
1994 | } |
1995 | |
1996 | template <typename... Ts> |
1997 | bool RequireCompleteSizedType(SourceLocation Loc, QualType T, unsigned DiagID, |
1998 | const Ts &... Args) { |
1999 | SizelessTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...); |
2000 | CompleteTypeKind Kind = CompleteTypeKind::Normal; |
2001 | if (T->isVLST()) |
2002 | Kind = CompleteTypeKind::AcceptSizeless; |
2003 | return RequireCompleteType(Loc, T, Kind, Diagnoser); |
2004 | } |
2005 | |
2006 | void completeExprArrayBound(Expr *E); |
2007 | bool RequireCompleteExprType(Expr *E, CompleteTypeKind Kind, |
2008 | TypeDiagnoser &Diagnoser); |
2009 | bool RequireCompleteExprType(Expr *E, unsigned DiagID); |
2010 | |
2011 | template <typename... Ts> |
2012 | bool RequireCompleteExprType(Expr *E, unsigned DiagID, const Ts &...Args) { |
2013 | BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...); |
2014 | return RequireCompleteExprType(E, CompleteTypeKind::Default, Diagnoser); |
2015 | } |
2016 | |
2017 | template <typename... Ts> |
2018 | bool RequireCompleteSizedExprType(Expr *E, unsigned DiagID, |
2019 | const Ts &... Args) { |
2020 | SizelessTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...); |
2021 | CompleteTypeKind Kind = CompleteTypeKind::Normal; |
2022 | if (E->getType()->isVLST()) |
2023 | Kind = CompleteTypeKind::AcceptSizeless; |
2024 | return RequireCompleteExprType(E, Kind, 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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/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_NewExpr, ///< Constant expression in a noptr-new-declarator. |
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 CreateOverloadedUnaryOp(SourceLocation OpLoc, |
3560 | UnaryOperatorKind Opc, |
3561 | const UnresolvedSetImpl &Fns, |
3562 | Expr *input, bool RequiresADL = true); |
3563 | |
3564 | void LookupOverloadedBinOp(OverloadCandidateSet &CandidateSet, |
3565 | OverloadedOperatorKind Op, |
3566 | const UnresolvedSetImpl &Fns, |
3567 | ArrayRef<Expr *> Args, bool RequiresADL = true); |
3568 | ExprResult CreateOverloadedBinOp(SourceLocation OpLoc, |
3569 | BinaryOperatorKind Opc, |
3570 | const UnresolvedSetImpl &Fns, |
3571 | Expr *LHS, Expr *RHS, |
3572 | bool RequiresADL = true, |
3573 | bool AllowRewrittenCandidates = true, |
3574 | FunctionDecl *DefaultedFn = nullptr); |
3575 | ExprResult BuildSynthesizedThreeWayComparison(SourceLocation OpLoc, |
3576 | const UnresolvedSetImpl &Fns, |
3577 | Expr *LHS, Expr *RHS, |
3578 | FunctionDecl *DefaultedFn); |
3579 | |
3580 | ExprResult CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, |
3581 | SourceLocation RLoc, |
3582 | Expr *Base,Expr *Idx); |
3583 | |
3584 | ExprResult |
3585 | BuildCallToMemberFunction(Scope *S, Expr *MemExpr, |
3586 | SourceLocation LParenLoc, |
3587 | MultiExprArg Args, |
3588 | SourceLocation RParenLoc); |
3589 | ExprResult |
3590 | BuildCallToObjectOfClassType(Scope *S, Expr *Object, SourceLocation LParenLoc, |
3591 | MultiExprArg Args, |
3592 | SourceLocation RParenLoc); |
3593 | |
3594 | ExprResult BuildOverloadedArrowExpr(Scope *S, Expr *Base, |
3595 | SourceLocation OpLoc, |
3596 | bool *NoArrowOperatorFound = nullptr); |
3597 | |
3598 | /// CheckCallReturnType - Checks that a call expression's return type is |
3599 | /// complete. Returns true on failure. The location passed in is the location |
3600 | /// that best represents the call. |
3601 | bool CheckCallReturnType(QualType ReturnType, SourceLocation Loc, |
3602 | CallExpr *CE, FunctionDecl *FD); |
3603 | |
3604 | /// Helpers for dealing with blocks and functions. |
3605 | bool CheckParmsForFunctionDef(ArrayRef<ParmVarDecl *> Parameters, |
3606 | bool CheckParameterNames); |
3607 | void CheckCXXDefaultArguments(FunctionDecl *FD); |
3608 | void CheckExtraCXXDefaultArguments(Declarator &D); |
3609 | Scope *getNonFieldDeclScope(Scope *S); |
3610 | |
3611 | /// \name Name lookup |
3612 | /// |
3613 | /// These routines provide name lookup that is used during semantic |
3614 | /// analysis to resolve the various kinds of names (identifiers, |
3615 | /// overloaded operator names, constructor names, etc.) into zero or |
3616 | /// more declarations within a particular scope. The major entry |
3617 | /// points are LookupName, which performs unqualified name lookup, |
3618 | /// and LookupQualifiedName, which performs qualified name lookup. |
3619 | /// |
3620 | /// All name lookup is performed based on some specific criteria, |
3621 | /// which specify what names will be visible to name lookup and how |
3622 | /// far name lookup should work. These criteria are important both |
3623 | /// for capturing language semantics (certain lookups will ignore |
3624 | /// certain names, for example) and for performance, since name |
3625 | /// lookup is often a bottleneck in the compilation of C++. Name |
3626 | /// lookup criteria is specified via the LookupCriteria enumeration. |
3627 | /// |
3628 | /// The results of name lookup can vary based on the kind of name |
3629 | /// lookup performed, the current language, and the translation |
3630 | /// unit. In C, for example, name lookup will either return nothing |
3631 | /// (no entity found) or a single declaration. In C++, name lookup |
3632 | /// can additionally refer to a set of overloaded functions or |
3633 | /// result in an ambiguity. All of the possible results of name |
3634 | /// lookup are captured by the LookupResult class, which provides |
3635 | /// the ability to distinguish among them. |
3636 | //@{ |
3637 | |
3638 | /// Describes the kind of name lookup to perform. |
3639 | enum LookupNameKind { |
3640 | /// Ordinary name lookup, which finds ordinary names (functions, |
3641 | /// variables, typedefs, etc.) in C and most kinds of names |
3642 | /// (functions, variables, members, types, etc.) in C++. |
3643 | LookupOrdinaryName = 0, |
3644 | /// Tag name lookup, which finds the names of enums, classes, |
3645 | /// structs, and unions. |
3646 | LookupTagName, |
3647 | /// Label name lookup. |
3648 | LookupLabel, |
3649 | /// Member name lookup, which finds the names of |
3650 | /// class/struct/union members. |
3651 | LookupMemberName, |
3652 | /// Look up of an operator name (e.g., operator+) for use with |
3653 | /// operator overloading. This lookup is similar to ordinary name |
3654 | /// lookup, but will ignore any declarations that are class members. |
3655 | LookupOperatorName, |
3656 | /// Look up a name following ~ in a destructor name. This is an ordinary |
3657 | /// lookup, but prefers tags to typedefs. |
3658 | LookupDestructorName, |
3659 | /// Look up of a name that precedes the '::' scope resolution |
3660 | /// operator in C++. This lookup completely ignores operator, object, |
3661 | /// function, and enumerator names (C++ [basic.lookup.qual]p1). |
3662 | LookupNestedNameSpecifierName, |
3663 | /// Look up a namespace name within a C++ using directive or |
3664 | /// namespace alias definition, ignoring non-namespace names (C++ |
3665 | /// [basic.lookup.udir]p1). |
3666 | LookupNamespaceName, |
3667 | /// Look up all declarations in a scope with the given name, |
3668 | /// including resolved using declarations. This is appropriate |
3669 | /// for checking redeclarations for a using declaration. |
3670 | LookupUsingDeclName, |
3671 | /// Look up an ordinary name that is going to be redeclared as a |
3672 | /// name with linkage. This lookup ignores any declarations that |
3673 | /// are outside of the current scope unless they have linkage. See |
3674 | /// C99 6.2.2p4-5 and C++ [basic.link]p6. |
3675 | LookupRedeclarationWithLinkage, |
3676 | /// Look up a friend of a local class. This lookup does not look |
3677 | /// outside the innermost non-class scope. See C++11 [class.friend]p11. |
3678 | LookupLocalFriendName, |
3679 | /// Look up the name of an Objective-C protocol. |
3680 | LookupObjCProtocolName, |
3681 | /// Look up implicit 'self' parameter of an objective-c method. |
3682 | LookupObjCImplicitSelfParam, |
3683 | /// Look up the name of an OpenMP user-defined reduction operation. |
3684 | LookupOMPReductionName, |
3685 | /// Look up the name of an OpenMP user-defined mapper. |
3686 | LookupOMPMapperName, |
3687 | /// Look up any declaration with any name. |
3688 | LookupAnyName |
3689 | }; |
3690 | |
3691 | /// Specifies whether (or how) name lookup is being performed for a |
3692 | /// redeclaration (vs. a reference). |
3693 | enum RedeclarationKind { |
3694 | /// The lookup is a reference to this name that is not for the |
3695 | /// purpose of redeclaring the name. |
3696 | NotForRedeclaration = 0, |
3697 | /// The lookup results will be used for redeclaration of a name, |
3698 | /// if an entity by that name already exists and is visible. |
3699 | ForVisibleRedeclaration, |
3700 | /// The lookup results will be used for redeclaration of a name |
3701 | /// with external linkage; non-visible lookup results with external linkage |
3702 | /// may also be found. |
3703 | ForExternalRedeclaration |
3704 | }; |
3705 | |
3706 | RedeclarationKind forRedeclarationInCurContext() { |
3707 | // A declaration with an owning module for linkage can never link against |
3708 | // anything that is not visible. We don't need to check linkage here; if |
3709 | // the context has internal linkage, redeclaration lookup won't find things |
3710 | // from other TUs, and we can't safely compute linkage yet in general. |
3711 | if (cast<Decl>(CurContext) |
3712 | ->getOwningModuleForLinkage(/*IgnoreLinkage*/true)) |
3713 | return ForVisibleRedeclaration; |
3714 | return ForExternalRedeclaration; |
3715 | } |
3716 | |
3717 | /// The possible outcomes of name lookup for a literal operator. |
3718 | enum LiteralOperatorLookupResult { |
3719 | /// The lookup resulted in an error. |
3720 | LOLR_Error, |
3721 | /// The lookup found no match but no diagnostic was issued. |
3722 | LOLR_ErrorNoDiagnostic, |
3723 | /// The lookup found a single 'cooked' literal operator, which |
3724 | /// expects a normal literal to be built and passed to it. |
3725 | LOLR_Cooked, |
3726 | /// The lookup found a single 'raw' literal operator, which expects |
3727 | /// a string literal containing the spelling of the literal token. |
3728 | LOLR_Raw, |
3729 | /// The lookup found an overload set of literal operator templates, |
3730 | /// which expect the characters of the spelling of the literal token to be |
3731 | /// passed as a non-type template argument pack. |
3732 | LOLR_Template, |
3733 | /// The lookup found an overload set of literal operator templates, |
3734 | /// which expect the character type and characters of the spelling of the |
3735 | /// string literal token to be passed as template arguments. |
3736 | LOLR_StringTemplate |
3737 | }; |
3738 | |
3739 | SpecialMemberOverloadResult LookupSpecialMember(CXXRecordDecl *D, |
3740 | CXXSpecialMember SM, |
3741 | bool ConstArg, |
3742 | bool VolatileArg, |
3743 | bool RValueThis, |
3744 | bool ConstThis, |
3745 | bool VolatileThis); |
3746 | |
3747 | typedef std::function<void(const TypoCorrection &)> TypoDiagnosticGenerator; |
3748 | typedef std::function<ExprResult(Sema &, TypoExpr *, TypoCorrection)> |
3749 | TypoRecoveryCallback; |
3750 | |
3751 | private: |
3752 | bool CppLookupName(LookupResult &R, Scope *S); |
3753 | |
3754 | struct TypoExprState { |
3755 | std::unique_ptr<TypoCorrectionConsumer> Consumer; |
3756 | TypoDiagnosticGenerator DiagHandler; |
3757 | TypoRecoveryCallback RecoveryHandler; |
3758 | TypoExprState(); |
3759 | TypoExprState(TypoExprState &&other) noexcept; |
3760 | TypoExprState &operator=(TypoExprState &&other) noexcept; |
3761 | }; |
3762 | |
3763 | /// The set of unhandled TypoExprs and their associated state. |
3764 | llvm::MapVector<TypoExpr *, TypoExprState> DelayedTypos; |
3765 | |
3766 | /// Creates a new TypoExpr AST node. |
3767 | TypoExpr *createDelayedTypo(std::unique_ptr<TypoCorrectionConsumer> TCC, |
3768 | TypoDiagnosticGenerator TDG, |
3769 | TypoRecoveryCallback TRC, SourceLocation TypoLoc); |
3770 | |
3771 | // The set of known/encountered (unique, canonicalized) NamespaceDecls. |
3772 | // |
3773 | // The boolean value will be true to indicate that the namespace was loaded |
3774 | // from an AST/PCH file, or false otherwise. |
3775 | llvm::MapVector<NamespaceDecl*, bool> KnownNamespaces; |
3776 | |
3777 | /// Whether we have already loaded known namespaces from an extenal |
3778 | /// source. |
3779 | bool LoadedExternalKnownNamespaces; |
3780 | |
3781 | /// Helper for CorrectTypo and CorrectTypoDelayed used to create and |
3782 | /// populate a new TypoCorrectionConsumer. Returns nullptr if typo correction |
3783 | /// should be skipped entirely. |
3784 | std::unique_ptr<TypoCorrectionConsumer> |
3785 | makeTypoCorrectionConsumer(const DeclarationNameInfo &Typo, |
3786 | Sema::LookupNameKind LookupKind, Scope *S, |
3787 | CXXScopeSpec *SS, |
3788 | CorrectionCandidateCallback &CCC, |
3789 | DeclContext *MemberContext, bool EnteringContext, |
3790 | const ObjCObjectPointerType *OPT, |
3791 | bool ErrorRecovery); |
3792 | |
3793 | public: |
3794 | const TypoExprState &getTypoExprState(TypoExpr *TE) const; |
3795 | |
3796 | /// Clears the state of the given TypoExpr. |
3797 | void clearDelayedTypo(TypoExpr *TE); |
3798 | |
3799 | /// Look up a name, looking for a single declaration. Return |
3800 | /// null if the results were absent, ambiguous, or overloaded. |
3801 | /// |
3802 | /// It is preferable to use the elaborated form and explicitly handle |
3803 | /// ambiguity and overloaded. |
3804 | NamedDecl *LookupSingleName(Scope *S, DeclarationName Name, |
3805 | SourceLocation Loc, |
3806 | LookupNameKind NameKind, |
3807 | RedeclarationKind Redecl |
3808 | = NotForRedeclaration); |
3809 | bool LookupBuiltin(LookupResult &R); |
3810 | bool LookupName(LookupResult &R, Scope *S, |
3811 | bool AllowBuiltinCreation = false); |
3812 | bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, |
3813 | bool InUnqualifiedLookup = false); |
3814 | bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, |
3815 | CXXScopeSpec &SS); |
3816 | bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, |
3817 | bool AllowBuiltinCreation = false, |
3818 | bool EnteringContext = false); |
3819 | ObjCProtocolDecl *LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc, |
3820 | RedeclarationKind Redecl |
3821 | = NotForRedeclaration); |
3822 | bool LookupInSuper(LookupResult &R, CXXRecordDecl *Class); |
3823 | |
3824 | void LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S, |
3825 | QualType T1, QualType T2, |
3826 | UnresolvedSetImpl &Functions); |
3827 | |
3828 | LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc, |
3829 | SourceLocation GnuLabelLoc = SourceLocation()); |
3830 | |
3831 | DeclContextLookupResult LookupConstructors(CXXRecordDecl *Class); |
3832 | CXXConstructorDecl *LookupDefaultConstructor(CXXRecordDecl *Class); |
3833 | CXXConstructorDecl *LookupCopyingConstructor(CXXRecordDecl *Class, |
3834 | unsigned Quals); |
3835 | CXXMethodDecl *LookupCopyingAssignment(CXXRecordDecl *Class, unsigned Quals, |
3836 | bool RValueThis, unsigned ThisQuals); |
3837 | CXXConstructorDecl *LookupMovingConstructor(CXXRecordDecl *Class, |
3838 | unsigned Quals); |
3839 | CXXMethodDecl *LookupMovingAssignment(CXXRecordDecl *Class, unsigned Quals, |
3840 | bool RValueThis, unsigned ThisQuals); |
3841 | CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class); |
3842 | |
3843 | bool checkLiteralOperatorId(const CXXScopeSpec &SS, const UnqualifiedId &Id); |
3844 | LiteralOperatorLookupResult LookupLiteralOperator(Scope *S, LookupResult &R, |
3845 | ArrayRef<QualType> ArgTys, |
3846 | bool AllowRaw, |
3847 | bool AllowTemplate, |
3848 | bool AllowStringTemplate, |
3849 | bool DiagnoseMissing); |
3850 | bool isKnownName(StringRef name); |
3851 | |
3852 | /// Status of the function emission on the CUDA/HIP/OpenMP host/device attrs. |
3853 | enum class FunctionEmissionStatus { |
3854 | Emitted, |
3855 | CUDADiscarded, // Discarded due to CUDA/HIP hostness |
3856 | OMPDiscarded, // Discarded due to OpenMP hostness |
3857 | TemplateDiscarded, // Discarded due to uninstantiated templates |
3858 | Unknown, |
3859 | }; |
3860 | FunctionEmissionStatus getEmissionStatus(FunctionDecl *Decl, |
3861 | bool Final = false); |
3862 | |
3863 | // Whether the callee should be ignored in CUDA/HIP/OpenMP host/device check. |
3864 | bool shouldIgnoreInHostDeviceCheck(FunctionDecl *Callee); |
3865 | |
3866 | void ArgumentDependentLookup(DeclarationName Name, SourceLocation Loc, |
3867 | ArrayRef<Expr *> Args, ADLResult &Functions); |
3868 | |
3869 | void LookupVisibleDecls(Scope *S, LookupNameKind Kind, |
3870 | VisibleDeclConsumer &Consumer, |
3871 | bool IncludeGlobalScope = true, |
3872 | bool LoadExternal = true); |
3873 | void LookupVisibleDecls(DeclContext *Ctx, LookupNameKind Kind, |
3874 | VisibleDeclConsumer &Consumer, |
3875 | bool IncludeGlobalScope = true, |
3876 | bool IncludeDependentBases = false, |
3877 | bool LoadExternal = true); |
3878 | |
3879 | enum CorrectTypoKind { |
3880 | CTK_NonError, // CorrectTypo used in a non error recovery situation. |
3881 | CTK_ErrorRecovery // CorrectTypo used in normal error recovery. |
3882 | }; |
3883 | |
3884 | TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, |
3885 | Sema::LookupNameKind LookupKind, |
3886 | Scope *S, CXXScopeSpec *SS, |
3887 | CorrectionCandidateCallback &CCC, |
3888 | CorrectTypoKind Mode, |
3889 | DeclContext *MemberContext = nullptr, |
3890 | bool EnteringContext = false, |
3891 | const ObjCObjectPointerType *OPT = nullptr, |
3892 | bool RecordFailure = true); |
3893 | |
3894 | TypoExpr *CorrectTypoDelayed(const DeclarationNameInfo &Typo, |
3895 | Sema::LookupNameKind LookupKind, Scope *S, |
3896 | CXXScopeSpec *SS, |
3897 | CorrectionCandidateCallback &CCC, |
3898 | TypoDiagnosticGenerator TDG, |
3899 | TypoRecoveryCallback TRC, CorrectTypoKind Mode, |
3900 | DeclContext *MemberContext = nullptr, |
3901 | bool EnteringContext = false, |
3902 | const ObjCObjectPointerType *OPT = nullptr); |
3903 | |
3904 | /// Process any TypoExprs in the given Expr and its children, |
3905 | /// generating diagnostics as appropriate and returning a new Expr if there |
3906 | /// were typos that were all successfully corrected and ExprError if one or |
3907 | /// more typos could not be corrected. |
3908 | /// |
3909 | /// \param E The Expr to check for TypoExprs. |
3910 | /// |
3911 | /// \param InitDecl A VarDecl to avoid because the Expr being corrected is its |
3912 | /// initializer. |
3913 | /// |
3914 | /// \param RecoverUncorrectedTypos If true, when typo correction fails, it |
3915 | /// will rebuild the given Expr with all TypoExprs degraded to RecoveryExprs. |
3916 | /// |
3917 | /// \param Filter A function applied to a newly rebuilt Expr to determine if |
3918 | /// it is an acceptable/usable result from a single combination of typo |
3919 | /// corrections. As long as the filter returns ExprError, different |
3920 | /// combinations of corrections will be tried until all are exhausted. |
3921 | ExprResult CorrectDelayedTyposInExpr( |
3922 | Expr *E, VarDecl *InitDecl = nullptr, |
3923 | bool RecoverUncorrectedTypos = false, |
3924 | llvm::function_ref<ExprResult(Expr *)> Filter = |
3925 | [](Expr *E) -> ExprResult { return E; }); |
3926 | |
3927 | ExprResult CorrectDelayedTyposInExpr( |
3928 | ExprResult ER, VarDecl *InitDecl = nullptr, |
3929 | bool RecoverUncorrectedTypos = false, |
3930 | llvm::function_ref<ExprResult(Expr *)> Filter = |
3931 | [](Expr *E) -> ExprResult { return E; }) { |
3932 | return ER.isInvalid() |
3933 | ? ER |
3934 | : CorrectDelayedTyposInExpr(ER.get(), InitDecl, |
3935 | RecoverUncorrectedTypos, Filter); |
3936 | } |
3937 | |
3938 | void diagnoseTypo(const TypoCorrection &Correction, |
3939 | const PartialDiagnostic &TypoDiag, |
3940 | bool ErrorRecovery = true); |
3941 | |
3942 | void diagnoseTypo(const TypoCorrection &Correction, |
3943 | const PartialDiagnostic &TypoDiag, |
3944 | const PartialDiagnostic &PrevNote, |
3945 | bool ErrorRecovery = true); |
3946 | |
3947 | void MarkTypoCorrectedFunctionDefinition(const NamedDecl *F); |
3948 | |
3949 | void FindAssociatedClassesAndNamespaces(SourceLocation InstantiationLoc, |
3950 | ArrayRef<Expr *> Args, |
3951 | AssociatedNamespaceSet &AssociatedNamespaces, |
3952 | AssociatedClassSet &AssociatedClasses); |
3953 | |
3954 | void FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S, |
3955 | bool ConsiderLinkage, bool AllowInlineNamespace); |
3956 | |
3957 | bool CheckRedeclarationModuleOwnership(NamedDecl *New, NamedDecl *Old); |
3958 | |
3959 | void DiagnoseAmbiguousLookup(LookupResult &Result); |
3960 | //@} |
3961 | |
3962 | /// Attempts to produce a RecoveryExpr after some AST node cannot be created. |
3963 | ExprResult CreateRecoveryExpr(SourceLocation Begin, SourceLocation End, |
3964 | ArrayRef<Expr *> SubExprs, |
3965 | QualType T = QualType()); |
3966 | |
3967 | ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *&Id, |
3968 | SourceLocation IdLoc, |
3969 | bool TypoCorrection = false); |
3970 | NamedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID, |
3971 | Scope *S, bool ForRedeclaration, |
3972 | SourceLocation Loc); |
3973 | NamedDecl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II, |
3974 | Scope *S); |
3975 | void AddKnownFunctionAttributesForReplaceableGlobalAllocationFunction( |
3976 | FunctionDecl *FD); |
3977 | void AddKnownFunctionAttributes(FunctionDecl *FD); |
3978 | |
3979 | // More parsing and symbol table subroutines. |
3980 | |
3981 | void ProcessPragmaWeak(Scope *S, Decl *D); |
3982 | // Decl attributes - this routine is the top level dispatcher. |
3983 | void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD); |
3984 | // Helper for delayed processing of attributes. |
3985 | void ProcessDeclAttributeDelayed(Decl *D, |
3986 | const ParsedAttributesView &AttrList); |
3987 | void ProcessDeclAttributeList(Scope *S, Decl *D, const ParsedAttributesView &AL, |
3988 | bool IncludeCXX11Attributes = true); |
3989 | bool ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl, |
3990 | const ParsedAttributesView &AttrList); |
3991 | |
3992 | void checkUnusedDeclAttributes(Declarator &D); |
3993 | |
3994 | /// Determine if type T is a valid subject for a nonnull and similar |
3995 | /// attributes. By default, we look through references (the behavior used by |
3996 | /// nonnull), but if the second parameter is true, then we treat a reference |
3997 | /// type as valid. |
3998 | bool isValidPointerAttrType(QualType T, bool RefOkay = false); |
3999 | |
4000 | bool CheckRegparmAttr(const ParsedAttr &attr, unsigned &value); |
4001 | bool CheckCallingConvAttr(const ParsedAttr &attr, CallingConv &CC, |
4002 | const FunctionDecl *FD = nullptr); |
4003 | bool CheckAttrTarget(const ParsedAttr &CurrAttr); |
4004 | bool CheckAttrNoArgs(const ParsedAttr &CurrAttr); |
4005 | bool checkStringLiteralArgumentAttr(const ParsedAttr &Attr, unsigned ArgNum, |
4006 | StringRef &Str, |
4007 | SourceLocation *ArgLocation = nullptr); |
4008 | bool checkSectionName(SourceLocation LiteralLoc, StringRef Str); |
4009 | bool checkTargetAttr(SourceLocation LiteralLoc, StringRef Str); |
4010 | bool checkMSInheritanceAttrOnDefinition( |
4011 | CXXRecordDecl *RD, SourceRange Range, bool BestCase, |
4012 | MSInheritanceModel SemanticSpelling); |
4013 | |
4014 | void CheckAlignasUnderalignment(Decl *D); |
4015 | |
4016 | /// Adjust the calling convention of a method to be the ABI default if it |
4017 | /// wasn't specified explicitly. This handles method types formed from |
4018 | /// function type typedefs and typename template arguments. |
4019 | void adjustMemberFunctionCC(QualType &T, bool IsStatic, bool IsCtorOrDtor, |
4020 | SourceLocation Loc); |
4021 | |
4022 | // Check if there is an explicit attribute, but only look through parens. |
4023 | // The intent is to look for an attribute on the current declarator, but not |
4024 | // one that came from a typedef. |
4025 | bool hasExplicitCallingConv(QualType T); |
4026 | |
4027 | /// Get the outermost AttributedType node that sets a calling convention. |
4028 | /// Valid types should not have multiple attributes with different CCs. |
4029 | const AttributedType *getCallingConvAttributedType(QualType T) const; |
4030 | |
4031 | /// Stmt attributes - this routine is the top level dispatcher. |
4032 | StmtResult ProcessStmtAttributes(Stmt *Stmt, |
4033 | const ParsedAttributesView &Attrs, |
4034 | SourceRange Range); |
4035 | |
4036 | void WarnConflictingTypedMethods(ObjCMethodDecl *Method, |
4037 | ObjCMethodDecl *MethodDecl, |
4038 | bool IsProtocolMethodDecl); |
4039 | |
4040 | void CheckConflictingOverridingMethod(ObjCMethodDecl *Method, |
4041 | ObjCMethodDecl *Overridden, |
4042 | bool IsProtocolMethodDecl); |
4043 | |
4044 | /// WarnExactTypedMethods - This routine issues a warning if method |
4045 | /// implementation declaration matches exactly that of its declaration. |
4046 | void WarnExactTypedMethods(ObjCMethodDecl *Method, |
4047 | ObjCMethodDecl *MethodDecl, |
4048 | bool IsProtocolMethodDecl); |
4049 | |
4050 | typedef llvm::SmallPtrSet<Selector, 8> SelectorSet; |
4051 | |
4052 | /// CheckImplementationIvars - This routine checks if the instance variables |
4053 | /// listed in the implelementation match those listed in the interface. |
4054 | void CheckImplementationIvars(ObjCImplementationDecl *ImpDecl, |
4055 | ObjCIvarDecl **Fields, unsigned nIvars, |
4056 | SourceLocation Loc); |
4057 | |
4058 | /// ImplMethodsVsClassMethods - This is main routine to warn if any method |
4059 | /// remains unimplemented in the class or category \@implementation. |
4060 | void ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl, |
4061 | ObjCContainerDecl* IDecl, |
4062 | bool IncompleteImpl = false); |
4063 | |
4064 | /// DiagnoseUnimplementedProperties - This routine warns on those properties |
4065 | /// which must be implemented by this implementation. |
4066 | void DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl, |
4067 | ObjCContainerDecl *CDecl, |
4068 | bool SynthesizeProperties); |
4069 | |
4070 | /// Diagnose any null-resettable synthesized setters. |
4071 | void diagnoseNullResettableSynthesizedSetters(const ObjCImplDecl *impDecl); |
4072 | |
4073 | /// DefaultSynthesizeProperties - This routine default synthesizes all |
4074 | /// properties which must be synthesized in the class's \@implementation. |
4075 | void DefaultSynthesizeProperties(Scope *S, ObjCImplDecl *IMPDecl, |
4076 | ObjCInterfaceDecl *IDecl, |
4077 | SourceLocation AtEnd); |
4078 | void DefaultSynthesizeProperties(Scope *S, Decl *D, SourceLocation AtEnd); |
4079 | |
4080 | /// IvarBacksCurrentMethodAccessor - This routine returns 'true' if 'IV' is |
4081 | /// an ivar synthesized for 'Method' and 'Method' is a property accessor |
4082 | /// declared in class 'IFace'. |
4083 | bool IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace, |
4084 | ObjCMethodDecl *Method, ObjCIvarDecl *IV); |
4085 | |
4086 | /// DiagnoseUnusedBackingIvarInAccessor - Issue an 'unused' warning if ivar which |
4087 | /// backs the property is not used in the property's accessor. |
4088 | void DiagnoseUnusedBackingIvarInAccessor(Scope *S, |
4089 | const ObjCImplementationDecl *ImplD); |
4090 | |
4091 | /// GetIvarBackingPropertyAccessor - If method is a property setter/getter and |
4092 | /// it property has a backing ivar, returns this ivar; otherwise, returns NULL. |
4093 | /// It also returns ivar's property on success. |
4094 | ObjCIvarDecl *GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method, |
4095 | const ObjCPropertyDecl *&PDecl) const; |
4096 | |
4097 | /// Called by ActOnProperty to handle \@property declarations in |
4098 | /// class extensions. |
4099 | ObjCPropertyDecl *HandlePropertyInClassExtension(Scope *S, |
4100 | SourceLocation AtLoc, |
4101 | SourceLocation LParenLoc, |
4102 | FieldDeclarator &FD, |
4103 | Selector GetterSel, |
4104 | SourceLocation GetterNameLoc, |
4105 | Selector SetterSel, |
4106 | SourceLocation SetterNameLoc, |
4107 | const bool isReadWrite, |
4108 | unsigned &Attributes, |
4109 | const unsigned AttributesAsWritten, |
4110 | QualType T, |
4111 | TypeSourceInfo *TSI, |
4112 | tok::ObjCKeywordKind MethodImplKind); |
4113 | |
4114 | /// Called by ActOnProperty and HandlePropertyInClassExtension to |
4115 | /// handle creating the ObjcPropertyDecl for a category or \@interface. |
4116 | ObjCPropertyDecl *CreatePropertyDecl(Scope *S, |
4117 | ObjCContainerDecl *CDecl, |
4118 | SourceLocation AtLoc, |
4119 | SourceLocation LParenLoc, |
4120 | FieldDeclarator &FD, |
4121 | Selector GetterSel, |
4122 | SourceLocation GetterNameLoc, |
4123 | Selector SetterSel, |
4124 | SourceLocation SetterNameLoc, |
4125 | const bool isReadWrite, |
4126 | const unsigned Attributes, |
4127 | const unsigned AttributesAsWritten, |
4128 | QualType T, |
4129 | TypeSourceInfo *TSI, |
4130 | tok::ObjCKeywordKind MethodImplKind, |
4131 | DeclContext *lexicalDC = nullptr); |
4132 | |
4133 | /// AtomicPropertySetterGetterRules - This routine enforces the rule (via |
4134 | /// warning) when atomic property has one but not the other user-declared |
4135 | /// setter or getter. |
4136 | void AtomicPropertySetterGetterRules(ObjCImplDecl* IMPDecl, |
4137 | ObjCInterfaceDecl* IDecl); |
4138 | |
4139 | void DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D); |
4140 | |
4141 | void DiagnoseMissingDesignatedInitOverrides( |
4142 | const ObjCImplementationDecl *ImplD, |
4143 | const ObjCInterfaceDecl *IFD); |
4144 | |
4145 | void DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, ObjCInterfaceDecl *SID); |
4146 | |
4147 | enum MethodMatchStrategy { |
4148 | MMS_loose, |
4149 | MMS_strict |
4150 | }; |
4151 | |
4152 | /// MatchTwoMethodDeclarations - Checks if two methods' type match and returns |
4153 | /// true, or false, accordingly. |
4154 | bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method, |
4155 | const ObjCMethodDecl *PrevMethod, |
4156 | MethodMatchStrategy strategy = MMS_strict); |
4157 | |
4158 | /// MatchAllMethodDeclarations - Check methods declaraed in interface or |
4159 | /// or protocol against those declared in their implementations. |
4160 | void MatchAllMethodDeclarations(const SelectorSet &InsMap, |
4161 | const SelectorSet &ClsMap, |
4162 | SelectorSet &InsMapSeen, |
4163 | SelectorSet &ClsMapSeen, |
4164 | ObjCImplDecl* IMPDecl, |
4165 | ObjCContainerDecl* IDecl, |
4166 | bool &IncompleteImpl, |
4167 | bool ImmediateClass, |
4168 | bool WarnCategoryMethodImpl=false); |
4169 | |
4170 | /// CheckCategoryVsClassMethodMatches - Checks that methods implemented in |
4171 | /// category matches with those implemented in its primary class and |
4172 | /// warns each time an exact match is found. |
4173 | void CheckCategoryVsClassMethodMatches(ObjCCategoryImplDecl *CatIMP); |
4174 | |
4175 | /// Add the given method to the list of globally-known methods. |
4176 | void addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method); |
4177 | |
4178 | /// Returns default addr space for method qualifiers. |
4179 | LangAS getDefaultCXXMethodAddrSpace() const; |
4180 | |
4181 | private: |
4182 | /// AddMethodToGlobalPool - Add an instance or factory method to the global |
4183 | /// pool. See descriptoin of AddInstanceMethodToGlobalPool. |
4184 | void AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl, bool instance); |
4185 | |
4186 | /// LookupMethodInGlobalPool - Returns the instance or factory method and |
4187 | /// optionally warns if there are multiple signatures. |
4188 | ObjCMethodDecl *LookupMethodInGlobalPool(Selector Sel, SourceRange R, |
4189 | bool receiverIdOrClass, |
4190 | bool instance); |
4191 | |
4192 | public: |
4193 | /// - Returns instance or factory methods in global method pool for |
4194 | /// given selector. It checks the desired kind first, if none is found, and |
4195 | /// parameter checkTheOther is set, it then checks the other kind. If no such |
4196 | /// method or only one method is found, function returns false; otherwise, it |
4197 | /// returns true. |
4198 | bool |
4199 | CollectMultipleMethodsInGlobalPool(Selector Sel, |
4200 | SmallVectorImpl<ObjCMethodDecl*>& Methods, |
4201 | bool InstanceFirst, bool CheckTheOther, |
4202 | const ObjCObjectType *TypeBound = nullptr); |
4203 | |
4204 | bool |
4205 | AreMultipleMethodsInGlobalPool(Selector Sel, ObjCMethodDecl *BestMethod, |
4206 | SourceRange R, bool receiverIdOrClass, |
4207 | SmallVectorImpl<ObjCMethodDecl*>& Methods); |
4208 | |
4209 | void |
4210 | DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl<ObjCMethodDecl*> &Methods, |
4211 | Selector Sel, SourceRange R, |
4212 | bool receiverIdOrClass); |
4213 | |
4214 | private: |
4215 | /// - Returns a selector which best matches given argument list or |
4216 | /// nullptr if none could be found |
4217 | ObjCMethodDecl *SelectBestMethod(Selector Sel, MultiExprArg Args, |
4218 | bool IsInstance, |
4219 | SmallVectorImpl<ObjCMethodDecl*>& Methods); |
4220 | |
4221 | |
4222 | /// Record the typo correction failure and return an empty correction. |
4223 | TypoCorrection FailedCorrection(IdentifierInfo *Typo, SourceLocation TypoLoc, |
4224 | bool RecordFailure = true) { |
4225 | if (RecordFailure) |
4226 | TypoCorrectionFailures[Typo].insert(TypoLoc); |
4227 | return TypoCorrection(); |
4228 | } |
4229 | |
4230 | public: |
4231 | /// AddInstanceMethodToGlobalPool - All instance methods in a translation |
4232 | /// unit are added to a global pool. This allows us to efficiently associate |
4233 | /// a selector with a method declaraation for purposes of typechecking |
4234 | /// messages sent to "id" (where the class of the object is unknown). |
4235 | void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false) { |
4236 | AddMethodToGlobalPool(Method, impl, /*instance*/true); |
4237 | } |
4238 | |
4239 | /// AddFactoryMethodToGlobalPool - Same as above, but for factory methods. |
4240 | void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false) { |
4241 | AddMethodToGlobalPool(Method, impl, /*instance*/false); |
4242 | } |
4243 | |
4244 | /// AddAnyMethodToGlobalPool - Add any method, instance or factory to global |
4245 | /// pool. |
4246 | void AddAnyMethodToGlobalPool(Decl *D); |
4247 | |
4248 | /// LookupInstanceMethodInGlobalPool - Returns the method and warns if |
4249 | /// there are multiple signatures. |
4250 | ObjCMethodDecl *LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R, |
4251 | bool receiverIdOrClass=false) { |
4252 | return LookupMethodInGlobalPool(Sel, R, receiverIdOrClass, |
4253 | /*instance*/true); |
4254 | } |
4255 | |
4256 | /// LookupFactoryMethodInGlobalPool - Returns the method and warns if |
4257 | /// there are multiple signatures. |
4258 | ObjCMethodDecl *LookupFactoryMethodInGlobalPool(Selector Sel, SourceRange R, |
4259 | bool receiverIdOrClass=false) { |
4260 | return LookupMethodInGlobalPool(Sel, R, receiverIdOrClass, |
4261 | /*instance*/false); |
4262 | } |
4263 | |
4264 | const ObjCMethodDecl *SelectorsForTypoCorrection(Selector Sel, |
4265 | QualType ObjectType=QualType()); |
4266 | /// LookupImplementedMethodInGlobalPool - Returns the method which has an |
4267 | /// implementation. |
4268 | ObjCMethodDecl *LookupImplementedMethodInGlobalPool(Selector Sel); |
4269 | |
4270 | /// CollectIvarsToConstructOrDestruct - Collect those ivars which require |
4271 | /// initialization. |
4272 | void CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI, |
4273 | SmallVectorImpl<ObjCIvarDecl*> &Ivars); |
4274 | |
4275 | //===--------------------------------------------------------------------===// |
4276 | // Statement Parsing Callbacks: SemaStmt.cpp. |
4277 | public: |
4278 | class FullExprArg { |
4279 | public: |
4280 | FullExprArg() : E(nullptr) { } |
4281 | FullExprArg(Sema &actions) : E(nullptr) { } |
4282 | |
4283 | ExprResult release() { |
4284 | return E; |
4285 | } |
4286 | |
4287 | Expr *get() const { return E; } |
4288 | |
4289 | Expr *operator->() { |
4290 | return E; |
4291 | } |
4292 | |
4293 | private: |
4294 | // FIXME: No need to make the entire Sema class a friend when it's just |
4295 | // Sema::MakeFullExpr that needs access to the constructor below. |
4296 | friend class Sema; |
4297 | |
4298 | explicit FullExprArg(Expr *expr) : E(expr) {} |
4299 | |
4300 | Expr *E; |
4301 | }; |
4302 | |
4303 | FullExprArg MakeFullExpr(Expr *Arg) { |
4304 | return MakeFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation()); |
4305 | } |
4306 | FullExprArg MakeFullExpr(Expr *Arg, SourceLocation CC) { |
4307 | return FullExprArg( |
4308 | ActOnFinishFullExpr(Arg, CC, /*DiscardedValue*/ false).get()); |
4309 | } |
4310 | FullExprArg MakeFullDiscardedValueExpr(Expr *Arg) { |
4311 | ExprResult FE = |
4312 | ActOnFinishFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation(), |
4313 | /*DiscardedValue*/ true); |
4314 | return FullExprArg(FE.get()); |
4315 | } |
4316 | |
4317 | StmtResult ActOnExprStmt(ExprResult Arg, bool DiscardedValue = true); |
4318 | StmtResult ActOnExprStmtError(); |
4319 | |
4320 | StmtResult ActOnNullStmt(SourceLocation SemiLoc, |
4321 | bool HasLeadingEmptyMacro = false); |
4322 | |
4323 | void ActOnStartOfCompoundStmt(bool IsStmtExpr); |
4324 | void ActOnFinishOfCompoundStmt(); |
4325 | StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, |
4326 | ArrayRef<Stmt *> Elts, bool isStmtExpr); |
4327 | |
4328 | /// A RAII object to enter scope of a compound statement. |
4329 | class CompoundScopeRAII { |
4330 | public: |
4331 | CompoundScopeRAII(Sema &S, bool IsStmtExpr = false) : S(S) { |
4332 | S.ActOnStartOfCompoundStmt(IsStmtExpr); |
4333 | } |
4334 | |
4335 | ~CompoundScopeRAII() { |
4336 | S.ActOnFinishOfCompoundStmt(); |
4337 | } |
4338 | |
4339 | private: |
4340 | Sema &S; |
4341 | }; |
4342 | |
4343 | /// An RAII helper that pops function a function scope on exit. |
4344 | struct FunctionScopeRAII { |
4345 | Sema &S; |
4346 | bool Active; |
4347 | FunctionScopeRAII(Sema &S) : S(S), Active(true) {} |
4348 | ~FunctionScopeRAII() { |
4349 | if (Active) |
4350 | S.PopFunctionScopeInfo(); |
4351 | } |
4352 | void disable() { Active = false; } |
4353 | }; |
4354 | |
4355 | StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, |
4356 | SourceLocation StartLoc, |
4357 | SourceLocation EndLoc); |
4358 | void ActOnForEachDeclStmt(DeclGroupPtrTy Decl); |
4359 | StmtResult ActOnForEachLValueExpr(Expr *E); |
4360 | ExprResult ActOnCaseExpr(SourceLocation CaseLoc, ExprResult Val); |
4361 | StmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprResult LHS, |
4362 | SourceLocation DotDotDotLoc, ExprResult RHS, |
4363 | SourceLocation ColonLoc); |
4364 | void ActOnCaseStmtBody(Stmt *CaseStmt, Stmt *SubStmt); |
4365 | |
4366 | StmtResult ActOnDefaultStmt(SourceLocation DefaultLoc, |
4367 | SourceLocation ColonLoc, |
4368 | Stmt *SubStmt, Scope *CurScope); |
4369 | StmtResult ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl, |
4370 | SourceLocation ColonLoc, Stmt *SubStmt); |
4371 | |
4372 | StmtResult ActOnAttributedStmt(SourceLocation AttrLoc, |
4373 | ArrayRef<const Attr*> Attrs, |
4374 | Stmt *SubStmt); |
4375 | |
4376 | class ConditionResult; |
4377 | StmtResult ActOnIfStmt(SourceLocation IfLoc, bool IsConstexpr, |
4378 | Stmt *InitStmt, |
4379 | ConditionResult Cond, Stmt *ThenVal, |
4380 | SourceLocation ElseLoc, Stmt *ElseVal); |
4381 | StmtResult BuildIfStmt(SourceLocation IfLoc, bool IsConstexpr, |
4382 | Stmt *InitStmt, |
4383 | ConditionResult Cond, Stmt *ThenVal, |
4384 | SourceLocation ElseLoc, Stmt *ElseVal); |
4385 | StmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, |
4386 | Stmt *InitStmt, |
4387 | ConditionResult Cond); |
4388 | StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc, |
4389 | Stmt *Switch, Stmt *Body); |
4390 | StmtResult ActOnWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc, |
4391 | ConditionResult Cond, SourceLocation RParenLoc, |
4392 | Stmt *Body); |
4393 | StmtResult ActOnDoStmt(SourceLocation DoLoc, Stmt *Body, |
4394 | SourceLocation WhileLoc, SourceLocation CondLParen, |
4395 | Expr *Cond, SourceLocation CondRParen); |
4396 | |
4397 | StmtResult ActOnForStmt(SourceLocation ForLoc, |
4398 | SourceLocation LParenLoc, |
4399 | Stmt *First, |
4400 | ConditionResult Second, |
4401 | FullExprArg Third, |
4402 | SourceLocation RParenLoc, |
4403 | Stmt *Body); |
4404 | ExprResult CheckObjCForCollectionOperand(SourceLocation forLoc, |
4405 | Expr *collection); |
4406 | StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc, |
4407 | Stmt *First, Expr *collection, |
4408 | SourceLocation RParenLoc); |
4409 | StmtResult FinishObjCForCollectionStmt(Stmt *ForCollection, Stmt *Body); |
4410 | |
4411 | enum BuildForRangeKind { |
4412 | /// Initial building of a for-range statement. |
4413 | BFRK_Build, |
4414 | /// Instantiation or recovery rebuild of a for-range statement. Don't |
4415 | /// attempt any typo-correction. |
4416 | BFRK_Rebuild, |
4417 | /// Determining whether a for-range statement could be built. Avoid any |
4418 | /// unnecessary or irreversible actions. |
4419 | BFRK_Check |
4420 | }; |
4421 | |
4422 | StmtResult ActOnCXXForRangeStmt(Scope *S, SourceLocation ForLoc, |
4423 | SourceLocation CoawaitLoc, |
4424 | Stmt *InitStmt, |
4425 | Stmt *LoopVar, |
4426 | SourceLocation ColonLoc, Expr *Collection, |
4427 | SourceLocation RParenLoc, |
4428 | BuildForRangeKind Kind); |
4429 | StmtResult BuildCXXForRangeStmt(SourceLocation ForLoc, |
4430 | SourceLocation CoawaitLoc, |
4431 | Stmt *InitStmt, |
4432 | SourceLocation ColonLoc, |
4433 | Stmt *RangeDecl, Stmt *Begin, Stmt *End, |
4434 | Expr *Cond, Expr *Inc, |
4435 | Stmt *LoopVarDecl, |
4436 | SourceLocation RParenLoc, |
4437 | BuildForRangeKind Kind); |
4438 | StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body); |
4439 | |
4440 | StmtResult ActOnGotoStmt(SourceLocation GotoLoc, |
4441 | SourceLocation LabelLoc, |
4442 | LabelDecl *TheDecl); |
4443 | StmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc, |
4444 | SourceLocation StarLoc, |
4445 | Expr *DestExp); |
4446 | StmtResult ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope); |
4447 | StmtResult ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope); |
4448 | |
4449 | void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, |
4450 | CapturedRegionKind Kind, unsigned NumParams); |
4451 | typedef std::pair<StringRef, QualType> CapturedParamNameType; |
4452 | void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, |
4453 | CapturedRegionKind Kind, |
4454 | ArrayRef<CapturedParamNameType> Params, |
4455 | unsigned OpenMPCaptureLevel = 0); |
4456 | StmtResult ActOnCapturedRegionEnd(Stmt *S); |
4457 | void ActOnCapturedRegionError(); |
4458 | RecordDecl *CreateCapturedStmtRecordDecl(CapturedDecl *&CD, |
4459 | SourceLocation Loc, |
4460 | unsigned NumParams); |
4461 | |
4462 | enum CopyElisionSemanticsKind { |
4463 | CES_Strict = 0, |
4464 | CES_AllowParameters = 1, |
4465 | CES_AllowDifferentTypes = 2, |
4466 | CES_AllowExceptionVariables = 4, |
4467 | CES_FormerDefault = (CES_AllowParameters), |
4468 | CES_Default = (CES_AllowParameters | CES_AllowDifferentTypes), |
4469 | CES_AsIfByStdMove = (CES_AllowParameters | CES_AllowDifferentTypes | |
4470 | CES_AllowExceptionVariables), |
4471 | }; |
4472 | |
4473 | VarDecl *getCopyElisionCandidate(QualType ReturnType, Expr *E, |
4474 | CopyElisionSemanticsKind CESK); |
4475 | bool isCopyElisionCandidate(QualType ReturnType, const VarDecl *VD, |
4476 | CopyElisionSemanticsKind CESK); |
4477 | |
4478 | StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, |
4479 | Scope *CurScope); |
4480 | StmtResult BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp); |
4481 | StmtResult ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp); |
4482 | |
4483 | StmtResult ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, |
4484 | bool IsVolatile, unsigned NumOutputs, |
4485 | unsigned NumInputs, IdentifierInfo **Names, |
4486 | MultiExprArg Constraints, MultiExprArg Exprs, |
4487 | Expr *AsmString, MultiExprArg Clobbers, |
4488 | unsigned NumLabels, |
4489 | SourceLocation RParenLoc); |
4490 | |
4491 | void FillInlineAsmIdentifierInfo(Expr *Res, |
4492 | llvm::InlineAsmIdentifierInfo &Info); |
4493 | ExprResult LookupInlineAsmIdentifier(CXXScopeSpec &SS, |
4494 | SourceLocation TemplateKWLoc, |
4495 | UnqualifiedId &Id, |
4496 | bool IsUnevaluatedContext); |
4497 | bool LookupInlineAsmField(StringRef Base, StringRef Member, |
4498 | unsigned &Offset, SourceLocation AsmLoc); |
4499 | ExprResult LookupInlineAsmVarDeclField(Expr *RefExpr, StringRef Member, |
4500 | SourceLocation AsmLoc); |
4501 | StmtResult ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc, |
4502 | ArrayRef<Token> AsmToks, |
4503 | StringRef AsmString, |
4504 | unsigned NumOutputs, unsigned NumInputs, |
4505 | ArrayRef<StringRef> Constraints, |
4506 | ArrayRef<StringRef> Clobbers, |
4507 | ArrayRef<Expr*> Exprs, |
4508 | SourceLocation EndLoc); |
4509 | LabelDecl *GetOrCreateMSAsmLabel(StringRef ExternalLabelName, |
4510 | SourceLocation Location, |
4511 | bool AlwaysCreate); |
4512 | |
4513 | VarDecl *BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType ExceptionType, |
4514 | SourceLocation StartLoc, |
4515 | SourceLocation IdLoc, IdentifierInfo *Id, |
4516 | bool Invalid = false); |
4517 | |
4518 | Decl *ActOnObjCExceptionDecl(Scope *S, Declarator &D); |
4519 | |
4520 | StmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc, SourceLocation RParen, |
4521 | Decl *Parm, Stmt *Body); |
4522 | |
4523 | StmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body); |
4524 | |
4525 | StmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try, |
4526 | MultiStmtArg Catch, Stmt *Finally); |
4527 | |
4528 | StmtResult BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw); |
4529 | StmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw, |
4530 | Scope *CurScope); |
4531 | ExprResult ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, |
4532 | Expr *operand); |
4533 | StmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, |
4534 | Expr *SynchExpr, |
4535 | Stmt *SynchBody); |
4536 | |
4537 | StmtResult ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body); |
4538 | |
4539 | VarDecl *BuildExceptionDeclaration(Scope *S, TypeSourceInfo *TInfo, |
4540 | SourceLocation StartLoc, |
4541 | SourceLocation IdLoc, |
4542 | IdentifierInfo *Id); |
4543 | |
4544 | Decl *ActOnExceptionDeclarator(Scope *S, Declarator &D); |
4545 | |
4546 | StmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc, |
4547 | Decl *ExDecl, Stmt *HandlerBlock); |
4548 | StmtResult ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, |
4549 | ArrayRef<Stmt *> Handlers); |
4550 | |
4551 | StmtResult ActOnSEHTryBlock(bool IsCXXTry, // try (true) or __try (false) ? |
4552 | SourceLocation TryLoc, Stmt *TryBlock, |
4553 | Stmt *Handler); |
4554 | StmtResult ActOnSEHExceptBlock(SourceLocation Loc, |
4555 | Expr *FilterExpr, |
4556 | Stmt *Block); |
4557 | void ActOnStartSEHFinallyBlock(); |
4558 | void ActOnAbortSEHFinallyBlock(); |
4559 | StmtResult ActOnFinishSEHFinallyBlock(SourceLocation Loc, Stmt *Block); |
4560 | StmtResult ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope); |
4561 | |
4562 | void DiagnoseReturnInConstructorExceptionHandler(CXXTryStmt *TryBlock); |
4563 | |
4564 | bool ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const; |
4565 | |
4566 | /// If it's a file scoped decl that must warn if not used, keep track |
4567 | /// of it. |
4568 | void MarkUnusedFileScopedDecl(const DeclaratorDecl *D); |
4569 | |
4570 | /// DiagnoseUnusedExprResult - If the statement passed in is an expression |
4571 | /// whose result is unused, warn. |
4572 | void DiagnoseUnusedExprResult(const Stmt *S); |
4573 | void DiagnoseUnusedNestedTypedefs(const RecordDecl *D); |
4574 | void DiagnoseUnusedDecl(const NamedDecl *ND); |
4575 | |
4576 | /// Emit \p DiagID if statement located on \p StmtLoc has a suspicious null |
4577 | /// statement as a \p Body, and it is located on the same line. |
4578 | /// |
4579 | /// This helps prevent bugs due to typos, such as: |
4580 | /// if (condition); |
4581 | /// do_stuff(); |
4582 | void DiagnoseEmptyStmtBody(SourceLocation StmtLoc, |
4583 | const Stmt *Body, |
4584 | unsigned DiagID); |
4585 | |
4586 | /// Warn if a for/while loop statement \p S, which is followed by |
4587 | /// \p PossibleBody, has a suspicious null statement as a body. |
4588 | void DiagnoseEmptyLoopBody(const Stmt *S, |
4589 | const Stmt *PossibleBody); |
4590 | |
4591 | /// Warn if a value is moved to itself. |
4592 | void DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, |
4593 | SourceLocation OpLoc); |
4594 | |
4595 | /// Warn if we're implicitly casting from a _Nullable pointer type to a |
4596 | /// _Nonnull one. |
4597 | void diagnoseNullableToNonnullConversion(QualType DstType, QualType SrcType, |
4598 | SourceLocation Loc); |
4599 | |
4600 | /// Warn when implicitly casting 0 to nullptr. |
4601 | void diagnoseZeroToNullptrConversion(CastKind Kind, const Expr *E); |
4602 | |
4603 | ParsingDeclState PushParsingDeclaration(sema::DelayedDiagnosticPool &pool) { |
4604 | return DelayedDiagnostics.push(pool); |
4605 | } |
4606 | void PopParsingDeclaration(ParsingDeclState state, Decl *decl); |
4607 | |
4608 | typedef ProcessingContextState ParsingClassState; |
4609 | ParsingClassState PushParsingClass() { |
4610 | ParsingClassDepth++; |
4611 | return DelayedDiagnostics.pushUndelayed(); |
4612 | } |
4613 | void PopParsingClass(ParsingClassState state) { |
4614 | ParsingClassDepth--; |
4615 | DelayedDiagnostics.popUndelayed(state); |
4616 | } |
4617 | |
4618 | void redelayDiagnostics(sema::DelayedDiagnosticPool &pool); |
4619 | |
4620 | void DiagnoseAvailabilityOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs, |
4621 | const ObjCInterfaceDecl *UnknownObjCClass, |
4622 | bool ObjCPropertyAccess, |
4623 | bool AvoidPartialAvailabilityChecks = false, |
4624 | ObjCInterfaceDecl *ClassReceiver = nullptr); |
4625 | |
4626 | bool makeUnavailableInSystemHeader(SourceLocation loc, |
4627 | UnavailableAttr::ImplicitReason reason); |
4628 | |
4629 | /// Issue any -Wunguarded-availability warnings in \c FD |
4630 | void DiagnoseUnguardedAvailabilityViolations(Decl *FD); |
4631 | |
4632 | void handleDelayedAvailabilityCheck(sema::DelayedDiagnostic &DD, Decl *Ctx); |
4633 | |
4634 | //===--------------------------------------------------------------------===// |
4635 | // Expression Parsing Callbacks: SemaExpr.cpp. |
4636 | |
4637 | bool CanUseDecl(NamedDecl *D, bool TreatUnavailableAsInvalid); |
4638 | bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs, |
4639 | const ObjCInterfaceDecl *UnknownObjCClass = nullptr, |
4640 | bool ObjCPropertyAccess = false, |
4641 | bool AvoidPartialAvailabilityChecks = false, |
4642 | ObjCInterfaceDecl *ClassReciever = nullptr); |
4643 | void NoteDeletedFunction(FunctionDecl *FD); |
4644 | void NoteDeletedInheritingConstructor(CXXConstructorDecl *CD); |
4645 | bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD, |
4646 | ObjCMethodDecl *Getter, |
4647 | SourceLocation Loc); |
4648 | void DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc, |
4649 | ArrayRef<Expr *> Args); |
4650 | |
4651 | void PushExpressionEvaluationContext( |
4652 | ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl = nullptr, |
4653 | ExpressionEvaluationContextRecord::ExpressionKind Type = |
4654 | ExpressionEvaluationContextRecord::EK_Other); |
4655 | enum ReuseLambdaContextDecl_t { ReuseLambdaContextDecl }; |
4656 | void PushExpressionEvaluationContext( |
4657 | ExpressionEvaluationContext NewContext, ReuseLambdaContextDecl_t, |
4658 | ExpressionEvaluationContextRecord::ExpressionKind Type = |
4659 | ExpressionEvaluationContextRecord::EK_Other); |
4660 | void PopExpressionEvaluationContext(); |
4661 | |
4662 | void DiscardCleanupsInEvaluationContext(); |
4663 | |
4664 | ExprResult TransformToPotentiallyEvaluated(Expr *E); |
4665 | ExprResult HandleExprEvaluationContextForTypeof(Expr *E); |
4666 | |
4667 | ExprResult CheckUnevaluatedOperand(Expr *E); |
4668 | void CheckUnusedVolatileAssignment(Expr *E); |
4669 | |
4670 | ExprResult ActOnConstantExpression(ExprResult Res); |
4671 | |
4672 | // Functions for marking a declaration referenced. These functions also |
4673 | // contain the relevant logic for marking if a reference to a function or |
4674 | // variable is an odr-use (in the C++11 sense). There are separate variants |
4675 | // for expressions referring to a decl; these exist because odr-use marking |
4676 | // needs to be delayed for some constant variables when we build one of the |
4677 | // named expressions. |
4678 | // |
4679 | // MightBeOdrUse indicates whether the use could possibly be an odr-use, and |
4680 | // should usually be true. This only needs to be set to false if the lack of |
4681 | // odr-use cannot be determined from the current context (for instance, |
4682 | // because the name denotes a virtual function and was written without an |
4683 | // explicit nested-name-specifier). |
4684 | void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool MightBeOdrUse); |
4685 | void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, |
4686 | bool MightBeOdrUse = true); |
4687 | void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var); |
4688 | void MarkDeclRefReferenced(DeclRefExpr *E, const Expr *Base = nullptr); |
4689 | void MarkMemberReferenced(MemberExpr *E); |
4690 | void MarkFunctionParmPackReferenced(FunctionParmPackExpr *E); |
4691 | void MarkCaptureUsedInEnclosingContext(VarDecl *Capture, SourceLocation Loc, |
4692 | unsigned CapturingScopeIndex); |
4693 | |
4694 | ExprResult CheckLValueToRValueConversionOperand(Expr *E); |
4695 | void CleanupVarDeclMarking(); |
4696 | |
4697 | enum TryCaptureKind { |
4698 | TryCapture_Implicit, TryCapture_ExplicitByVal, TryCapture_ExplicitByRef |
4699 | }; |
4700 | |
4701 | /// Try to capture the given variable. |
4702 | /// |
4703 | /// \param Var The variable to capture. |
4704 | /// |
4705 | /// \param Loc The location at which the capture occurs. |
4706 | /// |
4707 | /// \param Kind The kind of capture, which may be implicit (for either a |
4708 | /// block or a lambda), or explicit by-value or by-reference (for a lambda). |
4709 | /// |
4710 | /// \param EllipsisLoc The location of the ellipsis, if one is provided in |
4711 | /// an explicit lambda capture. |
4712 | /// |
4713 | /// \param BuildAndDiagnose Whether we are actually supposed to add the |
4714 | /// captures or diagnose errors. If false, this routine merely check whether |
4715 | /// the capture can occur without performing the capture itself or complaining |
4716 | /// if the variable cannot be captured. |
4717 | /// |
4718 | /// \param CaptureType Will be set to the type of the field used to capture |
4719 | /// this variable in the innermost block or lambda. Only valid when the |
4720 | /// variable can be captured. |
4721 | /// |
4722 | /// \param DeclRefType Will be set to the type of a reference to the capture |
4723 | /// from within the current scope. Only valid when the variable can be |
4724 | /// captured. |
4725 | /// |
4726 | /// \param FunctionScopeIndexToStopAt If non-null, it points to the index |
4727 | /// of the FunctionScopeInfo stack beyond which we do not attempt to capture. |
4728 | /// This is useful when enclosing lambdas must speculatively capture |
4729 | /// variables that may or may not be used in certain specializations of |
4730 | /// a nested generic lambda. |
4731 | /// |
4732 | /// \returns true if an error occurred (i.e., the variable cannot be |
4733 | /// captured) and false if the capture succeeded. |
4734 | bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc, TryCaptureKind Kind, |
4735 | SourceLocation EllipsisLoc, bool BuildAndDiagnose, |
4736 | QualType &CaptureType, |
4737 | QualType &DeclRefType, |
4738 | const unsigned *const FunctionScopeIndexToStopAt); |
4739 | |
4740 | /// Try to capture the given variable. |
4741 | bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc, |
4742 | TryCaptureKind Kind = TryCapture_Implicit, |
4743 | SourceLocation EllipsisLoc = SourceLocation()); |
4744 | |
4745 | /// Checks if the variable must be captured. |
4746 | bool NeedToCaptureVariable(VarDecl *Var, SourceLocation Loc); |
4747 | |
4748 | /// Given a variable, determine the type that a reference to that |
4749 | /// variable will have in the given scope. |
4750 | QualType getCapturedDeclRefType(VarDecl *Var, SourceLocation Loc); |
4751 | |
4752 | /// Mark all of the declarations referenced within a particular AST node as |
4753 | /// referenced. Used when template instantiation instantiates a non-dependent |
4754 | /// type -- entities referenced by the type are now referenced. |
4755 | void MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T); |
4756 | void MarkDeclarationsReferencedInExpr(Expr *E, |
4757 | bool SkipLocalVariables = false); |
4758 | |
4759 | /// Try to recover by turning the given expression into a |
4760 | /// call. Returns true if recovery was attempted or an error was |
4761 | /// emitted; this may also leave the ExprResult invalid. |
4762 | bool tryToRecoverWithCall(ExprResult &E, const PartialDiagnostic &PD, |
4763 | bool ForceComplain = false, |
4764 | bool (*IsPlausibleResult)(QualType) = nullptr); |
4765 | |
4766 | /// Figure out if an expression could be turned into a call. |
4767 | bool tryExprAsCall(Expr &E, QualType &ZeroArgCallReturnTy, |
4768 | UnresolvedSetImpl &NonTemplateOverloads); |
4769 | |
4770 | /// Try to convert an expression \p E to type \p Ty. Returns the result of the |
4771 | /// conversion. |
4772 | ExprResult tryConvertExprToType(Expr *E, QualType Ty); |
4773 | |
4774 | /// Conditionally issue a diagnostic based on the current |
4775 | /// evaluation context. |
4776 | /// |
4777 | /// \param Statement If Statement is non-null, delay reporting the |
4778 | /// diagnostic until the function body is parsed, and then do a basic |
4779 | /// reachability analysis to determine if the statement is reachable. |
4780 | /// If it is unreachable, the diagnostic will not be emitted. |
4781 | bool DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement, |
4782 | const PartialDiagnostic &PD); |
4783 | /// Similar, but diagnostic is only produced if all the specified statements |
4784 | /// are reachable. |
4785 | bool DiagRuntimeBehavior(SourceLocation Loc, ArrayRef<const Stmt*> Stmts, |
4786 | const PartialDiagnostic &PD); |
4787 | |
4788 | // Primary Expressions. |
4789 | SourceRange getExprRange(Expr *E) const; |
4790 | |
4791 | ExprResult ActOnIdExpression( |
4792 | Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, |
4793 | UnqualifiedId &Id, bool HasTrailingLParen, bool IsAddressOfOperand, |
4794 | CorrectionCandidateCallback *CCC = nullptr, |
4795 | bool IsInlineAsmIdentifier = false, Token *KeywordReplacement = nullptr); |
4796 | |
4797 | void DecomposeUnqualifiedId(const UnqualifiedId &Id, |
4798 | TemplateArgumentListInfo &Buffer, |
4799 | DeclarationNameInfo &NameInfo, |
4800 | const TemplateArgumentListInfo *&TemplateArgs); |
4801 | |
4802 | bool |
4803 | DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, |
4804 | CorrectionCandidateCallback &CCC, |
4805 | TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr, |
4806 | ArrayRef<Expr *> Args = None, TypoExpr **Out = nullptr); |
4807 | |
4808 | DeclResult LookupIvarInObjCMethod(LookupResult &Lookup, Scope *S, |
4809 | IdentifierInfo *II); |
4810 | ExprResult BuildIvarRefExpr(Scope *S, SourceLocation Loc, ObjCIvarDecl *IV); |
4811 | |
4812 | ExprResult LookupInObjCMethod(LookupResult &LookUp, Scope *S, |
4813 | IdentifierInfo *II, |
4814 | bool AllowBuiltinCreation=false); |
4815 | |
4816 | ExprResult ActOnDependentIdExpression(const CXXScopeSpec &SS, |
4817 | SourceLocation TemplateKWLoc, |
4818 | const DeclarationNameInfo &NameInfo, |
4819 | bool isAddressOfOperand, |
4820 | const TemplateArgumentListInfo *TemplateArgs); |
4821 | |
4822 | /// If \p D cannot be odr-used in the current expression evaluation context, |
4823 | /// return a reason explaining why. Otherwise, return NOUR_None. |
4824 | NonOdrUseReason getNonOdrUseReasonInCurrentContext(ValueDecl *D); |
4825 | |
4826 | DeclRefExpr *BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, |
4827 | SourceLocation Loc, |
4828 | const CXXScopeSpec *SS = nullptr); |
4829 | DeclRefExpr * |
4830 | BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, |
4831 | const DeclarationNameInfo &NameInfo, |
4832 | const CXXScopeSpec *SS = nullptr, |
4833 | NamedDecl *FoundD = nullptr, |
4834 | SourceLocation TemplateKWLoc = SourceLocation(), |
4835 | const TemplateArgumentListInfo *TemplateArgs = nullptr); |
4836 | DeclRefExpr * |
4837 | BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, |
4838 | const DeclarationNameInfo &NameInfo, |
4839 | NestedNameSpecifierLoc NNS, |
4840 | NamedDecl *FoundD = nullptr, |
4841 | SourceLocation TemplateKWLoc = SourceLocation(), |
4842 | const TemplateArgumentListInfo *TemplateArgs = nullptr); |
4843 | |
4844 | ExprResult |
4845 | BuildAnonymousStructUnionMemberReference( |
4846 | const CXXScopeSpec &SS, |
4847 | SourceLocation nameLoc, |
4848 | IndirectFieldDecl *indirectField, |
4849 | DeclAccessPair FoundDecl = DeclAccessPair::make(nullptr, AS_none), |
4850 | Expr *baseObjectExpr = nullptr, |
4851 | SourceLocation opLoc = SourceLocation()); |
4852 | |
4853 | ExprResult BuildPossibleImplicitMemberExpr( |
4854 | const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, LookupResult &R, |
4855 | const TemplateArgumentListInfo *TemplateArgs, const Scope *S, |
4856 | UnresolvedLookupExpr *AsULE = nullptr); |
4857 | ExprResult BuildImplicitMemberExpr(const CXXScopeSpec &SS, |
4858 | SourceLocation TemplateKWLoc, |
4859 | LookupResult &R, |
4860 | const TemplateArgumentListInfo *TemplateArgs, |
4861 | bool IsDefiniteInstance, |
4862 | const Scope *S); |
4863 | bool UseArgumentDependentLookup(const CXXScopeSpec &SS, |
4864 | const LookupResult &R, |
4865 | bool HasTrailingLParen); |
4866 | |
4867 | ExprResult |
4868 | BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS, |
4869 | const DeclarationNameInfo &NameInfo, |
4870 | bool IsAddressOfOperand, const Scope *S, |
4871 | TypeSourceInfo **RecoveryTSI = nullptr); |
4872 | |
4873 | ExprResult BuildDependentDeclRefExpr(const CXXScopeSpec &SS, |
4874 | SourceLocation TemplateKWLoc, |
4875 | const DeclarationNameInfo &NameInfo, |
4876 | const TemplateArgumentListInfo *TemplateArgs); |
4877 | |
4878 | ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS, |
4879 | LookupResult &R, |
4880 | bool NeedsADL, |
4881 | bool AcceptInvalidDecl = false); |
4882 | ExprResult BuildDeclarationNameExpr( |
4883 | const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, NamedDecl *D, |
4884 | NamedDecl *FoundD = nullptr, |
4885 | const TemplateArgumentListInfo *TemplateArgs = nullptr, |
4886 | bool AcceptInvalidDecl = false); |
4887 | |
4888 | ExprResult BuildLiteralOperatorCall(LookupResult &R, |
4889 | DeclarationNameInfo &SuffixInfo, |
4890 | ArrayRef<Expr *> Args, |
4891 | SourceLocation LitEndLoc, |
4892 | TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr); |
4893 | |
4894 | ExprResult BuildPredefinedExpr(SourceLocation Loc, |
4895 | PredefinedExpr::IdentKind IK); |
4896 | ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind); |
4897 | ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val); |
4898 | |
4899 | ExprResult BuildUniqueStableName(SourceLocation Loc, TypeSourceInfo *Operand); |
4900 | ExprResult BuildUniqueStableName(SourceLocation Loc, Expr *E); |
4901 | ExprResult ActOnUniqueStableNameExpr(SourceLocation OpLoc, |
4902 | SourceLocation LParen, |
4903 | SourceLocation RParen, ParsedType Ty); |
4904 | ExprResult ActOnUniqueStableNameExpr(SourceLocation OpLoc, |
4905 | SourceLocation LParen, |
4906 | SourceLocation RParen, Expr *E); |
4907 | |
4908 | bool CheckLoopHintExpr(Expr *E, SourceLocation Loc); |
4909 | |
4910 | ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope = nullptr); |
4911 | ExprResult ActOnCharacterConstant(const Token &Tok, |
4912 | Scope *UDLScope = nullptr); |
4913 | ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E); |
4914 | ExprResult ActOnParenListExpr(SourceLocation L, |
4915 | SourceLocation R, |
4916 | MultiExprArg Val); |
4917 | |
4918 | /// ActOnStringLiteral - The specified tokens were lexed as pasted string |
4919 | /// fragments (e.g. "foo" "bar" L"baz"). |
4920 | ExprResult ActOnStringLiteral(ArrayRef<Token> StringToks, |
4921 | Scope *UDLScope = nullptr); |
4922 | |
4923 | ExprResult ActOnGenericSelectionExpr(SourceLocation KeyLoc, |
4924 | SourceLocation DefaultLoc, |
4925 | SourceLocation RParenLoc, |
4926 | Expr *ControllingExpr, |
4927 | ArrayRef<ParsedType> ArgTypes, |
4928 | ArrayRef<Expr *> ArgExprs); |
4929 | ExprResult CreateGenericSelectionExpr(SourceLocation KeyLoc, |
4930 | SourceLocation DefaultLoc, |
4931 | SourceLocation RParenLoc, |
4932 | Expr *ControllingExpr, |
4933 | ArrayRef<TypeSourceInfo *> Types, |
4934 | ArrayRef<Expr *> Exprs); |
4935 | |
4936 | // Binary/Unary Operators. 'Tok' is the token for the operator. |
4937 | ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, |
4938 | Expr *InputExpr); |
4939 | ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, |
4940 | UnaryOperatorKind Opc, Expr *Input); |
4941 | ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, |
4942 | tok::TokenKind Op, Expr *Input); |
4943 | |
4944 | bool isQualifiedMemberAccess(Expr *E); |
4945 | QualType CheckAddressOfOperand(ExprResult &Operand, SourceLocation OpLoc); |
4946 | |
4947 | ExprResult CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo, |
4948 | SourceLocation OpLoc, |
4949 | UnaryExprOrTypeTrait ExprKind, |
4950 | SourceRange R); |
4951 | ExprResult CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc, |
4952 | UnaryExprOrTypeTrait ExprKind); |
4953 | ExprResult |
4954 | ActOnUnaryExprOrTypeTraitExpr(SourceLocation OpLoc, |
4955 | UnaryExprOrTypeTrait ExprKind, |
4956 | bool IsType, void *TyOrEx, |
4957 | SourceRange ArgRange); |
4958 | |
4959 | ExprResult CheckPlaceholderExpr(Expr *E); |
4960 | bool CheckVecStepExpr(Expr *E); |
4961 | |
4962 | bool CheckUnaryExprOrTypeTraitOperand(Expr *E, UnaryExprOrTypeTrait ExprKind); |
4963 | bool CheckUnaryExprOrTypeTraitOperand(QualType ExprType, SourceLocation OpLoc, |
4964 | SourceRange ExprRange, |
4965 | UnaryExprOrTypeTrait ExprKind); |
4966 | ExprResult ActOnSizeofParameterPackExpr(Scope *S, |
4967 | SourceLocation OpLoc, |
4968 | IdentifierInfo &Name, |
4969 | SourceLocation NameLoc, |
4970 | SourceLocation RParenLoc); |
4971 | ExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc, |
4972 | tok::TokenKind Kind, Expr *Input); |
4973 | |
4974 | ExprResult ActOnArraySubscriptExpr(Scope *S, Expr *Base, SourceLocation LLoc, |
4975 | Expr *Idx, SourceLocation RLoc); |
4976 | ExprResult CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, |
4977 | Expr *Idx, SourceLocation RLoc); |
4978 | |
4979 | ExprResult CreateBuiltinMatrixSubscriptExpr(Expr *Base, Expr *RowIdx, |
4980 | Expr *ColumnIdx, |
4981 | SourceLocation RBLoc); |
4982 | |
4983 | ExprResult ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, |
4984 | Expr *LowerBound, |
4985 | SourceLocation ColonLocFirst, |
4986 | SourceLocation ColonLocSecond, |
4987 | Expr *Length, Expr *Stride, |
4988 | SourceLocation RBLoc); |
4989 | ExprResult ActOnOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc, |
4990 | SourceLocation RParenLoc, |
4991 | ArrayRef<Expr *> Dims, |
4992 | ArrayRef<SourceRange> Brackets); |
4993 | |
4994 | /// Data structure for iterator expression. |
4995 | struct OMPIteratorData { |
4996 | IdentifierInfo *DeclIdent = nullptr; |
4997 | SourceLocation DeclIdentLoc; |
4998 | ParsedType Type; |
4999 | OMPIteratorExpr::IteratorRange Range; |
5000 | SourceLocation AssignLoc; |
5001 | SourceLocation ColonLoc; |
5002 | SourceLocation SecColonLoc; |
5003 | }; |
5004 | |
5005 | ExprResult ActOnOMPIteratorExpr(Scope *S, SourceLocation IteratorKwLoc, |
5006 | SourceLocation LLoc, SourceLocation RLoc, |
5007 | ArrayRef<OMPIteratorData> Data); |
5008 | |
5009 | // This struct is for use by ActOnMemberAccess to allow |
5010 | // BuildMemberReferenceExpr to be able to reinvoke ActOnMemberAccess after |
5011 | // changing the access operator from a '.' to a '->' (to see if that is the |
5012 | // change needed to fix an error about an unknown member, e.g. when the class |
5013 | // defines a custom operator->). |
5014 | struct ActOnMemberAccessExtraArgs { |
5015 | Scope *S; |
5016 | UnqualifiedId &Id; |
5017 | Decl *ObjCImpDecl; |
5018 | }; |
5019 | |
5020 | ExprResult BuildMemberReferenceExpr( |
5021 | Expr *Base, QualType BaseType, SourceLocation OpLoc, bool IsArrow, |
5022 | CXXScopeSpec &SS, SourceLocation TemplateKWLoc, |
5023 | NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo, |
5024 | const TemplateArgumentListInfo *TemplateArgs, |
5025 | const Scope *S, |
5026 | ActOnMemberAccessExtraArgs *ExtraArgs = nullptr); |
5027 | |
5028 | ExprResult |
5029 | BuildMemberReferenceExpr(Expr *Base, QualType BaseType, SourceLocation OpLoc, |
5030 | bool IsArrow, const CXXScopeSpec &SS, |
5031 | SourceLocation TemplateKWLoc, |
5032 | NamedDecl *FirstQualifierInScope, LookupResult &R, |
5033 | const TemplateArgumentListInfo *TemplateArgs, |
5034 | const Scope *S, |
5035 | bool SuppressQualifierCheck = false, |
5036 | ActOnMemberAccessExtraArgs *ExtraArgs = nullptr); |
5037 | |
5038 | ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, |
5039 | SourceLocation OpLoc, |
5040 | const CXXScopeSpec &SS, FieldDecl *Field, |
5041 | DeclAccessPair FoundDecl, |
5042 | const DeclarationNameInfo &MemberNameInfo); |
5043 | |
5044 | ExprResult PerformMemberExprBaseConversion(Expr *Base, bool IsArrow); |
5045 | |
5046 | bool CheckQualifiedMemberReference(Expr *BaseExpr, QualType BaseType, |
5047 | const CXXScopeSpec &SS, |
5048 | const LookupResult &R); |
5049 | |
5050 | ExprResult ActOnDependentMemberExpr(Expr *Base, QualType BaseType, |
5051 | bool IsArrow, SourceLocation OpLoc, |
5052 | const CXXScopeSpec &SS, |
5053 | SourceLocation TemplateKWLoc, |
5054 | NamedDecl *FirstQualifierInScope, |
5055 | const DeclarationNameInfo &NameInfo, |
5056 | const TemplateArgumentListInfo *TemplateArgs); |
5057 | |
5058 | ExprResult ActOnMemberAccessExpr(Scope *S, Expr *Base, |
5059 | SourceLocation OpLoc, |
5060 | tok::TokenKind OpKind, |
5061 | CXXScopeSpec &SS, |
5062 | SourceLocation TemplateKWLoc, |
5063 | UnqualifiedId &Member, |
5064 | Decl *ObjCImpDecl); |
5065 | |
5066 | MemberExpr * |
5067 | BuildMemberExpr(Expr *Base, bool IsArrow, SourceLocation OpLoc, |
5068 | const CXXScopeSpec *SS, SourceLocation TemplateKWLoc, |
5069 | ValueDecl *Member, DeclAccessPair FoundDecl, |
5070 | bool HadMultipleCandidates, |
5071 | const DeclarationNameInfo &MemberNameInfo, QualType Ty, |
5072 | ExprValueKind VK, ExprObjectKind OK, |
5073 | const TemplateArgumentListInfo *TemplateArgs = nullptr); |
5074 | MemberExpr * |
5075 | BuildMemberExpr(Expr *Base, bool IsArrow, SourceLocation OpLoc, |
5076 | NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc, |
5077 | ValueDecl *Member, DeclAccessPair FoundDecl, |
5078 | bool HadMultipleCandidates, |
5079 | const DeclarationNameInfo &MemberNameInfo, QualType Ty, |
5080 | ExprValueKind VK, ExprObjectKind OK, |
5081 | const TemplateArgumentListInfo *TemplateArgs = nullptr); |
5082 | |
5083 | void ActOnDefaultCtorInitializers(Decl *CDtorDecl); |
5084 | bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, |
5085 | FunctionDecl *FDecl, |
5086 | const FunctionProtoType *Proto, |
5087 | ArrayRef<Expr *> Args, |
5088 | SourceLocation RParenLoc, |
5089 | bool ExecConfig = false); |
5090 | void CheckStaticArrayArgument(SourceLocation CallLoc, |
5091 | ParmVarDecl *Param, |
5092 | const Expr *ArgExpr); |
5093 | |
5094 | /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments. |
5095 | /// This provides the location of the left/right parens and a list of comma |
5096 | /// locations. |
5097 | ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, |
5098 | MultiExprArg ArgExprs, SourceLocation RParenLoc, |
5099 | Expr *ExecConfig = nullptr); |
5100 | ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, |
5101 | MultiExprArg ArgExprs, SourceLocation RParenLoc, |
5102 | Expr *ExecConfig = nullptr, |
5103 | bool IsExecConfig = false); |
5104 | enum class AtomicArgumentOrder { API, AST }; |
5105 | ExprResult |
5106 | BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, |
5107 | SourceLocation RParenLoc, MultiExprArg Args, |
5108 | AtomicExpr::AtomicOp Op, |
5109 | AtomicArgumentOrder ArgOrder = AtomicArgumentOrder::API); |
5110 | ExprResult |
5111 | BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, SourceLocation LParenLoc, |
5112 | ArrayRef<Expr *> Arg, SourceLocation RParenLoc, |
5113 | Expr *Config = nullptr, bool IsExecConfig = false, |
5114 | ADLCallKind UsesADL = ADLCallKind::NotADL); |
5115 | |
5116 | ExprResult ActOnCUDAExecConfigExpr(Scope *S, SourceLocation LLLLoc, |
5117 | MultiExprArg ExecConfig, |
5118 | SourceLocation GGGLoc); |
5119 | |
5120 | ExprResult ActOnCastExpr(Scope *S, SourceLocation LParenLoc, |
5121 | Declarator &D, ParsedType &Ty, |
5122 | SourceLocation RParenLoc, Expr *CastExpr); |
5123 | ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, |
5124 | TypeSourceInfo *Ty, |
5125 | SourceLocation RParenLoc, |
5126 | Expr *Op); |
5127 | CastKind PrepareScalarCast(ExprResult &src, QualType destType); |
5128 | |
5129 | /// Build an altivec or OpenCL literal. |
5130 | ExprResult BuildVectorLiteral(SourceLocation LParenLoc, |
5131 | SourceLocation RParenLoc, Expr *E, |
5132 | TypeSourceInfo *TInfo); |
5133 | |
5134 | ExprResult MaybeConvertParenListExprToParenExpr(Scope *S, Expr *ME); |
5135 | |
5136 | ExprResult ActOnCompoundLiteral(SourceLocation LParenLoc, |
5137 | ParsedType Ty, |
5138 | SourceLocation RParenLoc, |
5139 | Expr *InitExpr); |
5140 | |
5141 | ExprResult BuildCompoundLiteralExpr(SourceLocation LParenLoc, |
5142 | TypeSourceInfo *TInfo, |
5143 | SourceLocation RParenLoc, |
5144 | Expr *LiteralExpr); |
5145 | |
5146 | ExprResult ActOnInitList(SourceLocation LBraceLoc, |
5147 | MultiExprArg InitArgList, |
5148 | SourceLocation RBraceLoc); |
5149 | |
5150 | ExprResult BuildInitList(SourceLocation LBraceLoc, |
5151 | MultiExprArg InitArgList, |
5152 | SourceLocation RBraceLoc); |
5153 | |
5154 | ExprResult ActOnDesignatedInitializer(Designation &Desig, |
5155 | SourceLocation EqualOrColonLoc, |
5156 | bool GNUSyntax, |
5157 | ExprResult Init); |
5158 | |
5159 | private: |
5160 | static BinaryOperatorKind ConvertTokenKindToBinaryOpcode(tok::TokenKind Kind); |
5161 | |
5162 | public: |
5163 | ExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc, |
5164 | tok::TokenKind Kind, Expr *LHSExpr, Expr *RHSExpr); |
5165 | ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, |
5166 | BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr); |
5167 | ExprResult CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, |
5168 | Expr *LHSExpr, Expr *RHSExpr); |
5169 | |
5170 | void DiagnoseCommaOperator(const Expr *LHS, SourceLocation Loc); |
5171 | |
5172 | /// ActOnConditionalOp - Parse a ?: operation. Note that 'LHS' may be null |
5173 | /// in the case of a the GNU conditional expr extension. |
5174 | ExprResult ActOnConditionalOp(SourceLocation QuestionLoc, |
5175 | SourceLocation ColonLoc, |
5176 | Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr); |
5177 | |
5178 | /// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo". |
5179 | ExprResult ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc, |
5180 | LabelDecl *TheDecl); |
5181 | |
5182 | void ActOnStartStmtExpr(); |
5183 | ExprResult ActOnStmtExpr(Scope *S, SourceLocation LPLoc, Stmt *SubStmt, |
5184 | SourceLocation RPLoc); |
5185 | ExprResult BuildStmtExpr(SourceLocation LPLoc, Stmt *SubStmt, |
5186 | SourceLocation RPLoc, unsigned TemplateDepth); |
5187 | // Handle the final expression in a statement expression. |
5188 | ExprResult ActOnStmtExprResult(ExprResult E); |
5189 | void ActOnStmtExprError(); |
5190 | |
5191 | // __builtin_offsetof(type, identifier(.identifier|[expr])*) |
5192 | struct OffsetOfComponent { |
5193 | SourceLocation LocStart, LocEnd; |
5194 | bool isBrackets; // true if [expr], false if .ident |
5195 | union { |
5196 | IdentifierInfo *IdentInfo; |
5197 | Expr *E; |
5198 | } U; |
5199 | }; |
5200 | |
5201 | /// __builtin_offsetof(type, a.b[123][456].c) |
5202 | ExprResult BuildBuiltinOffsetOf(SourceLocation BuiltinLoc, |
5203 | TypeSourceInfo *TInfo, |
5204 | ArrayRef<OffsetOfComponent> Components, |
5205 | SourceLocation RParenLoc); |
5206 | ExprResult ActOnBuiltinOffsetOf(Scope *S, |
5207 | SourceLocation BuiltinLoc, |
5208 | SourceLocation TypeLoc, |
5209 | ParsedType ParsedArgTy, |
5210 | ArrayRef<OffsetOfComponent> Components, |
5211 | SourceLocation RParenLoc); |
5212 | |
5213 | // __builtin_choose_expr(constExpr, expr1, expr2) |
5214 | ExprResult ActOnChooseExpr(SourceLocation BuiltinLoc, |
5215 | Expr *CondExpr, Expr *LHSExpr, |
5216 | Expr *RHSExpr, SourceLocation RPLoc); |
5217 | |
5218 | // __builtin_va_arg(expr, type) |
5219 | ExprResult ActOnVAArg(SourceLocation BuiltinLoc, Expr *E, ParsedType Ty, |
5220 | SourceLocation RPLoc); |
5221 | ExprResult BuildVAArgExpr(SourceLocation BuiltinLoc, Expr *E, |
5222 | TypeSourceInfo *TInfo, SourceLocation RPLoc); |
5223 | |
5224 | // __builtin_LINE(), __builtin_FUNCTION(), __builtin_FILE(), |
5225 | // __builtin_COLUMN() |
5226 | ExprResult ActOnSourceLocExpr(SourceLocExpr::IdentKind Kind, |
5227 | SourceLocation BuiltinLoc, |
5228 | SourceLocation RPLoc); |
5229 | |
5230 | // Build a potentially resolved SourceLocExpr. |
5231 | ExprResult BuildSourceLocExpr(SourceLocExpr::IdentKind Kind, |
5232 | SourceLocation BuiltinLoc, SourceLocation RPLoc, |
5233 | DeclContext *ParentContext); |
5234 | |
5235 | // __null |
5236 | ExprResult ActOnGNUNullExpr(SourceLocation TokenLoc); |
5237 | |
5238 | bool CheckCaseExpression(Expr *E); |
5239 | |
5240 | /// Describes the result of an "if-exists" condition check. |
5241 | enum IfExistsResult { |
5242 | /// The symbol exists. |
5243 | IER_Exists, |
5244 | |
5245 | /// The symbol does not exist. |
5246 | IER_DoesNotExist, |
5247 | |
5248 | /// The name is a dependent name, so the results will differ |
5249 | /// from one instantiation to the next. |
5250 | IER_Dependent, |
5251 | |
5252 | /// An error occurred. |
5253 | IER_Error |
5254 | }; |
5255 | |
5256 | IfExistsResult |
5257 | CheckMicrosoftIfExistsSymbol(Scope *S, CXXScopeSpec &SS, |
5258 | const DeclarationNameInfo &TargetNameInfo); |
5259 | |
5260 | IfExistsResult |
5261 | CheckMicrosoftIfExistsSymbol(Scope *S, SourceLocation KeywordLoc, |
5262 | bool IsIfExists, CXXScopeSpec &SS, |
5263 | UnqualifiedId &Name); |
5264 | |
5265 | StmtResult BuildMSDependentExistsStmt(SourceLocation KeywordLoc, |
5266 | bool IsIfExists, |
5267 | NestedNameSpecifierLoc QualifierLoc, |
5268 | DeclarationNameInfo NameInfo, |
5269 | Stmt *Nested); |
5270 | StmtResult ActOnMSDependentExistsStmt(SourceLocation KeywordLoc, |
5271 | bool IsIfExists, |
5272 | CXXScopeSpec &SS, UnqualifiedId &Name, |
5273 | Stmt *Nested); |
5274 | |
5275 | //===------------------------- "Block" Extension ------------------------===// |
5276 | |
5277 | /// ActOnBlockStart - This callback is invoked when a block literal is |
5278 | /// started. |
5279 | void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope); |
5280 | |
5281 | /// ActOnBlockArguments - This callback allows processing of block arguments. |
5282 | /// If there are no arguments, this is still invoked. |
5283 | void ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo, |
5284 | Scope *CurScope); |
5285 | |
5286 | /// ActOnBlockError - If there is an error parsing a block, this callback |
5287 | /// is invoked to pop the information about the block from the action impl. |
5288 | void ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope); |
5289 | |
5290 | /// ActOnBlockStmtExpr - This is called when the body of a block statement |
5291 | /// literal was successfully completed. ^(int x){...} |
5292 | ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc, Stmt *Body, |
5293 | Scope *CurScope); |
5294 | |
5295 | //===---------------------------- Clang Extensions ----------------------===// |
5296 | |
5297 | /// __builtin_convertvector(...) |
5298 | ExprResult ActOnConvertVectorExpr(Expr *E, ParsedType ParsedDestTy, |
5299 | SourceLocation BuiltinLoc, |
5300 | SourceLocation RParenLoc); |
5301 | |
5302 | //===---------------------------- OpenCL Features -----------------------===// |
5303 | |
5304 | /// __builtin_astype(...) |
5305 | ExprResult ActOnAsTypeExpr(Expr *E, ParsedType ParsedDestTy, |
5306 | SourceLocation BuiltinLoc, |
5307 | SourceLocation RParenLoc); |
5308 | |
5309 | //===---------------------------- C++ Features --------------------------===// |
5310 | |
5311 | // Act on C++ namespaces |
5312 | Decl *ActOnStartNamespaceDef(Scope *S, SourceLocation InlineLoc, |
5313 | SourceLocation NamespaceLoc, |
5314 | SourceLocation IdentLoc, IdentifierInfo *Ident, |
5315 | SourceLocation LBrace, |
5316 | const ParsedAttributesView &AttrList, |
5317 | UsingDirectiveDecl *&UsingDecl); |
5318 | void ActOnFinishNamespaceDef(Decl *Dcl, SourceLocation RBrace); |
5319 | |
5320 | NamespaceDecl *getStdNamespace() const; |
5321 | NamespaceDecl *getOrCreateStdNamespace(); |
5322 | |
5323 | NamespaceDecl *lookupStdExperimentalNamespace(); |
5324 | |
5325 | CXXRecordDecl *getStdBadAlloc() const; |
5326 | EnumDecl *getStdAlignValT() const; |
5327 | |
5328 | private: |
5329 | // A cache representing if we've fully checked the various comparison category |
5330 | // types stored in ASTContext. The bit-index corresponds to the integer value |
5331 | // of a ComparisonCategoryType enumerator. |
5332 | llvm::SmallBitVector FullyCheckedComparisonCategories; |
5333 | |
5334 | ValueDecl *tryLookupCtorInitMemberDecl(CXXRecordDecl *ClassDecl, |
5335 | CXXScopeSpec &SS, |
5336 | ParsedType TemplateTypeTy, |
5337 | IdentifierInfo *MemberOrBase); |
5338 | |
5339 | public: |
5340 | enum class ComparisonCategoryUsage { |
5341 | /// The '<=>' operator was used in an expression and a builtin operator |
5342 | /// was selected. |
5343 | OperatorInExpression, |
5344 | /// A defaulted 'operator<=>' needed the comparison category. This |
5345 | /// typically only applies to 'std::strong_ordering', due to the implicit |
5346 | /// fallback return value. |
5347 | DefaultedOperator, |
5348 | }; |
5349 | |
5350 | /// Lookup the specified comparison category types in the standard |
5351 | /// library, an check the VarDecls possibly returned by the operator<=> |
5352 | /// builtins for that type. |
5353 | /// |
5354 | /// \return The type of the comparison category type corresponding to the |
5355 | /// specified Kind, or a null type if an error occurs |
5356 | QualType CheckComparisonCategoryType(ComparisonCategoryType Kind, |
5357 | SourceLocation Loc, |
5358 | ComparisonCategoryUsage Usage); |
5359 | |
5360 | /// Tests whether Ty is an instance of std::initializer_list and, if |
5361 | /// it is and Element is not NULL, assigns the element type to Element. |
5362 | bool isStdInitializerList(QualType Ty, QualType *Element); |
5363 | |
5364 | /// Looks for the std::initializer_list template and instantiates it |
5365 | /// with Element, or emits an error if it's not found. |
5366 | /// |
5367 | /// \returns The instantiated template, or null on error. |
5368 | QualType BuildStdInitializerList(QualType Element, SourceLocation Loc); |
5369 | |
5370 | /// Determine whether Ctor is an initializer-list constructor, as |
5371 | /// defined in [dcl.init.list]p2. |
5372 | bool isInitListConstructor(const FunctionDecl *Ctor); |
5373 | |
5374 | Decl *ActOnUsingDirective(Scope *CurScope, SourceLocation UsingLoc, |
5375 | SourceLocation NamespcLoc, CXXScopeSpec &SS, |
5376 | SourceLocation IdentLoc, |
5377 | IdentifierInfo *NamespcName, |
5378 | const ParsedAttributesView &AttrList); |
5379 | |
5380 | void PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir); |
5381 | |
5382 | Decl *ActOnNamespaceAliasDef(Scope *CurScope, |
5383 | SourceLocation NamespaceLoc, |
5384 | SourceLocation AliasLoc, |
5385 | IdentifierInfo *Alias, |
5386 | CXXScopeSpec &SS, |
5387 | SourceLocation IdentLoc, |
5388 | IdentifierInfo *Ident); |
5389 | |
5390 | void HideUsingShadowDecl(Scope *S, UsingShadowDecl *Shadow); |
5391 | bool CheckUsingShadowDecl(UsingDecl *UD, NamedDecl *Target, |
5392 | const LookupResult &PreviousDecls, |
5393 | UsingShadowDecl *&PrevShadow); |
5394 | UsingShadowDecl *BuildUsingShadowDecl(Scope *S, UsingDecl *UD, |
5395 | NamedDecl *Target, |
5396 | UsingShadowDecl *PrevDecl); |
5397 | |
5398 | bool CheckUsingDeclRedeclaration(SourceLocation UsingLoc, |
5399 | bool HasTypenameKeyword, |
5400 | const CXXScopeSpec &SS, |
5401 | SourceLocation NameLoc, |
5402 | const LookupResult &Previous); |
5403 | bool CheckUsingDeclQualifier(SourceLocation UsingLoc, |
5404 | bool HasTypename, |
5405 | const CXXScopeSpec &SS, |
5406 | const DeclarationNameInfo &NameInfo, |
5407 | SourceLocation NameLoc); |
5408 | |
5409 | NamedDecl *BuildUsingDeclaration( |
5410 | Scope *S, AccessSpecifier AS, SourceLocation UsingLoc, |
5411 | bool HasTypenameKeyword, SourceLocation TypenameLoc, CXXScopeSpec &SS, |
5412 | DeclarationNameInfo NameInfo, SourceLocation EllipsisLoc, |
5413 | const ParsedAttributesView &AttrList, bool IsInstantiation); |
5414 | NamedDecl *BuildUsingPackDecl(NamedDecl *InstantiatedFrom, |
5415 | ArrayRef<NamedDecl *> Expansions); |
5416 | |
5417 | bool CheckInheritingConstructorUsingDecl(UsingDecl *UD); |
5418 | |
5419 | /// Given a derived-class using shadow declaration for a constructor and the |
5420 | /// correspnding base class constructor, find or create the implicit |
5421 | /// synthesized derived class constructor to use for this initialization. |
5422 | CXXConstructorDecl * |
5423 | findInheritingConstructor(SourceLocation Loc, CXXConstructorDecl *BaseCtor, |
5424 | ConstructorUsingShadowDecl *DerivedShadow); |
5425 | |
5426 | Decl *ActOnUsingDeclaration(Scope *CurScope, AccessSpecifier AS, |
5427 | SourceLocation UsingLoc, |
5428 | SourceLocation TypenameLoc, CXXScopeSpec &SS, |
5429 | UnqualifiedId &Name, SourceLocation EllipsisLoc, |
5430 | const ParsedAttributesView &AttrList); |
5431 | Decl *ActOnAliasDeclaration(Scope *CurScope, AccessSpecifier AS, |
5432 | MultiTemplateParamsArg TemplateParams, |
5433 | SourceLocation UsingLoc, UnqualifiedId &Name, |
5434 | const ParsedAttributesView &AttrList, |
5435 | TypeResult Type, Decl *DeclFromDeclSpec); |
5436 | |
5437 | /// BuildCXXConstructExpr - Creates a complete call to a constructor, |
5438 | /// including handling of its default argument expressions. |
5439 | /// |
5440 | /// \param ConstructKind - a CXXConstructExpr::ConstructionKind |
5441 | ExprResult |
5442 | BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, |
5443 | NamedDecl *FoundDecl, |
5444 | CXXConstructorDecl *Constructor, MultiExprArg Exprs, |
5445 | bool HadMultipleCandidates, bool IsListInitialization, |
5446 | bool IsStdInitListInitialization, |
5447 | bool RequiresZeroInit, unsigned ConstructKind, |
5448 | SourceRange ParenRange); |
5449 | |
5450 | /// Build a CXXConstructExpr whose constructor has already been resolved if |
5451 | /// it denotes an inherited constructor. |
5452 | ExprResult |
5453 | BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, |
5454 | CXXConstructorDecl *Constructor, bool Elidable, |
5455 | MultiExprArg Exprs, |
5456 | bool HadMultipleCandidates, bool IsListInitialization, |
5457 | bool IsStdInitListInitialization, |
5458 | bool RequiresZeroInit, unsigned ConstructKind, |
5459 | SourceRange ParenRange); |
5460 | |
5461 | // FIXME: Can we remove this and have the above BuildCXXConstructExpr check if |
5462 | // the constructor can be elidable? |
5463 | ExprResult |
5464 | BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, |
5465 | NamedDecl *FoundDecl, |
5466 | CXXConstructorDecl *Constructor, bool Elidable, |
5467 | MultiExprArg Exprs, bool HadMultipleCandidates, |
5468 | bool IsListInitialization, |
5469 | bool IsStdInitListInitialization, bool RequiresZeroInit, |
5470 | unsigned ConstructKind, SourceRange ParenRange); |
5471 | |
5472 | ExprResult BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field); |
5473 | |
5474 | |
5475 | /// Instantiate or parse a C++ default argument expression as necessary. |
5476 | /// Return true on error. |
5477 | bool CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD, |
5478 | ParmVarDecl *Param); |
5479 | |
5480 | /// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating |
5481 | /// the default expr if needed. |
5482 | ExprResult BuildCXXDefaultArgExpr(SourceLocation CallLoc, |
5483 | FunctionDecl *FD, |
5484 | ParmVarDecl *Param); |
5485 | |
5486 | /// FinalizeVarWithDestructor - Prepare for calling destructor on the |
5487 | /// constructed variable. |
5488 | void FinalizeVarWithDestructor(VarDecl *VD, const RecordType *DeclInitType); |
5489 | |
5490 | /// Helper class that collects exception specifications for |
5491 | /// implicitly-declared special member functions. |
5492 | class ImplicitExceptionSpecification { |
5493 | // Pointer to allow copying |
5494 | Sema *Self; |
5495 | // We order exception specifications thus: |
5496 | // noexcept is the most restrictive, but is only used in C++11. |
5497 | // throw() comes next. |
5498 | // Then a throw(collected exceptions) |
5499 | // Finally no specification, which is expressed as noexcept(false). |
5500 | // throw(...) is used instead if any called function uses it. |
5501 | ExceptionSpecificationType ComputedEST; |
5502 | llvm::SmallPtrSet<CanQualType, 4> ExceptionsSeen; |
5503 | SmallVector<QualType, 4> Exceptions; |
5504 | |
5505 | void ClearExceptions() { |
5506 | ExceptionsSeen.clear(); |
5507 | Exceptions.clear(); |
5508 | } |
5509 | |
5510 | public: |
5511 | explicit ImplicitExceptionSpecification(Sema &Self) |
5512 | : Self(&Self), ComputedEST(EST_BasicNoexcept) { |
5513 | if (!Self.getLangOpts().CPlusPlus11) |
5514 | ComputedEST = EST_DynamicNone; |
5515 | } |
5516 | |
5517 | /// Get the computed exception specification type. |
5518 | ExceptionSpecificationType getExceptionSpecType() const { |
5519 | 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~++20200806111125+5446ec85070/clang/include/clang/Sema/Sema.h" , 5520, __PRETTY_FUNCTION__)) |
5520 | "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~++20200806111125+5446ec85070/clang/include/clang/Sema/Sema.h" , 5520, __PRETTY_FUNCTION__)); |
5521 | return ComputedEST; |
5522 | } |
5523 | |
5524 | /// The number of exceptions in the exception specification. |
5525 | unsigned size() const { return Exceptions.size(); } |
5526 | |
5527 | /// The set of exceptions in the exception specification. |
5528 | const QualType *data() const { return Exceptions.data(); } |
5529 | |
5530 | /// Integrate another called method into the collected data. |
5531 | void CalledDecl(SourceLocation CallLoc, const CXXMethodDecl *Method); |
5532 | |
5533 | /// Integrate an invoked expression into the collected data. |
5534 | void CalledExpr(Expr *E) { CalledStmt(E); } |
5535 | |
5536 | /// Integrate an invoked statement into the collected data. |
5537 | void CalledStmt(Stmt *S); |
5538 | |
5539 | /// Overwrite an EPI's exception specification with this |
5540 | /// computed exception specification. |
5541 | FunctionProtoType::ExceptionSpecInfo getExceptionSpec() const { |
5542 | FunctionProtoType::ExceptionSpecInfo ESI; |
5543 | ESI.Type = getExceptionSpecType(); |
5544 | if (ESI.Type == EST_Dynamic) { |
5545 | ESI.Exceptions = Exceptions; |
5546 | } else if (ESI.Type == EST_None) { |
5547 | /// C++11 [except.spec]p14: |
5548 | /// The exception-specification is noexcept(false) if the set of |
5549 | /// potential exceptions of the special member function contains "any" |
5550 | ESI.Type = EST_NoexceptFalse; |
5551 | ESI.NoexceptExpr = Self->ActOnCXXBoolLiteral(SourceLocation(), |
5552 | tok::kw_false).get(); |
5553 | } |
5554 | return ESI; |
5555 | } |
5556 | }; |
5557 | |
5558 | /// Determine what sort of exception specification a defaulted |
5559 | /// copy constructor of a class will have. |
5560 | ImplicitExceptionSpecification |
5561 | ComputeDefaultedDefaultCtorExceptionSpec(SourceLocation Loc, |
5562 | CXXMethodDecl *MD); |
5563 | |
5564 | /// Determine what sort of exception specification a defaulted |
5565 | /// default constructor of a class will have, and whether the parameter |
5566 | /// will be const. |
5567 | ImplicitExceptionSpecification |
5568 | ComputeDefaultedCopyCtorExceptionSpec(CXXMethodDecl *MD); |
5569 | |
5570 | /// Determine what sort of exception specification a defaulted |
5571 | /// copy assignment operator of a class will have, and whether the |
5572 | /// parameter will be const. |
5573 | ImplicitExceptionSpecification |
5574 | ComputeDefaultedCopyAssignmentExceptionSpec(CXXMethodDecl *MD); |
5575 | |
5576 | /// Determine what sort of exception specification a defaulted move |
5577 | /// constructor of a class will have. |
5578 | ImplicitExceptionSpecification |
5579 | ComputeDefaultedMoveCtorExceptionSpec(CXXMethodDecl *MD); |
5580 | |
5581 | /// Determine what sort of exception specification a defaulted move |
5582 | /// assignment operator of a class will have. |
5583 | ImplicitExceptionSpecification |
5584 | ComputeDefaultedMoveAssignmentExceptionSpec(CXXMethodDecl *MD); |
5585 | |
5586 | /// Determine what sort of exception specification a defaulted |
5587 | /// destructor of a class will have. |
5588 | ImplicitExceptionSpecification |
5589 | ComputeDefaultedDtorExceptionSpec(CXXMethodDecl *MD); |
5590 | |
5591 | /// Determine what sort of exception specification an inheriting |
5592 | /// constructor of a class will have. |
5593 | ImplicitExceptionSpecification |
5594 | ComputeInheritingCtorExceptionSpec(SourceLocation Loc, |
5595 | CXXConstructorDecl *CD); |
5596 | |
5597 | /// Evaluate the implicit exception specification for a defaulted |
5598 | /// special member function. |
5599 | void EvaluateImplicitExceptionSpec(SourceLocation Loc, FunctionDecl *FD); |
5600 | |
5601 | /// Check the given noexcept-specifier, convert its expression, and compute |
5602 | /// the appropriate ExceptionSpecificationType. |
5603 | ExprResult ActOnNoexceptSpec(SourceLocation NoexceptLoc, Expr *NoexceptExpr, |
5604 | ExceptionSpecificationType &EST); |
5605 | |
5606 | /// Check the given exception-specification and update the |
5607 | /// exception specification information with the results. |
5608 | void checkExceptionSpecification(bool IsTopLevel, |
5609 | ExceptionSpecificationType EST, |
5610 | ArrayRef<ParsedType> DynamicExceptions, |
5611 | ArrayRef<SourceRange> DynamicExceptionRanges, |
5612 | Expr *NoexceptExpr, |
5613 | SmallVectorImpl<QualType> &Exceptions, |
5614 | FunctionProtoType::ExceptionSpecInfo &ESI); |
5615 | |
5616 | /// Determine if we're in a case where we need to (incorrectly) eagerly |
5617 | /// parse an exception specification to work around a libstdc++ bug. |
5618 | bool isLibstdcxxEagerExceptionSpecHack(const Declarator &D); |
5619 | |
5620 | /// Add an exception-specification to the given member function |
5621 | /// (or member function template). The exception-specification was parsed |
5622 | /// after the method itself was declared. |
5623 | void actOnDelayedExceptionSpecification(Decl *Method, |
5624 | ExceptionSpecificationType EST, |
5625 | SourceRange SpecificationRange, |
5626 | ArrayRef<ParsedType> DynamicExceptions, |
5627 | ArrayRef<SourceRange> DynamicExceptionRanges, |
5628 | Expr *NoexceptExpr); |
5629 | |
5630 | class InheritedConstructorInfo; |
5631 | |
5632 | /// Determine if a special member function should have a deleted |
5633 | /// definition when it is defaulted. |
5634 | bool ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM, |
5635 | InheritedConstructorInfo *ICI = nullptr, |
5636 | bool Diagnose = false); |
5637 | |
5638 | /// Produce notes explaining why a defaulted function was defined as deleted. |
5639 | void DiagnoseDeletedDefaultedFunction(FunctionDecl *FD); |
5640 | |
5641 | /// Declare the implicit default constructor for the given class. |
5642 | /// |
5643 | /// \param ClassDecl The class declaration into which the implicit |
5644 | /// default constructor will be added. |
5645 | /// |
5646 | /// \returns The implicitly-declared default constructor. |
5647 | CXXConstructorDecl *DeclareImplicitDefaultConstructor( |
5648 | CXXRecordDecl *ClassDecl); |
5649 | |
5650 | /// DefineImplicitDefaultConstructor - Checks for feasibility of |
5651 | /// defining this constructor as the default constructor. |
5652 | void DefineImplicitDefaultConstructor(SourceLocation CurrentLocation, |
5653 | CXXConstructorDecl *Constructor); |
5654 | |
5655 | /// Declare the implicit destructor for the given class. |
5656 | /// |
5657 | /// \param ClassDecl The class declaration into which the implicit |
5658 | /// destructor will be added. |
5659 | /// |
5660 | /// \returns The implicitly-declared destructor. |
5661 | CXXDestructorDecl *DeclareImplicitDestructor(CXXRecordDecl *ClassDecl); |
5662 | |
5663 | /// DefineImplicitDestructor - Checks for feasibility of |
5664 | /// defining this destructor as the default destructor. |
5665 | void DefineImplicitDestructor(SourceLocation CurrentLocation, |
5666 | CXXDestructorDecl *Destructor); |
5667 | |
5668 | /// Build an exception spec for destructors that don't have one. |
5669 | /// |
5670 | /// C++11 says that user-defined destructors with no exception spec get one |
5671 | /// that looks as if the destructor was implicitly declared. |
5672 | void AdjustDestructorExceptionSpec(CXXDestructorDecl *Destructor); |
5673 | |
5674 | /// Define the specified inheriting constructor. |
5675 | void DefineInheritingConstructor(SourceLocation UseLoc, |
5676 | CXXConstructorDecl *Constructor); |
5677 | |
5678 | /// Declare the implicit copy constructor for the given class. |
5679 | /// |
5680 | /// \param ClassDecl The class declaration into which the implicit |
5681 | /// copy constructor will be added. |
5682 | /// |
5683 | /// \returns The implicitly-declared copy constructor. |
5684 | CXXConstructorDecl *DeclareImplicitCopyConstructor(CXXRecordDecl *ClassDecl); |
5685 | |
5686 | /// DefineImplicitCopyConstructor - Checks for feasibility of |
5687 | /// defining this constructor as the copy constructor. |
5688 | void DefineImplicitCopyConstructor(SourceLocation CurrentLocation, |
5689 | CXXConstructorDecl *Constructor); |
5690 | |
5691 | /// Declare the implicit move constructor for the given class. |
5692 | /// |
5693 | /// \param ClassDecl The Class declaration into which the implicit |
5694 | /// move constructor will be added. |
5695 | /// |
5696 | /// \returns The implicitly-declared move constructor, or NULL if it wasn't |
5697 | /// declared. |
5698 | CXXConstructorDecl *DeclareImplicitMoveConstructor(CXXRecordDecl *ClassDecl); |
5699 | |
5700 | /// DefineImplicitMoveConstructor - Checks for feasibility of |
5701 | /// defining this constructor as the move constructor. |
5702 | void DefineImplicitMoveConstructor(SourceLocation CurrentLocation, |
5703 | CXXConstructorDecl *Constructor); |
5704 | |
5705 | /// Declare the implicit copy assignment operator for the given class. |
5706 | /// |
5707 | /// \param ClassDecl The class declaration into which the implicit |
5708 | /// copy assignment operator will be added. |
5709 | /// |
5710 | /// \returns The implicitly-declared copy assignment operator. |
5711 | CXXMethodDecl *DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl); |
5712 | |
5713 | /// Defines an implicitly-declared copy assignment operator. |
5714 | void DefineImplicitCopyAssignment(SourceLocation CurrentLocation, |
5715 | CXXMethodDecl *MethodDecl); |
5716 | |
5717 | /// Declare the implicit move assignment operator for the given class. |
5718 | /// |
5719 | /// \param ClassDecl The Class declaration into which the implicit |
5720 | /// move assignment operator will be added. |
5721 | /// |
5722 | /// \returns The implicitly-declared move assignment operator, or NULL if it |
5723 | /// wasn't declared. |
5724 | CXXMethodDecl *DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl); |
5725 | |
5726 | /// Defines an implicitly-declared move assignment operator. |
5727 | void DefineImplicitMoveAssignment(SourceLocation CurrentLocation, |
5728 | CXXMethodDecl *MethodDecl); |
5729 | |
5730 | /// Force the declaration of any implicitly-declared members of this |
5731 | /// class. |
5732 | void ForceDeclarationOfImplicitMembers(CXXRecordDecl *Class); |
5733 | |
5734 | /// Check a completed declaration of an implicit special member. |
5735 | void CheckImplicitSpecialMemberDeclaration(Scope *S, FunctionDecl *FD); |
5736 | |
5737 | /// Determine whether the given function is an implicitly-deleted |
5738 | /// special member function. |
5739 | bool isImplicitlyDeleted(FunctionDecl *FD); |
5740 | |
5741 | /// Check whether 'this' shows up in the type of a static member |
5742 | /// function after the (naturally empty) cv-qualifier-seq would be. |
5743 | /// |
5744 | /// \returns true if an error occurred. |
5745 | bool checkThisInStaticMemberFunctionType(CXXMethodDecl *Method); |
5746 | |
5747 | /// Whether this' shows up in the exception specification of a static |
5748 | /// member function. |
5749 | bool checkThisInStaticMemberFunctionExceptionSpec(CXXMethodDecl *Method); |
5750 | |
5751 | /// Check whether 'this' shows up in the attributes of the given |
5752 | /// static member function. |
5753 | /// |
5754 | /// \returns true if an error occurred. |
5755 | bool checkThisInStaticMemberFunctionAttributes(CXXMethodDecl *Method); |
5756 | |
5757 | /// MaybeBindToTemporary - If the passed in expression has a record type with |
5758 | /// a non-trivial destructor, this will return CXXBindTemporaryExpr. Otherwise |
5759 | /// it simply returns the passed in expression. |
5760 | ExprResult MaybeBindToTemporary(Expr *E); |
5761 | |
5762 | /// Wrap the expression in a ConstantExpr if it is a potential immediate |
5763 | /// invocation. |
5764 | ExprResult CheckForImmediateInvocation(ExprResult E, FunctionDecl *Decl); |
5765 | |
5766 | bool CompleteConstructorCall(CXXConstructorDecl *Constructor, |
5767 | MultiExprArg ArgsPtr, |
5768 | SourceLocation Loc, |
5769 | SmallVectorImpl<Expr*> &ConvertedArgs, |
5770 | bool AllowExplicit = false, |
5771 | bool IsListInitialization = false); |
5772 | |
5773 | ParsedType getInheritingConstructorName(CXXScopeSpec &SS, |
5774 | SourceLocation NameLoc, |
5775 | IdentifierInfo &Name); |
5776 | |
5777 | ParsedType getConstructorName(IdentifierInfo &II, SourceLocation NameLoc, |
5778 | Scope *S, CXXScopeSpec &SS, |
5779 | bool EnteringContext); |
5780 | ParsedType getDestructorName(SourceLocation TildeLoc, |
5781 | IdentifierInfo &II, SourceLocation NameLoc, |
5782 | Scope *S, CXXScopeSpec &SS, |
5783 | ParsedType ObjectType, |
5784 | bool EnteringContext); |
5785 | |
5786 | ParsedType getDestructorTypeForDecltype(const DeclSpec &DS, |
5787 | ParsedType ObjectType); |
5788 | |
5789 | // Checks that reinterpret casts don't have undefined behavior. |
5790 | void CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType, |
5791 | bool IsDereference, SourceRange Range); |
5792 | |
5793 | /// ActOnCXXNamedCast - Parse |
5794 | /// {dynamic,static,reinterpret,const,addrspace}_cast's. |
5795 | ExprResult ActOnCXXNamedCast(SourceLocation OpLoc, |
5796 | tok::TokenKind Kind, |
5797 | SourceLocation LAngleBracketLoc, |
5798 | Declarator &D, |
5799 | SourceLocation RAngleBracketLoc, |
5800 | SourceLocation LParenLoc, |
5801 | Expr *E, |
5802 | SourceLocation RParenLoc); |
5803 | |
5804 | ExprResult BuildCXXNamedCast(SourceLocation OpLoc, |
5805 | tok::TokenKind Kind, |
5806 | TypeSourceInfo *Ty, |
5807 | Expr *E, |
5808 | SourceRange AngleBrackets, |
5809 | SourceRange Parens); |
5810 | |
5811 | ExprResult ActOnBuiltinBitCastExpr(SourceLocation KWLoc, Declarator &Dcl, |
5812 | ExprResult Operand, |
5813 | SourceLocation RParenLoc); |
5814 | |
5815 | ExprResult BuildBuiltinBitCastExpr(SourceLocation KWLoc, TypeSourceInfo *TSI, |
5816 | Expr *Operand, SourceLocation RParenLoc); |
5817 | |
5818 | ExprResult BuildCXXTypeId(QualType TypeInfoType, |
5819 | SourceLocation TypeidLoc, |
5820 | TypeSourceInfo *Operand, |
5821 | SourceLocation RParenLoc); |
5822 | ExprResult BuildCXXTypeId(QualType TypeInfoType, |
5823 | SourceLocation TypeidLoc, |
5824 | Expr *Operand, |
5825 | SourceLocation RParenLoc); |
5826 | |
5827 | /// ActOnCXXTypeid - Parse typeid( something ). |
5828 | ExprResult ActOnCXXTypeid(SourceLocation OpLoc, |
5829 | SourceLocation LParenLoc, bool isType, |
5830 | void *TyOrExpr, |
5831 | SourceLocation RParenLoc); |
5832 | |
5833 | ExprResult BuildCXXUuidof(QualType TypeInfoType, |
5834 | SourceLocation TypeidLoc, |
5835 | TypeSourceInfo *Operand, |
5836 | SourceLocation RParenLoc); |
5837 | ExprResult BuildCXXUuidof(QualType TypeInfoType, |
5838 | SourceLocation TypeidLoc, |
5839 | Expr *Operand, |
5840 | SourceLocation RParenLoc); |
5841 | |
5842 | /// ActOnCXXUuidof - Parse __uuidof( something ). |
5843 | ExprResult ActOnCXXUuidof(SourceLocation OpLoc, |
5844 | SourceLocation LParenLoc, bool isType, |
5845 | void *TyOrExpr, |
5846 | SourceLocation RParenLoc); |
5847 | |
5848 | /// Handle a C++1z fold-expression: ( expr op ... op expr ). |
5849 | ExprResult ActOnCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS, |
5850 | tok::TokenKind Operator, |
5851 | SourceLocation EllipsisLoc, Expr *RHS, |
5852 | SourceLocation RParenLoc); |
5853 | ExprResult BuildCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS, |
5854 | BinaryOperatorKind Operator, |
5855 | SourceLocation EllipsisLoc, Expr *RHS, |
5856 | SourceLocation RParenLoc, |
5857 | Optional<unsigned> NumExpansions); |
5858 | ExprResult BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc, |
5859 | BinaryOperatorKind Operator); |
5860 | |
5861 | //// ActOnCXXThis - Parse 'this' pointer. |
5862 | ExprResult ActOnCXXThis(SourceLocation loc); |
5863 | |
5864 | /// Build a CXXThisExpr and mark it referenced in the current context. |
5865 | Expr *BuildCXXThisExpr(SourceLocation Loc, QualType Type, bool IsImplicit); |
5866 | void MarkThisReferenced(CXXThisExpr *This); |
5867 | |
5868 | /// Try to retrieve the type of the 'this' pointer. |
5869 | /// |
5870 | /// \returns The type of 'this', if possible. Otherwise, returns a NULL type. |
5871 | QualType getCurrentThisType(); |
5872 | |
5873 | /// When non-NULL, the C++ 'this' expression is allowed despite the |
5874 | /// current context not being a non-static member function. In such cases, |
5875 | /// this provides the type used for 'this'. |
5876 | QualType CXXThisTypeOverride; |
5877 | |
5878 | /// RAII object used to temporarily allow the C++ 'this' expression |
5879 | /// to be used, with the given qualifiers on the current class type. |
5880 | class CXXThisScopeRAII { |
5881 | Sema &S; |
5882 | QualType OldCXXThisTypeOverride; |
5883 | bool Enabled; |
5884 | |
5885 | public: |
5886 | /// Introduce a new scope where 'this' may be allowed (when enabled), |
5887 | /// using the given declaration (which is either a class template or a |
5888 | /// class) along with the given qualifiers. |
5889 | /// along with the qualifiers placed on '*this'. |
5890 | CXXThisScopeRAII(Sema &S, Decl *ContextDecl, Qualifiers CXXThisTypeQuals, |
5891 | bool Enabled = true); |
5892 | |
5893 | ~CXXThisScopeRAII(); |
5894 | }; |
5895 | |
5896 | /// Make sure the value of 'this' is actually available in the current |
5897 | /// context, if it is a potentially evaluated context. |
5898 | /// |
5899 | /// \param Loc The location at which the capture of 'this' occurs. |
5900 | /// |
5901 | /// \param Explicit Whether 'this' is explicitly captured in a lambda |
5902 | /// capture list. |
5903 | /// |
5904 | /// \param FunctionScopeIndexToStopAt If non-null, it points to the index |
5905 | /// of the FunctionScopeInfo stack beyond which we do not attempt to capture. |
5906 | /// This is useful when enclosing lambdas must speculatively capture |
5907 | /// 'this' that may or may not be used in certain specializations of |
5908 | /// a nested generic lambda (depending on whether the name resolves to |
5909 | /// a non-static member function or a static function). |
5910 | /// \return returns 'true' if failed, 'false' if success. |
5911 | bool CheckCXXThisCapture(SourceLocation Loc, bool Explicit = false, |
5912 | bool BuildAndDiagnose = true, |
5913 | const unsigned *const FunctionScopeIndexToStopAt = nullptr, |
5914 | bool ByCopy = false); |
5915 | |
5916 | /// Determine whether the given type is the type of *this that is used |
5917 | /// outside of the body of a member function for a type that is currently |
5918 | /// being defined. |
5919 | bool isThisOutsideMemberFunctionBody(QualType BaseType); |
5920 | |
5921 | /// ActOnCXXBoolLiteral - Parse {true,false} literals. |
5922 | ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind); |
5923 | |
5924 | |
5925 | /// ActOnObjCBoolLiteral - Parse {__objc_yes,__objc_no} literals. |
5926 | ExprResult ActOnObjCBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind); |
5927 | |
5928 | ExprResult |
5929 | ActOnObjCAvailabilityCheckExpr(llvm::ArrayRef<AvailabilitySpec> AvailSpecs, |
5930 | SourceLocation AtLoc, SourceLocation RParen); |
5931 | |
5932 | /// ActOnCXXNullPtrLiteral - Parse 'nullptr'. |
5933 | ExprResult ActOnCXXNullPtrLiteral(SourceLocation Loc); |
5934 | |
5935 | //// ActOnCXXThrow - Parse throw expressions. |
5936 | ExprResult ActOnCXXThrow(Scope *S, SourceLocation OpLoc, Expr *expr); |
5937 | ExprResult BuildCXXThrow(SourceLocation OpLoc, Expr *Ex, |
5938 | bool IsThrownVarInScope); |
5939 | bool CheckCXXThrowOperand(SourceLocation ThrowLoc, QualType ThrowTy, Expr *E); |
5940 | |
5941 | /// ActOnCXXTypeConstructExpr - Parse construction of a specified type. |
5942 | /// Can be interpreted either as function-style casting ("int(x)") |
5943 | /// or class type construction ("ClassType(x,y,z)") |
5944 | /// or creation of a value-initialized type ("int()"). |
5945 | ExprResult ActOnCXXTypeConstructExpr(ParsedType TypeRep, |
5946 | SourceLocation LParenOrBraceLoc, |
5947 | MultiExprArg Exprs, |
5948 | SourceLocation RParenOrBraceLoc, |
5949 | bool ListInitialization); |
5950 | |
5951 | ExprResult BuildCXXTypeConstructExpr(TypeSourceInfo *Type, |
5952 | SourceLocation LParenLoc, |
5953 | MultiExprArg Exprs, |
5954 | SourceLocation RParenLoc, |
5955 | bool ListInitialization); |
5956 | |
5957 | /// ActOnCXXNew - Parsed a C++ 'new' expression. |
5958 | ExprResult ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, |
5959 | SourceLocation PlacementLParen, |
5960 | MultiExprArg PlacementArgs, |
5961 | SourceLocation PlacementRParen, |
5962 | SourceRange TypeIdParens, Declarator &D, |
5963 | Expr *Initializer); |
5964 | ExprResult BuildCXXNew(SourceRange Range, bool UseGlobal, |
5965 | SourceLocation PlacementLParen, |
5966 | MultiExprArg PlacementArgs, |
5967 | SourceLocation PlacementRParen, |
5968 | SourceRange TypeIdParens, |
5969 | QualType AllocType, |
5970 | TypeSourceInfo *AllocTypeInfo, |
5971 | Optional<Expr *> ArraySize, |
5972 | SourceRange DirectInitRange, |
5973 | Expr *Initializer); |
5974 | |
5975 | /// Determine whether \p FD is an aligned allocation or deallocation |
5976 | /// function that is unavailable. |
5977 | bool isUnavailableAlignedAllocationFunction(const FunctionDecl &FD) const; |
5978 | |
5979 | /// Produce diagnostics if \p FD is an aligned allocation or deallocation |
5980 | /// function that is unavailable. |
5981 | void diagnoseUnavailableAlignedAllocation(const FunctionDecl &FD, |
5982 | SourceLocation Loc); |
5983 | |
5984 | bool CheckAllocatedType(QualType AllocType, SourceLocation Loc, |
5985 | SourceRange R); |
5986 | |
5987 | /// The scope in which to find allocation functions. |
5988 | enum AllocationFunctionScope { |
5989 | /// Only look for allocation functions in the global scope. |
5990 | AFS_Global, |
5991 | /// Only look for allocation functions in the scope of the |
5992 | /// allocated class. |
5993 | AFS_Class, |
5994 | /// Look for allocation functions in both the global scope |
5995 | /// and in the scope of the allocated class. |
5996 | AFS_Both |
5997 | }; |
5998 | |
5999 | /// Finds the overloads of operator new and delete that are appropriate |
6000 | /// for the allocation. |
6001 | bool FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, |
6002 | AllocationFunctionScope NewScope, |
6003 | AllocationFunctionScope DeleteScope, |
6004 | QualType AllocType, bool IsArray, |
6005 | bool &PassAlignment, MultiExprArg PlaceArgs, |
6006 | FunctionDecl *&OperatorNew, |
6007 | FunctionDecl *&OperatorDelete, |
6008 | bool Diagnose = true); |
6009 | void DeclareGlobalNewDelete(); |
6010 | void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return, |
6011 | ArrayRef<QualType> Params); |
6012 | |
6013 | bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD, |
6014 | DeclarationName Name, FunctionDecl* &Operator, |
6015 | bool Diagnose = true); |
6016 | FunctionDecl *FindUsualDeallocationFunction(SourceLocation StartLoc, |
6017 | bool CanProvideSize, |
6018 | bool Overaligned, |
6019 | DeclarationName Name); |
6020 | FunctionDecl *FindDeallocationFunctionForDestructor(SourceLocation StartLoc, |
6021 | CXXRecordDecl *RD); |
6022 | |
6023 | /// ActOnCXXDelete - Parsed a C++ 'delete' expression |
6024 | ExprResult ActOnCXXDelete(SourceLocation StartLoc, |
6025 | bool UseGlobal, bool ArrayForm, |
6026 | Expr *Operand); |
6027 | void CheckVirtualDtorCall(CXXDestructorDecl *dtor, SourceLocation Loc, |
6028 | bool IsDelete, bool CallCanBeVirtual, |
6029 | bool WarnOnNonAbstractTypes, |
6030 | SourceLocation DtorLoc); |
6031 | |
6032 | ExprResult ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation LParen, |
6033 | Expr *Operand, SourceLocation RParen); |
6034 | ExprResult BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand, |
6035 | SourceLocation RParen); |
6036 | |
6037 | /// Parsed one of the type trait support pseudo-functions. |
6038 | ExprResult ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc, |
6039 | ArrayRef<ParsedType> Args, |
6040 | SourceLocation RParenLoc); |
6041 | ExprResult BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc, |
6042 | ArrayRef<TypeSourceInfo *> Args, |
6043 | SourceLocation RParenLoc); |
6044 | |
6045 | /// ActOnArrayTypeTrait - Parsed one of the binary type trait support |
6046 | /// pseudo-functions. |
6047 | ExprResult ActOnArrayTypeTrait(ArrayTypeTrait ATT, |
6048 | SourceLocation KWLoc, |
6049 | ParsedType LhsTy, |
6050 | Expr *DimExpr, |
6051 | SourceLocation RParen); |
6052 | |
6053 | ExprResult BuildArrayTypeTrait(ArrayTypeTrait ATT, |
6054 | SourceLocation KWLoc, |
6055 | TypeSourceInfo *TSInfo, |
6056 | Expr *DimExpr, |
6057 | SourceLocation RParen); |
6058 | |
6059 | /// ActOnExpressionTrait - Parsed one of the unary type trait support |
6060 | /// pseudo-functions. |
6061 | ExprResult ActOnExpressionTrait(ExpressionTrait OET, |
6062 | SourceLocation KWLoc, |
6063 | Expr *Queried, |
6064 | SourceLocation RParen); |
6065 | |
6066 | ExprResult BuildExpressionTrait(ExpressionTrait OET, |
6067 | SourceLocation KWLoc, |
6068 | Expr *Queried, |
6069 | SourceLocation RParen); |
6070 | |
6071 | ExprResult ActOnStartCXXMemberReference(Scope *S, |
6072 | Expr *Base, |
6073 | SourceLocation OpLoc, |
6074 | tok::TokenKind OpKind, |
6075 | ParsedType &ObjectType, |
6076 | bool &MayBePseudoDestructor); |
6077 | |
6078 | ExprResult BuildPseudoDestructorExpr(Expr *Base, |
6079 | SourceLocation OpLoc, |
6080 | tok::TokenKind OpKind, |
6081 | const CXXScopeSpec &SS, |
6082 | TypeSourceInfo *ScopeType, |
6083 | SourceLocation CCLoc, |
6084 | SourceLocation TildeLoc, |
6085 | PseudoDestructorTypeStorage DestroyedType); |
6086 | |
6087 | ExprResult ActOnPseudoDestructorExpr(Scope *S, Expr *Base, |
6088 | SourceLocation OpLoc, |
6089 | tok::TokenKind OpKind, |
6090 | CXXScopeSpec &SS, |
6091 | UnqualifiedId &FirstTypeName, |
6092 | SourceLocation CCLoc, |
6093 | SourceLocation TildeLoc, |
6094 | UnqualifiedId &SecondTypeName); |
6095 | |
6096 | ExprResult ActOnPseudoDestructorExpr(Scope *S, Expr *Base, |
6097 | SourceLocation OpLoc, |
6098 | tok::TokenKind OpKind, |
6099 | SourceLocation TildeLoc, |
6100 | const DeclSpec& DS); |
6101 | |
6102 | /// MaybeCreateExprWithCleanups - If the current full-expression |
6103 | /// requires any cleanups, surround it with a ExprWithCleanups node. |
6104 | /// Otherwise, just returns the passed-in expression. |
6105 | Expr *MaybeCreateExprWithCleanups(Expr *SubExpr); |
6106 | Stmt *MaybeCreateStmtWithCleanups(Stmt *SubStmt); |
6107 | ExprResult MaybeCreateExprWithCleanups(ExprResult SubExpr); |
6108 | |
6109 | MaterializeTemporaryExpr * |
6110 | CreateMaterializeTemporaryExpr(QualType T, Expr *Temporary, |
6111 | bool BoundToLvalueReference); |
6112 | |
6113 | ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue) { |
6114 | return ActOnFinishFullExpr( |
6115 | Expr, Expr ? Expr->getExprLoc() : SourceLocation(), DiscardedValue); |
6116 | } |
6117 | ExprResult ActOnFinishFullExpr(Expr *Expr, SourceLocation CC, |
6118 | bool DiscardedValue, bool IsConstexpr = false); |
6119 | StmtResult ActOnFinishFullStmt(Stmt *Stmt); |
6120 | |
6121 | // Marks SS invalid if it represents an incomplete type. |
6122 | bool RequireCompleteDeclContext(CXXScopeSpec &SS, DeclContext *DC); |
6123 | |
6124 | DeclContext *computeDeclContext(QualType T); |
6125 | DeclContext *computeDeclContext(const CXXScopeSpec &SS, |
6126 | bool EnteringContext = false); |
6127 | bool isDependentScopeSpecifier(const CXXScopeSpec &SS); |
6128 | CXXRecordDecl *getCurrentInstantiationOf(NestedNameSpecifier *NNS); |
6129 | |
6130 | /// The parser has parsed a global nested-name-specifier '::'. |
6131 | /// |
6132 | /// \param CCLoc The location of the '::'. |
6133 | /// |
6134 | /// \param SS The nested-name-specifier, which will be updated in-place |
6135 | /// to reflect the parsed nested-name-specifier. |
6136 | /// |
6137 | /// \returns true if an error occurred, false otherwise. |
6138 | bool ActOnCXXGlobalScopeSpecifier(SourceLocation CCLoc, CXXScopeSpec &SS); |
6139 | |
6140 | /// The parser has parsed a '__super' nested-name-specifier. |
6141 | /// |
6142 | /// \param SuperLoc The location of the '__super' keyword. |
6143 | /// |
6144 | /// \param ColonColonLoc The location of the '::'. |
6145 | /// |
6146 | /// \param SS The nested-name-specifier, which will be updated in-place |
6147 | /// to reflect the parsed nested-name-specifier. |
6148 | /// |
6149 | /// \returns true if an error occurred, false otherwise. |
6150 | bool ActOnSuperScopeSpecifier(SourceLocation SuperLoc, |
6151 | SourceLocation ColonColonLoc, CXXScopeSpec &SS); |
6152 | |
6153 | bool isAcceptableNestedNameSpecifier(const NamedDecl *SD, |
6154 | bool *CanCorrect = nullptr); |
6155 | NamedDecl *FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS); |
6156 | |
6157 | /// Keeps information about an identifier in a nested-name-spec. |
6158 | /// |
6159 | struct NestedNameSpecInfo { |
6160 | /// The type of the object, if we're parsing nested-name-specifier in |
6161 | /// a member access expression. |
6162 | ParsedType ObjectType; |
6163 | |
6164 | /// The identifier preceding the '::'. |
6165 | IdentifierInfo *Identifier; |
6166 | |
6167 | /// The location of the identifier. |
6168 | SourceLocation IdentifierLoc; |
6169 | |
6170 | /// The location of the '::'. |
6171 | SourceLocation CCLoc; |
6172 | |
6173 | /// Creates info object for the most typical case. |
6174 | NestedNameSpecInfo(IdentifierInfo *II, SourceLocation IdLoc, |
6175 | SourceLocation ColonColonLoc, ParsedType ObjectType = ParsedType()) |
6176 | : ObjectType(ObjectType), Identifier(II), IdentifierLoc(IdLoc), |
6177 | CCLoc(ColonColonLoc) { |
6178 | } |
6179 | |
6180 | NestedNameSpecInfo(IdentifierInfo *II, SourceLocation IdLoc, |
6181 | SourceLocation ColonColonLoc, QualType ObjectType) |
6182 | : ObjectType(ParsedType::make(ObjectType)), Identifier(II), |
6183 | IdentifierLoc(IdLoc), CCLoc(ColonColonLoc) { |
6184 | } |
6185 | }; |
6186 | |
6187 | bool isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS, |
6188 | NestedNameSpecInfo &IdInfo); |
6189 | |
6190 | bool BuildCXXNestedNameSpecifier(Scope *S, |
6191 | NestedNameSpecInfo &IdInfo, |
6192 | bool EnteringContext, |
6193 | CXXScopeSpec &SS, |
6194 | NamedDecl *ScopeLookupResult, |
6195 | bool ErrorRecoveryLookup, |
6196 | bool *IsCorrectedToColon = nullptr, |
6197 | bool OnlyNamespace = false); |
6198 | |
6199 | /// The parser has parsed a nested-name-specifier 'identifier::'. |
6200 | /// |
6201 | /// \param S The scope in which this nested-name-specifier occurs. |
6202 | /// |
6203 | /// \param IdInfo Parser information about an identifier in the |
6204 | /// nested-name-spec. |
6205 | /// |
6206 | /// \param EnteringContext Whether we're entering the context nominated by |
6207 | /// this nested-name-specifier. |
6208 | /// |
6209 | /// \param SS The nested-name-specifier, which is both an input |
6210 | /// parameter (the nested-name-specifier before this type) and an |
6211 | /// output parameter (containing the full nested-name-specifier, |
6212 | /// including this new type). |
6213 | /// |
6214 | /// \param ErrorRecoveryLookup If true, then this method is called to improve |
6215 | /// error recovery. In this case do not emit error message. |
6216 | /// |
6217 | /// \param IsCorrectedToColon If not null, suggestions to replace '::' -> ':' |
6218 | /// are allowed. The bool value pointed by this parameter is set to 'true' |
6219 | /// if the identifier is treated as if it was followed by ':', not '::'. |
6220 | /// |
6221 | /// \param OnlyNamespace If true, only considers namespaces in lookup. |
6222 | /// |
6223 | /// \returns true if an error occurred, false otherwise. |
6224 | bool ActOnCXXNestedNameSpecifier(Scope *S, |
6225 | NestedNameSpecInfo &IdInfo, |
6226 | bool EnteringContext, |
6227 | CXXScopeSpec &SS, |
6228 | bool ErrorRecoveryLookup = false, |
6229 | bool *IsCorrectedToColon = nullptr, |
6230 | bool OnlyNamespace = false); |
6231 | |
6232 | ExprResult ActOnDecltypeExpression(Expr *E); |
6233 | |
6234 | bool ActOnCXXNestedNameSpecifierDecltype(CXXScopeSpec &SS, |
6235 | const DeclSpec &DS, |
6236 | SourceLocation ColonColonLoc); |
6237 | |
6238 | bool IsInvalidUnlessNestedName(Scope *S, CXXScopeSpec &SS, |
6239 | NestedNameSpecInfo &IdInfo, |
6240 | bool EnteringContext); |
6241 | |
6242 | /// The parser has parsed a nested-name-specifier |
6243 | /// 'template[opt] template-name < template-args >::'. |
6244 | /// |
6245 | /// \param S The scope in which this nested-name-specifier occurs. |
6246 | /// |
6247 | /// \param SS The nested-name-specifier, which is both an input |
6248 | /// parameter (the nested-name-specifier before this type) and an |
6249 | /// output parameter (containing the full nested-name-specifier, |
6250 | /// including this new type). |
6251 | /// |
6252 | /// \param TemplateKWLoc the location of the 'template' keyword, if any. |
6253 | /// \param TemplateName the template name. |
6254 | /// \param TemplateNameLoc The location of the template name. |
6255 | /// \param LAngleLoc The location of the opening angle bracket ('<'). |
6256 | /// \param TemplateArgs The template arguments. |
6257 | /// \param RAngleLoc The location of the closing angle bracket ('>'). |
6258 | /// \param CCLoc The location of the '::'. |
6259 | /// |
6260 | /// \param EnteringContext Whether we're entering the context of the |
6261 | /// nested-name-specifier. |
6262 | /// |
6263 | /// |
6264 | /// \returns true if an error occurred, false otherwise. |
6265 | bool ActOnCXXNestedNameSpecifier(Scope *S, |
6266 | CXXScopeSpec &SS, |
6267 | SourceLocation TemplateKWLoc, |
6268 | TemplateTy TemplateName, |
6269 | SourceLocation TemplateNameLoc, |
6270 | SourceLocation LAngleLoc, |
6271 | ASTTemplateArgsPtr TemplateArgs, |
6272 | SourceLocation RAngleLoc, |
6273 | SourceLocation CCLoc, |
6274 | bool EnteringContext); |
6275 | |
6276 | /// Given a C++ nested-name-specifier, produce an annotation value |
6277 | /// that the parser can use later to reconstruct the given |
6278 | /// nested-name-specifier. |
6279 | /// |
6280 | /// \param SS A nested-name-specifier. |
6281 | /// |
6282 | /// \returns A pointer containing all of the information in the |
6283 | /// nested-name-specifier \p SS. |
6284 | void *SaveNestedNameSpecifierAnnotation(CXXScopeSpec &SS); |
6285 | |
6286 | /// Given an annotation pointer for a nested-name-specifier, restore |
6287 | /// the nested-name-specifier structure. |
6288 | /// |
6289 | /// \param Annotation The annotation pointer, produced by |
6290 | /// \c SaveNestedNameSpecifierAnnotation(). |
6291 | /// |
6292 | /// \param AnnotationRange The source range corresponding to the annotation. |
6293 | /// |
6294 | /// \param SS The nested-name-specifier that will be updated with the contents |
6295 | /// of the annotation pointer. |
6296 | void RestoreNestedNameSpecifierAnnotation(void *Annotation, |
6297 | SourceRange AnnotationRange, |
6298 | CXXScopeSpec &SS); |
6299 | |
6300 | bool ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS); |
6301 | |
6302 | /// ActOnCXXEnterDeclaratorScope - Called when a C++ scope specifier (global |
6303 | /// scope or nested-name-specifier) is parsed, part of a declarator-id. |
6304 | /// After this method is called, according to [C++ 3.4.3p3], names should be |
6305 | /// looked up in the declarator-id's scope, until the declarator is parsed and |
6306 | /// ActOnCXXExitDeclaratorScope is called. |
6307 | /// The 'SS' should be a non-empty valid CXXScopeSpec. |
6308 | bool ActOnCXXEnterDeclaratorScope(Scope *S, CXXScopeSpec &SS); |
6309 | |
6310 | /// ActOnCXXExitDeclaratorScope - Called when a declarator that previously |
6311 | /// invoked ActOnCXXEnterDeclaratorScope(), is finished. 'SS' is the same |
6312 | /// CXXScopeSpec that was passed to ActOnCXXEnterDeclaratorScope as well. |
6313 | /// Used to indicate that names should revert to being looked up in the |
6314 | /// defining scope. |
6315 | void ActOnCXXExitDeclaratorScope(Scope *S, const CXXScopeSpec &SS); |
6316 | |
6317 | /// ActOnCXXEnterDeclInitializer - Invoked when we are about to parse an |
6318 | /// initializer for the declaration 'Dcl'. |
6319 | /// After this method is called, according to [C++ 3.4.1p13], if 'Dcl' is a |
6320 | /// static data member of class X, names should be looked up in the scope of |
6321 | /// class X. |
6322 | void ActOnCXXEnterDeclInitializer(Scope *S, Decl *Dcl); |
6323 | |
6324 | /// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an |
6325 | /// initializer for the declaration 'Dcl'. |
6326 | void ActOnCXXExitDeclInitializer(Scope *S, Decl *Dcl); |
6327 | |
6328 | /// Create a new lambda closure type. |
6329 | CXXRecordDecl *createLambdaClosureType(SourceRange IntroducerRange, |
6330 | TypeSourceInfo *Info, |
6331 | bool KnownDependent, |
6332 | LambdaCaptureDefault CaptureDefault); |
6333 | |
6334 | /// Start the definition of a lambda expression. |
6335 | CXXMethodDecl *startLambdaDefinition(CXXRecordDecl *Class, |
6336 | SourceRange IntroducerRange, |
6337 | TypeSourceInfo *MethodType, |
6338 | SourceLocation EndLoc, |
6339 | ArrayRef<ParmVarDecl *> Params, |
6340 | ConstexprSpecKind ConstexprKind, |
6341 | Expr *TrailingRequiresClause); |
6342 | |
6343 | /// Number lambda for linkage purposes if necessary. |
6344 | void handleLambdaNumbering( |
6345 | CXXRecordDecl *Class, CXXMethodDecl *Method, |
6346 | Optional<std::tuple<unsigned, bool, Decl *>> Mangling = None); |
6347 | |
6348 | /// Endow the lambda scope info with the relevant properties. |
6349 | void buildLambdaScope(sema::LambdaScopeInfo *LSI, |
6350 | CXXMethodDecl *CallOperator, |
6351 | SourceRange IntroducerRange, |
6352 | LambdaCaptureDefault CaptureDefault, |
6353 | SourceLocation CaptureDefaultLoc, |
6354 | bool ExplicitParams, |
6355 | bool ExplicitResultType, |
6356 | bool Mutable); |
6357 | |
6358 | /// Perform initialization analysis of the init-capture and perform |
6359 | /// any implicit conversions such as an lvalue-to-rvalue conversion if |
6360 | /// not being used to initialize a reference. |
6361 | ParsedType actOnLambdaInitCaptureInitialization( |
6362 | SourceLocation Loc, bool ByRef, SourceLocation EllipsisLoc, |
6363 | IdentifierInfo *Id, LambdaCaptureInitKind InitKind, Expr *&Init) { |
6364 | return ParsedType::make(buildLambdaInitCaptureInitialization( |
6365 | Loc, ByRef, EllipsisLoc, None, Id, |
6366 | InitKind != LambdaCaptureInitKind::CopyInit, Init)); |
6367 | } |
6368 | QualType buildLambdaInitCaptureInitialization( |
6369 | SourceLocation Loc, bool ByRef, SourceLocation EllipsisLoc, |
6370 | Optional<unsigned> NumExpansions, IdentifierInfo *Id, bool DirectInit, |
6371 | Expr *&Init); |
6372 | |
6373 | /// Create a dummy variable within the declcontext of the lambda's |
6374 | /// call operator, for name lookup purposes for a lambda init capture. |
6375 | /// |
6376 | /// CodeGen handles emission of lambda captures, ignoring these dummy |
6377 | /// variables appropriately. |
6378 | VarDecl *createLambdaInitCaptureVarDecl(SourceLocation Loc, |
6379 | QualType InitCaptureType, |
6380 | SourceLocation EllipsisLoc, |
6381 | IdentifierInfo *Id, |
6382 | unsigned InitStyle, Expr *Init); |
6383 | |
6384 | /// Add an init-capture to a lambda scope. |
6385 | void addInitCapture(sema::LambdaScopeInfo *LSI, VarDecl *Var); |
6386 | |
6387 | /// Note that we have finished the explicit captures for the |
6388 | /// given lambda. |
6389 | void finishLambdaExplicitCaptures(sema::LambdaScopeInfo *LSI); |
6390 | |
6391 | /// \brief This is called after parsing the explicit template parameter list |
6392 | /// on a lambda (if it exists) in C++2a. |
6393 | void ActOnLambdaExplicitTemplateParameterList(SourceLocation LAngleLoc, |
6394 | ArrayRef<NamedDecl *> TParams, |
6395 | SourceLocation RAngleLoc); |
6396 | |
6397 | /// Introduce the lambda parameters into scope. |
6398 | void addLambdaParameters( |
6399 | ArrayRef<LambdaIntroducer::LambdaCapture> Captures, |
6400 | CXXMethodDecl *CallOperator, Scope *CurScope); |
6401 | |
6402 | /// Deduce a block or lambda's return type based on the return |
6403 | /// statements present in the body. |
6404 | void deduceClosureReturnType(sema::CapturingScopeInfo &CSI); |
6405 | |
6406 | /// ActOnStartOfLambdaDefinition - This is called just before we start |
6407 | /// parsing the body of a lambda; it analyzes the explicit captures and |
6408 | /// arguments, and sets up various data-structures for the body of the |
6409 | /// lambda. |
6410 | void ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, |
6411 | Declarator &ParamInfo, Scope *CurScope); |
6412 | |
6413 | /// ActOnLambdaError - If there is an error parsing a lambda, this callback |
6414 | /// is invoked to pop the information about the lambda. |
6415 | void ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope, |
6416 | bool IsInstantiation = false); |
6417 | |
6418 | /// ActOnLambdaExpr - This is called when the body of a lambda expression |
6419 | /// was successfully completed. |
6420 | ExprResult ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body, |
6421 | Scope *CurScope); |
6422 | |
6423 | /// Does copying/destroying the captured variable have side effects? |
6424 | bool CaptureHasSideEffects(const sema::Capture &From); |
6425 | |
6426 | /// Diagnose if an explicit lambda capture is unused. Returns true if a |
6427 | /// diagnostic is emitted. |
6428 | bool DiagnoseUnusedLambdaCapture(SourceRange CaptureRange, |
6429 | const sema::Capture &From); |
6430 | |
6431 | /// Build a FieldDecl suitable to hold the given capture. |
6432 | FieldDecl *BuildCaptureField(RecordDecl *RD, const sema::Capture &Capture); |
6433 | |
6434 | /// Initialize the given capture with a suitable expression. |
6435 | ExprResult BuildCaptureInit(const sema::Capture &Capture, |
6436 | SourceLocation ImplicitCaptureLoc, |
6437 | bool IsOpenMPMapping = false); |
6438 | |
6439 | /// Complete a lambda-expression having processed and attached the |
6440 | /// lambda body. |
6441 | ExprResult BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc, |
6442 | sema::LambdaScopeInfo *LSI); |
6443 | |
6444 | /// Get the return type to use for a lambda's conversion function(s) to |
6445 | /// function pointer type, given the type of the call operator. |
6446 | QualType |
6447 | getLambdaConversionFunctionResultType(const FunctionProtoType *CallOpType); |
6448 | |
6449 | /// Define the "body" of the conversion from a lambda object to a |
6450 | /// function pointer. |
6451 | /// |
6452 | /// This routine doesn't actually define a sensible body; rather, it fills |
6453 | /// in the initialization expression needed to copy the lambda object into |
6454 | /// the block, and IR generation actually generates the real body of the |
6455 | /// block pointer conversion. |
6456 | void DefineImplicitLambdaToFunctionPointerConversion( |
6457 | SourceLocation CurrentLoc, CXXConversionDecl *Conv); |
6458 | |
6459 | /// Define the "body" of the conversion from a lambda object to a |
6460 | /// block pointer. |
6461 | /// |
6462 | /// This routine doesn't actually define a sensible body; rather, it fills |
6463 | /// in the initialization expression needed to copy the lambda object into |
6464 | /// the block, and IR generation actually generates the real body of the |
6465 | /// block pointer conversion. |
6466 | void DefineImplicitLambdaToBlockPointerConversion(SourceLocation CurrentLoc, |
6467 | CXXConversionDecl *Conv); |
6468 | |
6469 | ExprResult BuildBlockForLambdaConversion(SourceLocation CurrentLocation, |
6470 | SourceLocation ConvLocation, |
6471 | CXXConversionDecl *Conv, |
6472 | Expr *Src); |
6473 | |
6474 | /// Check whether the given expression is a valid constraint expression. |
6475 | /// A diagnostic is emitted if it is not, false is returned, and |
6476 | /// PossibleNonPrimary will be set to true if the failure might be due to a |
6477 | /// non-primary expression being used as an atomic constraint. |
6478 | bool CheckConstraintExpression(const Expr *CE, Token NextToken = Token(), |
6479 | bool *PossibleNonPrimary = nullptr, |
6480 | bool IsTrailingRequiresClause = false); |
6481 | |
6482 | private: |
6483 | /// Caches pairs of template-like decls whose associated constraints were |
6484 | /// checked for subsumption and whether or not the first's constraints did in |
6485 | /// fact subsume the second's. |
6486 | llvm::DenseMap<std::pair<NamedDecl *, NamedDecl *>, bool> SubsumptionCache; |
6487 | /// Caches the normalized associated constraints of declarations (concepts or |
6488 | /// constrained declarations). If an error occurred while normalizing the |
6489 | /// associated constraints of the template or concept, nullptr will be cached |
6490 | /// here. |
6491 | llvm::DenseMap<NamedDecl *, NormalizedConstraint *> |
6492 | NormalizationCache; |
6493 | |
6494 | llvm::ContextualFoldingSet<ConstraintSatisfaction, const ASTContext &> |
6495 | SatisfactionCache; |
6496 | |
6497 | public: |
6498 | const NormalizedConstraint * |
6499 | getNormalizedAssociatedConstraints( |
6500 | NamedDecl *ConstrainedDecl, ArrayRef<const Expr *> AssociatedConstraints); |
6501 | |
6502 | /// \brief Check whether the given declaration's associated constraints are |
6503 | /// at least as constrained than another declaration's according to the |
6504 | /// partial ordering of constraints. |
6505 | /// |
6506 | /// \param Result If no error occurred, receives the result of true if D1 is |
6507 | /// at least constrained than D2, and false otherwise. |
6508 | /// |
6509 | /// \returns true if an error occurred, false otherwise. |
6510 | bool IsAtLeastAsConstrained(NamedDecl *D1, ArrayRef<const Expr *> AC1, |
6511 | NamedDecl *D2, ArrayRef<const Expr *> AC2, |
6512 | bool &Result); |
6513 | |
6514 | /// If D1 was not at least as constrained as D2, but would've been if a pair |
6515 | /// of atomic constraints involved had been declared in a concept and not |
6516 | /// repeated in two separate places in code. |
6517 | /// \returns true if such a diagnostic was emitted, false otherwise. |
6518 | bool MaybeEmitAmbiguousAtomicConstraintsDiagnostic(NamedDecl *D1, |
6519 | ArrayRef<const Expr *> AC1, NamedDecl *D2, ArrayRef<const Expr *> AC2); |
6520 | |
6521 | /// \brief Check whether the given list of constraint expressions are |
6522 | /// satisfied (as if in a 'conjunction') given template arguments. |
6523 | /// \param Template the template-like entity that triggered the constraints |
6524 | /// check (either a concept or a constrained entity). |
6525 | /// \param ConstraintExprs a list of constraint expressions, treated as if |
6526 | /// they were 'AND'ed together. |
6527 | /// \param TemplateArgs the list of template arguments to substitute into the |
6528 | /// constraint expression. |
6529 | /// \param TemplateIDRange The source range of the template id that |
6530 | /// caused the constraints check. |
6531 | /// \param Satisfaction if true is returned, will contain details of the |
6532 | /// satisfaction, with enough information to diagnose an unsatisfied |
6533 | /// expression. |
6534 | /// \returns true if an error occurred and satisfaction could not be checked, |
6535 | /// false otherwise. |
6536 | bool CheckConstraintSatisfaction( |
6537 | const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs, |
6538 | ArrayRef<TemplateArgument> TemplateArgs, |
6539 | SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction); |
6540 | |
6541 | /// \brief Check whether the given non-dependent constraint expression is |
6542 | /// satisfied. Returns false and updates Satisfaction with the satisfaction |
6543 | /// verdict if successful, emits a diagnostic and returns true if an error |
6544 | /// occured and satisfaction could not be determined. |
6545 | /// |
6546 | /// \returns true if an error occurred, false otherwise. |
6547 | bool CheckConstraintSatisfaction(const Expr *ConstraintExpr, |
6548 | ConstraintSatisfaction &Satisfaction); |
6549 | |
6550 | /// Check whether the given function decl's trailing requires clause is |
6551 | /// satisfied, if any. Returns false and updates Satisfaction with the |
6552 | /// satisfaction verdict if successful, emits a diagnostic and returns true if |
6553 | /// an error occured and satisfaction could not be determined. |
6554 | /// |
6555 | /// \returns true if an error occurred, false otherwise. |
6556 | bool CheckFunctionConstraints(const FunctionDecl *FD, |
6557 | ConstraintSatisfaction &Satisfaction, |
6558 | SourceLocation UsageLoc = SourceLocation()); |
6559 | |
6560 | |
6561 | /// \brief Ensure that the given template arguments satisfy the constraints |
6562 | /// associated with the given template, emitting a diagnostic if they do not. |
6563 | /// |
6564 | /// \param Template The template to which the template arguments are being |
6565 | /// provided. |
6566 | /// |
6567 | /// \param TemplateArgs The converted, canonicalized template arguments. |
6568 | /// |
6569 | /// \param TemplateIDRange The source range of the template id that |
6570 | /// caused the constraints check. |
6571 | /// |
6572 | /// \returns true if the constrains are not satisfied or could not be checked |
6573 | /// for satisfaction, false if the constraints are satisfied. |
6574 | bool EnsureTemplateArgumentListConstraints(TemplateDecl *Template, |
6575 | ArrayRef<TemplateArgument> TemplateArgs, |
6576 | SourceRange TemplateIDRange); |
6577 | |
6578 | /// \brief Emit diagnostics explaining why a constraint expression was deemed |
6579 | /// unsatisfied. |
6580 | /// \param First whether this is the first time an unsatisfied constraint is |
6581 | /// diagnosed for this error. |
6582 | void |
6583 | DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction &Satisfaction, |
6584 | bool First = true); |
6585 | |
6586 | /// \brief Emit diagnostics explaining why a constraint expression was deemed |
6587 | /// unsatisfied. |
6588 | void |
6589 | DiagnoseUnsatisfiedConstraint(const ASTConstraintSatisfaction &Satisfaction, |
6590 | bool First = true); |
6591 | |
6592 | /// \brief Emit diagnostics explaining why a constraint expression was deemed |
6593 | /// unsatisfied because it was ill-formed. |
6594 | void DiagnoseUnsatisfiedIllFormedConstraint(SourceLocation DiagnosticLocation, |
6595 | StringRef Diagnostic); |
6596 | |
6597 | void DiagnoseRedeclarationConstraintMismatch(SourceLocation Old, |
6598 | SourceLocation New); |
6599 | |
6600 | // ParseObjCStringLiteral - Parse Objective-C string literals. |
6601 | ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs, |
6602 | ArrayRef<Expr *> Strings); |
6603 | |
6604 | ExprResult BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S); |
6605 | |
6606 | /// BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the |
6607 | /// numeric literal expression. Type of the expression will be "NSNumber *" |
6608 | /// or "id" if NSNumber is unavailable. |
6609 | ExprResult BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number); |
6610 | ExprResult ActOnObjCBoolLiteral(SourceLocation AtLoc, SourceLocation ValueLoc, |
6611 | bool Value); |
6612 | ExprResult BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements); |
6613 | |
6614 | /// BuildObjCBoxedExpr - builds an ObjCBoxedExpr AST node for the |
6615 | /// '@' prefixed parenthesized expression. The type of the expression will |
6616 | /// either be "NSNumber *", "NSString *" or "NSValue *" depending on the type |
6617 | /// of ValueType, which is allowed to be a built-in numeric type, "char *", |
6618 | /// "const char *" or C structure with attribute 'objc_boxable'. |
6619 | ExprResult BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr); |
6620 | |
6621 | ExprResult BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr, |
6622 | Expr *IndexExpr, |
6623 | ObjCMethodDecl *getterMethod, |
6624 | ObjCMethodDecl *setterMethod); |
6625 | |
6626 | ExprResult BuildObjCDictionaryLiteral(SourceRange SR, |
6627 | MutableArrayRef<ObjCDictionaryElement> Elements); |
6628 | |
6629 | ExprResult BuildObjCEncodeExpression(SourceLocation AtLoc, |
6630 | TypeSourceInfo *EncodedTypeInfo, |
6631 | SourceLocation RParenLoc); |
6632 | ExprResult BuildCXXMemberCallExpr(Expr *Exp, NamedDecl *FoundDecl, |
6633 | CXXConversionDecl *Method, |
6634 | bool HadMultipleCandidates); |
6635 | |
6636 | ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc, |
6637 | SourceLocation EncodeLoc, |
6638 | SourceLocation LParenLoc, |
6639 | ParsedType Ty, |
6640 | SourceLocation RParenLoc); |
6641 | |
6642 | /// ParseObjCSelectorExpression - Build selector expression for \@selector |
6643 | ExprResult ParseObjCSelectorExpression(Selector Sel, |
6644 | SourceLocation AtLoc, |
6645 | SourceLocation SelLoc, |
6646 | SourceLocation LParenLoc, |
6647 | SourceLocation RParenLoc, |
6648 | bool WarnMultipleSelectors); |
6649 | |
6650 | /// ParseObjCProtocolExpression - Build protocol expression for \@protocol |
6651 | ExprResult ParseObjCProtocolExpression(IdentifierInfo * ProtocolName, |
6652 | SourceLocation AtLoc, |
6653 | SourceLocation ProtoLoc, |
6654 | SourceLocation LParenLoc, |
6655 | SourceLocation ProtoIdLoc, |
6656 | SourceLocation RParenLoc); |
6657 | |
6658 | //===--------------------------------------------------------------------===// |
6659 | // C++ Declarations |
6660 | // |
6661 | Decl *ActOnStartLinkageSpecification(Scope *S, |
6662 | SourceLocation ExternLoc, |
6663 | Expr *LangStr, |
6664 | SourceLocation LBraceLoc); |
6665 | Decl *ActOnFinishLinkageSpecification(Scope *S, |
6666 | Decl *LinkageSpec, |
6667 | SourceLocation RBraceLoc); |
6668 | |
6669 | |
6670 | //===--------------------------------------------------------------------===// |
6671 | // C++ Classes |
6672 | // |
6673 | CXXRecordDecl *getCurrentClass(Scope *S, const CXXScopeSpec *SS); |
6674 | bool isCurrentClassName(const IdentifierInfo &II, Scope *S, |
6675 | const CXXScopeSpec *SS = nullptr); |
6676 | bool isCurrentClassNameTypo(IdentifierInfo *&II, const CXXScopeSpec *SS); |
6677 | |
6678 | bool ActOnAccessSpecifier(AccessSpecifier Access, SourceLocation ASLoc, |
6679 | SourceLocation ColonLoc, |
6680 | const ParsedAttributesView &Attrs); |
6681 | |
6682 | NamedDecl *ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, |
6683 | Declarator &D, |
6684 | MultiTemplateParamsArg TemplateParameterLists, |
6685 | Expr *BitfieldWidth, const VirtSpecifiers &VS, |
6686 | InClassInitStyle InitStyle); |
6687 | |
6688 | void ActOnStartCXXInClassMemberInitializer(); |
6689 | void ActOnFinishCXXInClassMemberInitializer(Decl *VarDecl, |
6690 | SourceLocation EqualLoc, |
6691 | Expr *Init); |
6692 | |
6693 | MemInitResult ActOnMemInitializer(Decl *ConstructorD, |
6694 | Scope *S, |
6695 | CXXScopeSpec &SS, |
6696 | IdentifierInfo *MemberOrBase, |
6697 | ParsedType TemplateTypeTy, |
6698 | const DeclSpec &DS, |
6699 | SourceLocation IdLoc, |
6700 | SourceLocation LParenLoc, |
6701 | ArrayRef<Expr *> Args, |
6702 | SourceLocation RParenLoc, |
6703 | SourceLocation EllipsisLoc); |
6704 | |
6705 | MemInitResult ActOnMemInitializer(Decl *ConstructorD, |
6706 | Scope *S, |
6707 | CXXScopeSpec &SS, |
6708 | IdentifierInfo *MemberOrBase, |
6709 | ParsedType TemplateTypeTy, |
6710 | const DeclSpec &DS, |
6711 | SourceLocation IdLoc, |
6712 | Expr *InitList, |
6713 | SourceLocation EllipsisLoc); |
6714 | |
6715 | MemInitResult BuildMemInitializer(Decl *ConstructorD, |
6716 | Scope *S, |
6717 | CXXScopeSpec &SS, |
6718 | IdentifierInfo *MemberOrBase, |
6719 | ParsedType TemplateTypeTy, |
6720 | const DeclSpec &DS, |
6721 | SourceLocation IdLoc, |
6722 | Expr *Init, |
6723 | SourceLocation EllipsisLoc); |
6724 | |
6725 | MemInitResult BuildMemberInitializer(ValueDecl *Member, |
6726 | Expr *Init, |
6727 | SourceLocation IdLoc); |
6728 | |
6729 | MemInitResult BuildBaseInitializer(QualType BaseType, |
6730 | TypeSourceInfo *BaseTInfo, |
6731 | Expr *Init, |
6732 | CXXRecordDecl *ClassDecl, |
6733 | SourceLocation EllipsisLoc); |
6734 | |
6735 | MemInitResult BuildDelegatingInitializer(TypeSourceInfo *TInfo, |
6736 | Expr *Init, |
6737 | CXXRecordDecl *ClassDecl); |
6738 | |
6739 | bool SetDelegatingInitializer(CXXConstructorDecl *Constructor, |
6740 | CXXCtorInitializer *Initializer); |
6741 | |
6742 | bool SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors, |
6743 | ArrayRef<CXXCtorInitializer *> Initializers = None); |
6744 | |
6745 | void SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation); |
6746 | |
6747 | |
6748 | /// MarkBaseAndMemberDestructorsReferenced - Given a record decl, |
6749 | /// mark all the non-trivial destructors of its members and bases as |
6750 | /// referenced. |
6751 | void MarkBaseAndMemberDestructorsReferenced(SourceLocation Loc, |
6752 | CXXRecordDecl *Record); |
6753 | |
6754 | /// Mark destructors of virtual bases of this class referenced. In the Itanium |
6755 | /// C++ ABI, this is done when emitting a destructor for any non-abstract |
6756 | /// class. In the Microsoft C++ ABI, this is done any time a class's |
6757 | /// destructor is referenced. |
6758 | void MarkVirtualBaseDestructorsReferenced( |
6759 | SourceLocation Location, CXXRecordDecl *ClassDecl, |
6760 | llvm::SmallPtrSetImpl<const RecordType *> *DirectVirtualBases = nullptr); |
6761 | |
6762 | /// Do semantic checks to allow the complete destructor variant to be emitted |
6763 | /// when the destructor is defined in another translation unit. In the Itanium |
6764 | /// C++ ABI, destructor variants are emitted together. In the MS C++ ABI, they |
6765 | /// can be emitted in separate TUs. To emit the complete variant, run a subset |
6766 | /// of the checks performed when emitting a regular destructor. |
6767 | void CheckCompleteDestructorVariant(SourceLocation CurrentLocation, |
6768 | CXXDestructorDecl *Dtor); |
6769 | |
6770 | /// The list of classes whose vtables have been used within |
6771 | /// this translation unit, and the source locations at which the |
6772 | /// first use occurred. |
6773 | typedef std::pair<CXXRecordDecl*, SourceLocation> VTableUse; |
6774 | |
6775 | /// The list of vtables that are required but have not yet been |
6776 | /// materialized. |
6777 | SmallVector<VTableUse, 16> VTableUses; |
6778 | |
6779 | /// The set of classes whose vtables have been used within |
6780 | /// this translation unit, and a bit that will be true if the vtable is |
6781 | /// required to be emitted (otherwise, it should be emitted only if needed |
6782 | /// by code generation). |
6783 | llvm::DenseMap<CXXRecordDecl *, bool> VTablesUsed; |
6784 | |
6785 | /// Load any externally-stored vtable uses. |
6786 | void LoadExternalVTableUses(); |
6787 | |
6788 | /// Note that the vtable for the given class was used at the |
6789 | /// given location. |
6790 | void MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class, |
6791 | bool DefinitionRequired = false); |
6792 | |
6793 | /// Mark the exception specifications of all virtual member functions |
6794 | /// in the given class as needed. |
6795 | void MarkVirtualMemberExceptionSpecsNeeded(SourceLocation Loc, |
6796 | const CXXRecordDecl *RD); |
6797 | |
6798 | /// MarkVirtualMembersReferenced - Will mark all members of the given |
6799 | /// CXXRecordDecl referenced. |
6800 | void MarkVirtualMembersReferenced(SourceLocation Loc, const CXXRecordDecl *RD, |
6801 | bool ConstexprOnly = false); |
6802 | |
6803 | /// Define all of the vtables that have been used in this |
6804 | /// translation unit and reference any virtual members used by those |
6805 | /// vtables. |
6806 | /// |
6807 | /// \returns true if any work was done, false otherwise. |
6808 | bool DefineUsedVTables(); |
6809 | |
6810 | void AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl); |
6811 | |
6812 | void ActOnMemInitializers(Decl *ConstructorDecl, |
6813 | SourceLocation ColonLoc, |
6814 | ArrayRef<CXXCtorInitializer*> MemInits, |
6815 | bool AnyErrors); |
6816 | |
6817 | /// Check class-level dllimport/dllexport attribute. The caller must |
6818 | /// ensure that referenceDLLExportedClassMethods is called some point later |
6819 | /// when all outer classes of Class are complete. |
6820 | void checkClassLevelDLLAttribute(CXXRecordDecl *Class); |
6821 | void checkClassLevelCodeSegAttribute(CXXRecordDecl *Class); |
6822 | |
6823 | void referenceDLLExportedClassMethods(); |
6824 | |
6825 | void propagateDLLAttrToBaseClassTemplate( |
6826 | CXXRecordDecl *Class, Attr *ClassAttr, |
6827 | ClassTemplateSpecializationDecl *BaseTemplateSpec, |
6828 | SourceLocation BaseLoc); |
6829 | |
6830 | /// Add gsl::Pointer attribute to std::container::iterator |
6831 | /// \param ND The declaration that introduces the name |
6832 | /// std::container::iterator. \param UnderlyingRecord The record named by ND. |
6833 | void inferGslPointerAttribute(NamedDecl *ND, CXXRecordDecl *UnderlyingRecord); |
6834 | |
6835 | /// Add [[gsl::Owner]] and [[gsl::Pointer]] attributes for std:: types. |
6836 | void inferGslOwnerPointerAttribute(CXXRecordDecl *Record); |
6837 | |
6838 | /// Add [[gsl::Pointer]] attributes for std:: types. |
6839 | void inferGslPointerAttribute(TypedefNameDecl *TD); |
6840 | |
6841 | void CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record); |
6842 | |
6843 | /// Check that the C++ class annoated with "trivial_abi" satisfies all the |
6844 | /// conditions that are needed for the attribute to have an effect. |
6845 | void checkIllFormedTrivialABIStruct(CXXRecordDecl &RD); |
6846 | |
6847 | void ActOnFinishCXXMemberSpecification(Scope *S, SourceLocation RLoc, |
6848 | Decl *TagDecl, SourceLocation LBrac, |
6849 | SourceLocation RBrac, |
6850 | const ParsedAttributesView &AttrList); |
6851 | void ActOnFinishCXXMemberDecls(); |
6852 | void ActOnFinishCXXNonNestedClass(); |
6853 | |
6854 | void ActOnReenterCXXMethodParameter(Scope *S, ParmVarDecl *Param); |
6855 | unsigned ActOnReenterTemplateScope(Decl *Template, |
6856 | llvm::function_ref<Scope *()> EnterScope); |
6857 | void ActOnStartDelayedMemberDeclarations(Scope *S, Decl *Record); |
6858 | void ActOnStartDelayedCXXMethodDeclaration(Scope *S, Decl *Method); |
6859 | void ActOnDelayedCXXMethodParameter(Scope *S, Decl *Param); |
6860 | void ActOnFinishDelayedMemberDeclarations(Scope *S, Decl *Record); |
6861 | void ActOnFinishDelayedCXXMethodDeclaration(Scope *S, Decl *Method); |
6862 | void ActOnFinishDelayedMemberInitializers(Decl *Record); |
6863 | void MarkAsLateParsedTemplate(FunctionDecl *FD, Decl *FnD, |
6864 | CachedTokens &Toks); |
6865 | void UnmarkAsLateParsedTemplate(FunctionDecl *FD); |
6866 | bool IsInsideALocalClassWithinATemplateFunction(); |
6867 | |
6868 | Decl *ActOnStaticAssertDeclaration(SourceLocation StaticAssertLoc, |
6869 | Expr *AssertExpr, |
6870 | Expr *AssertMessageExpr, |
6871 | SourceLocation RParenLoc); |
6872 | Decl *BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc, |
6873 | Expr *AssertExpr, |
6874 | StringLiteral *AssertMessageExpr, |
6875 | SourceLocation RParenLoc, |
6876 | bool Failed); |
6877 | |
6878 | FriendDecl *CheckFriendTypeDecl(SourceLocation LocStart, |
6879 | SourceLocation FriendLoc, |
6880 | TypeSourceInfo *TSInfo); |
6881 | Decl *ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS, |
6882 | MultiTemplateParamsArg TemplateParams); |
6883 | NamedDecl *ActOnFriendFunctionDecl(Scope *S, Declarator &D, |
6884 | MultiTemplateParamsArg TemplateParams); |
6885 | |
6886 | QualType CheckConstructorDeclarator(Declarator &D, QualType R, |
6887 | StorageClass& SC); |
6888 | void CheckConstructor(CXXConstructorDecl *Constructor); |
6889 | QualType CheckDestructorDeclarator(Declarator &D, QualType R, |
6890 | StorageClass& SC); |
6891 | bool CheckDestructor(CXXDestructorDecl *Destructor); |
6892 | void CheckConversionDeclarator(Declarator &D, QualType &R, |
6893 | StorageClass& SC); |
6894 | Decl *ActOnConversionDeclarator(CXXConversionDecl *Conversion); |
6895 | void CheckDeductionGuideDeclarator(Declarator &D, QualType &R, |
6896 | StorageClass &SC); |
6897 | void CheckDeductionGuideTemplate(FunctionTemplateDecl *TD); |
6898 | |
6899 | void CheckExplicitlyDefaultedFunction(Scope *S, FunctionDecl *MD); |
6900 | |
6901 | bool CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD, |
6902 | CXXSpecialMember CSM); |
6903 | void CheckDelayedMemberExceptionSpecs(); |
6904 | |
6905 | bool CheckExplicitlyDefaultedComparison(Scope *S, FunctionDecl *MD, |
6906 | DefaultedComparisonKind DCK); |
6907 | void DeclareImplicitEqualityComparison(CXXRecordDecl *RD, |
6908 | FunctionDecl *Spaceship); |
6909 | void DefineDefaultedComparison(SourceLocation Loc, FunctionDecl *FD, |
6910 | DefaultedComparisonKind DCK); |
6911 | |
6912 | //===--------------------------------------------------------------------===// |
6913 | // C++ Derived Classes |
6914 | // |
6915 | |
6916 | /// ActOnBaseSpecifier - Parsed a base specifier |
6917 | CXXBaseSpecifier *CheckBaseSpecifier(CXXRecordDecl *Class, |
6918 | SourceRange SpecifierRange, |
6919 | bool Virtual, AccessSpecifier Access, |
6920 | TypeSourceInfo *TInfo, |
6921 | SourceLocation EllipsisLoc); |
6922 | |
6923 | BaseResult ActOnBaseSpecifier(Decl *classdecl, |
6924 | SourceRange SpecifierRange, |
6925 | ParsedAttributes &Attrs, |
6926 | bool Virtual, AccessSpecifier Access, |
6927 | ParsedType basetype, |
6928 | SourceLocation BaseLoc, |
6929 | SourceLocation EllipsisLoc); |
6930 | |
6931 | bool AttachBaseSpecifiers(CXXRecordDecl *Class, |
6932 | MutableArrayRef<CXXBaseSpecifier *> Bases); |
6933 | void ActOnBaseSpecifiers(Decl *ClassDecl, |
6934 | MutableArrayRef<CXXBaseSpecifier *> Bases); |
6935 | |
6936 | bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base); |
6937 | bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base, |
6938 | CXXBasePaths &Paths); |
6939 | |
6940 | // FIXME: I don't like this name. |
6941 | void BuildBasePathArray(const CXXBasePaths &Paths, CXXCastPath &BasePath); |
6942 | |
6943 | bool CheckDerivedToBaseConversion(QualType Derived, QualType Base, |
6944 | SourceLocation Loc, SourceRange Range, |
6945 | CXXCastPath *BasePath = nullptr, |
6946 | bool IgnoreAccess = false); |
6947 | bool CheckDerivedToBaseConversion(QualType Derived, QualType Base, |
6948 | unsigned InaccessibleBaseID, |
6949 | unsigned AmbiguousBaseConvID, |
6950 | SourceLocation Loc, SourceRange Range, |
6951 | DeclarationName Name, |
6952 | CXXCastPath *BasePath, |
6953 | bool IgnoreAccess = false); |
6954 | |
6955 | std::string getAmbiguousPathsDisplayString(CXXBasePaths &Paths); |
6956 | |
6957 | bool CheckOverridingFunctionAttributes(const CXXMethodDecl *New, |
6958 | const CXXMethodDecl *Old); |
6959 | |
6960 | /// CheckOverridingFunctionReturnType - Checks whether the return types are |
6961 | /// covariant, according to C++ [class.virtual]p5. |
6962 | bool CheckOverridingFunctionReturnType(const CXXMethodDecl *New, |
6963 | const CXXMethodDecl *Old); |
6964 | |
6965 | /// CheckOverridingFunctionExceptionSpec - Checks whether the exception |
6966 | /// spec is a subset of base spec. |
6967 | bool CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New, |
6968 | const CXXMethodDecl *Old); |
6969 | |
6970 | bool CheckPureMethod(CXXMethodDecl *Method, SourceRange InitRange); |
6971 | |
6972 | /// CheckOverrideControl - Check C++11 override control semantics. |
6973 | void CheckOverrideControl(NamedDecl *D); |
6974 | |
6975 | /// DiagnoseAbsenceOfOverrideControl - Diagnose if 'override' keyword was |
6976 | /// not used in the declaration of an overriding method. |
6977 | void DiagnoseAbsenceOfOverrideControl(NamedDecl *D, bool Inconsistent); |
6978 | |
6979 | /// CheckForFunctionMarkedFinal - Checks whether a virtual member function |
6980 | /// overrides a virtual member function marked 'final', according to |
6981 | /// C++11 [class.virtual]p4. |
6982 | bool CheckIfOverriddenFunctionIsMarkedFinal(const CXXMethodDecl *New, |
6983 | const CXXMethodDecl *Old); |
6984 | |
6985 | |
6986 | //===--------------------------------------------------------------------===// |
6987 | // C++ Access Control |
6988 | // |
6989 | |
6990 | enum AccessResult { |
6991 | AR_accessible, |
6992 | AR_inaccessible, |
6993 | AR_dependent, |
6994 | AR_delayed |
6995 | }; |
6996 | |
6997 | bool SetMemberAccessSpecifier(NamedDecl *MemberDecl, |
6998 | NamedDecl *PrevMemberDecl, |
6999 | AccessSpecifier LexicalAS); |
7000 | |
7001 | AccessResult CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E, |
7002 | DeclAccessPair FoundDecl); |
7003 | AccessResult CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E, |
7004 | DeclAccessPair FoundDecl); |
7005 | AccessResult CheckAllocationAccess(SourceLocation OperatorLoc, |
7006 | SourceRange PlacementRange, |
7007 | CXXRecordDecl *NamingClass, |
7008 | DeclAccessPair FoundDecl, |
7009 | bool Diagnose = true); |
7010 | AccessResult CheckConstructorAccess(SourceLocation Loc, |
7011 | CXXConstructorDecl *D, |
7012 | DeclAccessPair FoundDecl, |
7013 | const InitializedEntity &Entity, |
7014 | bool IsCopyBindingRefToTemp = false); |
7015 | AccessResult CheckConstructorAccess(SourceLocation Loc, |
7016 | CXXConstructorDecl *D, |
7017 | DeclAccessPair FoundDecl, |
7018 | const InitializedEntity &Entity, |
7019 | const PartialDiagnostic &PDiag); |
7020 | AccessResult CheckDestructorAccess(SourceLocation Loc, |
7021 | CXXDestructorDecl *Dtor, |
7022 | const PartialDiagnostic &PDiag, |
7023 | QualType objectType = QualType()); |
7024 | AccessResult CheckFriendAccess(NamedDecl *D); |
7025 | AccessResult CheckMemberAccess(SourceLocation UseLoc, |
7026 | CXXRecordDecl *NamingClass, |
7027 | DeclAccessPair Found); |
7028 | AccessResult |
7029 | CheckStructuredBindingMemberAccess(SourceLocation UseLoc, |
7030 | CXXRecordDecl *DecomposedClass, |
7031 | DeclAccessPair Field); |
7032 | AccessResult CheckMemberOperatorAccess(SourceLocation Loc, |
7033 | Expr *ObjectExpr, |
7034 | Expr *ArgExpr, |
7035 | DeclAccessPair FoundDecl); |
7036 | AccessResult CheckAddressOfMemberAccess(Expr *OvlExpr, |
7037 | DeclAccessPair FoundDecl); |
7038 | AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, |
7039 | QualType Base, QualType Derived, |
7040 | const CXXBasePath &Path, |
7041 | unsigned DiagID, |
7042 | bool ForceCheck = false, |
7043 | bool ForceUnprivileged = false); |
7044 | void CheckLookupAccess(const LookupResult &R); |
7045 | bool IsSimplyAccessible(NamedDecl *Decl, CXXRecordDecl *NamingClass, |
7046 | QualType BaseType); |
7047 | bool isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass, |
7048 | DeclAccessPair Found, QualType ObjectType, |
7049 | SourceLocation Loc, |
7050 | const PartialDiagnostic &Diag); |
7051 | bool isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass, |
7052 | DeclAccessPair Found, |
7053 | QualType ObjectType) { |
7054 | return isMemberAccessibleForDeletion(NamingClass, Found, ObjectType, |
7055 | SourceLocation(), PDiag()); |
7056 | } |
7057 | |
7058 | void HandleDependentAccessCheck(const DependentDiagnostic &DD, |
7059 | const MultiLevelTemplateArgumentList &TemplateArgs); |
7060 | void PerformDependentDiagnostics(const DeclContext *Pattern, |
7061 | const MultiLevelTemplateArgumentList &TemplateArgs); |
7062 | |
7063 | void HandleDelayedAccessCheck(sema::DelayedDiagnostic &DD, Decl *Ctx); |
7064 | |
7065 | /// When true, access checking violations are treated as SFINAE |
7066 | /// failures rather than hard errors. |
7067 | bool AccessCheckingSFINAE; |
7068 | |
7069 | enum AbstractDiagSelID { |
7070 | AbstractNone = -1, |
7071 | AbstractReturnType, |
7072 | AbstractParamType, |
7073 | AbstractVariableType, |
7074 | AbstractFieldType, |
7075 | AbstractIvarType, |
7076 | AbstractSynthesizedIvarType, |
7077 | AbstractArrayType |
7078 | }; |
7079 | |
7080 | bool isAbstractType(SourceLocation Loc, QualType T); |
7081 | bool RequireNonAbstractType(SourceLocation Loc, QualType T, |
7082 | TypeDiagnoser &Diagnoser); |
7083 | template <typename... Ts> |
7084 | bool RequireNonAbstractType(SourceLocation Loc, QualType T, unsigned DiagID, |
7085 | const Ts &...Args) { |
7086 | BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...); |
7087 | return RequireNonAbstractType(Loc, T, Diagnoser); |
7088 | } |
7089 | |
7090 | void DiagnoseAbstractType(const CXXRecordDecl *RD); |
7091 | |
7092 | //===--------------------------------------------------------------------===// |
7093 | // C++ Overloaded Operators [C++ 13.5] |
7094 | // |
7095 | |
7096 | bool CheckOverloadedOperatorDeclaration(FunctionDecl *FnDecl); |
7097 | |
7098 | bool CheckLiteralOperatorDeclaration(FunctionDecl *FnDecl); |
7099 | |
7100 | //===--------------------------------------------------------------------===// |
7101 | // C++ Templates [C++ 14] |
7102 | // |
7103 | void FilterAcceptableTemplateNames(LookupResult &R, |
7104 | bool AllowFunctionTemplates = true, |
7105 | bool AllowDependent = true); |
7106 | bool hasAnyAcceptableTemplateNames(LookupResult &R, |
7107 | bool AllowFunctionTemplates = true, |
7108 | bool AllowDependent = true, |
7109 | bool AllowNonTemplateFunctions = false); |
7110 | /// Try to interpret the lookup result D as a template-name. |
7111 | /// |
7112 | /// \param D A declaration found by name lookup. |
7113 | /// \param AllowFunctionTemplates Whether function templates should be |
7114 | /// considered valid results. |
7115 | /// \param AllowDependent Whether unresolved using declarations (that might |
7116 | /// name templates) should be considered valid results. |
7117 | NamedDecl *getAsTemplateNameDecl(NamedDecl *D, |
7118 | bool AllowFunctionTemplates = true, |
7119 | bool AllowDependent = true); |
7120 | |
7121 | enum TemplateNameIsRequiredTag { TemplateNameIsRequired }; |
7122 | /// Whether and why a template name is required in this lookup. |
7123 | class RequiredTemplateKind { |
7124 | public: |
7125 | /// Template name is required if TemplateKWLoc is valid. |
7126 | RequiredTemplateKind(SourceLocation TemplateKWLoc = SourceLocation()) |
7127 | : TemplateKW(TemplateKWLoc) {} |
7128 | /// Template name is unconditionally required. |
7129 | RequiredTemplateKind(TemplateNameIsRequiredTag) : TemplateKW() {} |
7130 | |
7131 | SourceLocation getTemplateKeywordLoc() const { |
7132 | return TemplateKW.getValueOr(SourceLocation()); |
7133 | } |
7134 | bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); } |
7135 | bool isRequired() const { return TemplateKW != SourceLocation(); } |
7136 | explicit operator bool() const { return isRequired(); } |
7137 | |
7138 | private: |
7139 | llvm::Optional<SourceLocation> TemplateKW; |
7140 | }; |
7141 | |
7142 | enum class AssumedTemplateKind { |
7143 | /// This is not assumed to be a template name. |
7144 | None, |
7145 | /// This is assumed to be a template name because lookup found nothing. |
7146 | FoundNothing, |
7147 | /// This is assumed to be a template name because lookup found one or more |
7148 | /// functions (but no function templates). |
7149 | FoundFunctions, |
7150 | }; |
7151 | bool LookupTemplateName( |
7152 | LookupResult &R, Scope *S, CXXScopeSpec &SS, QualType ObjectType, |
7153 | bool EnteringContext, bool &MemberOfUnknownSpecialization, |
7154 | RequiredTemplateKind RequiredTemplate = SourceLocation(), |
7155 | AssumedTemplateKind *ATK = nullptr, bool AllowTypoCorrection = true); |
7156 | |
7157 | TemplateNameKind isTemplateName(Scope *S, |
7158 | CXXScopeSpec &SS, |
7159 | bool hasTemplateKeyword, |
7160 | const UnqualifiedId &Name, |
7161 | ParsedType ObjectType, |
7162 | bool EnteringContext, |
7163 | TemplateTy &Template, |
7164 | bool &MemberOfUnknownSpecialization, |
7165 | bool Disambiguation = false); |
7166 | |
7167 | /// Try to resolve an undeclared template name as a type template. |
7168 | /// |
7169 | /// Sets II to the identifier corresponding to the template name, and updates |
7170 | /// Name to a corresponding (typo-corrected) type template name and TNK to |
7171 | /// the corresponding kind, if possible. |
7172 | void ActOnUndeclaredTypeTemplateName(Scope *S, TemplateTy &Name, |
7173 | TemplateNameKind &TNK, |
7174 | SourceLocation NameLoc, |
7175 | IdentifierInfo *&II); |
7176 | |
7177 | bool resolveAssumedTemplateNameAsType(Scope *S, TemplateName &Name, |
7178 | SourceLocation NameLoc, |
7179 | bool Diagnose = true); |
7180 | |
7181 | /// Determine whether a particular identifier might be the name in a C++1z |
7182 | /// deduction-guide declaration. |
7183 | bool isDeductionGuideName(Scope *S, const IdentifierInfo &Name, |
7184 | SourceLocation NameLoc, |
7185 | ParsedTemplateTy *Template = nullptr); |
7186 | |
7187 | bool DiagnoseUnknownTemplateName(const IdentifierInfo &II, |
7188 | SourceLocation IILoc, |
7189 | Scope *S, |
7190 | const CXXScopeSpec *SS, |
7191 | TemplateTy &SuggestedTemplate, |
7192 | TemplateNameKind &SuggestedKind); |
7193 | |
7194 | bool DiagnoseUninstantiableTemplate(SourceLocation PointOfInstantiation, |
7195 | NamedDecl *Instantiation, |
7196 | bool InstantiatedFromMember, |
7197 | const NamedDecl *Pattern, |
7198 | const NamedDecl *PatternDef, |
7199 | TemplateSpecializationKind TSK, |
7200 | bool Complain = true); |
7201 | |
7202 | void DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl); |
7203 | TemplateDecl *AdjustDeclIfTemplate(Decl *&Decl); |
7204 | |
7205 | NamedDecl *ActOnTypeParameter(Scope *S, bool Typename, |
7206 | SourceLocation EllipsisLoc, |
7207 | SourceLocation KeyLoc, |
7208 | IdentifierInfo *ParamName, |
7209 | SourceLocation ParamNameLoc, |
7210 | unsigned Depth, unsigned Position, |
7211 | SourceLocation EqualLoc, |
7212 | ParsedType DefaultArg, bool HasTypeConstraint); |
7213 | |
7214 | bool ActOnTypeConstraint(const CXXScopeSpec &SS, |
7215 | TemplateIdAnnotation *TypeConstraint, |
7216 | TemplateTypeParmDecl *ConstrainedParameter, |
7217 | SourceLocation EllipsisLoc); |
7218 | |
7219 | bool AttachTypeConstraint(NestedNameSpecifierLoc NS, |
7220 | DeclarationNameInfo NameInfo, |
7221 | ConceptDecl *NamedConcept, |
7222 | const TemplateArgumentListInfo *TemplateArgs, |
7223 | TemplateTypeParmDecl *ConstrainedParameter, |
7224 | SourceLocation EllipsisLoc); |
7225 | |
7226 | bool AttachTypeConstraint(AutoTypeLoc TL, |
7227 | NonTypeTemplateParmDecl *ConstrainedParameter, |
7228 | SourceLocation EllipsisLoc); |
7229 | |
7230 | QualType CheckNonTypeTemplateParameterType(TypeSourceInfo *&TSI, |
7231 | SourceLocation Loc); |
7232 | QualType CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc); |
7233 | |
7234 | NamedDecl *ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, |
7235 | unsigned Depth, |
7236 | unsigned Position, |
7237 | SourceLocation EqualLoc, |
7238 | Expr *DefaultArg); |
7239 | NamedDecl *ActOnTemplateTemplateParameter(Scope *S, |
7240 | SourceLocation TmpLoc, |
7241 | TemplateParameterList *Params, |
7242 | SourceLocation EllipsisLoc, |
7243 | IdentifierInfo *ParamName, |
7244 | SourceLocation ParamNameLoc, |
7245 | unsigned Depth, |
7246 | unsigned Position, |
7247 | SourceLocation EqualLoc, |
7248 | ParsedTemplateArgument DefaultArg); |
7249 | |
7250 | TemplateParameterList * |
7251 | ActOnTemplateParameterList(unsigned Depth, |
7252 | SourceLocation ExportLoc, |
7253 | SourceLocation TemplateLoc, |
7254 | SourceLocation LAngleLoc, |
7255 | ArrayRef<NamedDecl *> Params, |
7256 | SourceLocation RAngleLoc, |
7257 | Expr *RequiresClause); |
7258 | |
7259 | /// The context in which we are checking a template parameter list. |
7260 | enum TemplateParamListContext { |
7261 | TPC_ClassTemplate, |
7262 | TPC_VarTemplate, |
7263 | TPC_FunctionTemplate, |
7264 | TPC_ClassTemplateMember, |
7265 | TPC_FriendClassTemplate, |
7266 | TPC_FriendFunctionTemplate, |
7267 | TPC_FriendFunctionTemplateDefinition, |
7268 | TPC_TypeAliasTemplate |
7269 | }; |
7270 | |
7271 | bool CheckTemplateParameterList(TemplateParameterList *NewParams, |
7272 | TemplateParameterList *OldParams, |
7273 | TemplateParamListContext TPC, |
7274 | SkipBodyInfo *SkipBody = nullptr); |
7275 | TemplateParameterList *MatchTemplateParametersToScopeSpecifier( |
7276 | SourceLocation DeclStartLoc, SourceLocation DeclLoc, |
7277 | const CXXScopeSpec &SS, TemplateIdAnnotation *TemplateId, |
7278 | ArrayRef<TemplateParameterList *> ParamLists, |
7279 | bool IsFriend, bool &IsMemberSpecialization, bool &Invalid, |
7280 | bool SuppressDiagnostic = false); |
7281 | |
7282 | DeclResult CheckClassTemplate( |
7283 | Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, |
7284 | CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, |
7285 | const ParsedAttributesView &Attr, TemplateParameterList *TemplateParams, |
7286 | AccessSpecifier AS, SourceLocation ModulePrivateLoc, |
7287 | SourceLocation FriendLoc, unsigned NumOuterTemplateParamLists, |
7288 | TemplateParameterList **OuterTemplateParamLists, |
7289 | SkipBodyInfo *SkipBody = nullptr); |
7290 | |
7291 | TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, |
7292 | QualType NTTPType, |
7293 | SourceLocation Loc); |
7294 | |
7295 | /// Get a template argument mapping the given template parameter to itself, |
7296 | /// e.g. for X in \c template<int X>, this would return an expression template |
7297 | /// argument referencing X. |
7298 | TemplateArgumentLoc getIdentityTemplateArgumentLoc(NamedDecl *Param, |
7299 | SourceLocation Location); |
7300 | |
7301 | void translateTemplateArguments(const ASTTemplateArgsPtr &In, |
7302 | TemplateArgumentListInfo &Out); |
7303 | |
7304 | ParsedTemplateArgument ActOnTemplateTypeArgument(TypeResult ParsedType); |
7305 | |
7306 | void NoteAllFoundTemplates(TemplateName Name); |
7307 | |
7308 | QualType CheckTemplateIdType(TemplateName Template, |
7309 | SourceLocation TemplateLoc, |
7310 | TemplateArgumentListInfo &TemplateArgs); |
7311 | |
7312 | TypeResult |
7313 | ActOnTemplateIdType(Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, |
7314 | TemplateTy Template, IdentifierInfo *TemplateII, |
7315 | SourceLocation TemplateIILoc, SourceLocation LAngleLoc, |
7316 | ASTTemplateArgsPtr TemplateArgs, SourceLocation RAngleLoc, |
7317 | bool IsCtorOrDtorName = false, bool IsClassName = false); |
7318 | |
7319 | /// Parsed an elaborated-type-specifier that refers to a template-id, |
7320 | /// such as \c class T::template apply<U>. |
7321 | TypeResult ActOnTagTemplateIdType(TagUseKind TUK, |
7322 | TypeSpecifierType TagSpec, |
7323 | SourceLocation TagLoc, |
7324 | CXXScopeSpec &SS, |
7325 | SourceLocation TemplateKWLoc, |
7326 | TemplateTy TemplateD, |
7327 | SourceLocation TemplateLoc, |
7328 | SourceLocation LAngleLoc, |
7329 | ASTTemplateArgsPtr TemplateArgsIn, |
7330 | SourceLocation RAngleLoc); |
7331 | |
7332 | DeclResult ActOnVarTemplateSpecialization( |
7333 | Scope *S, Declarator &D, TypeSourceInfo *DI, |
7334 | SourceLocation TemplateKWLoc, TemplateParameterList *TemplateParams, |
7335 | StorageClass SC, bool IsPartialSpecialization); |
7336 | |
7337 | DeclResult CheckVarTemplateId(VarTemplateDecl *Template, |
7338 | SourceLocation TemplateLoc, |
7339 | SourceLocation TemplateNameLoc, |
7340 | const TemplateArgumentListInfo &TemplateArgs); |
7341 | |
7342 | ExprResult CheckVarTemplateId(const CXXScopeSpec &SS, |
7343 | const DeclarationNameInfo &NameInfo, |
7344 | VarTemplateDecl *Template, |
7345 | SourceLocation TemplateLoc, |
7346 | const TemplateArgumentListInfo *TemplateArgs); |
7347 | |
7348 | ExprResult |
7349 | CheckConceptTemplateId(const CXXScopeSpec &SS, |
7350 | SourceLocation TemplateKWLoc, |
7351 | const DeclarationNameInfo &ConceptNameInfo, |
7352 | NamedDecl *FoundDecl, ConceptDecl *NamedConcept, |
7353 | const TemplateArgumentListInfo *TemplateArgs); |
7354 | |
7355 | void diagnoseMissingTemplateArguments(TemplateName Name, SourceLocation Loc); |
7356 | |
7357 | ExprResult BuildTemplateIdExpr(const CXXScopeSpec &SS, |
7358 | SourceLocation TemplateKWLoc, |
7359 | LookupResult &R, |
7360 | bool RequiresADL, |
7361 | const TemplateArgumentListInfo *TemplateArgs); |
7362 | |
7363 | ExprResult BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS, |
7364 | SourceLocation TemplateKWLoc, |
7365 | const DeclarationNameInfo &NameInfo, |
7366 | const TemplateArgumentListInfo *TemplateArgs); |
7367 | |
7368 | TemplateNameKind ActOnTemplateName( |
7369 | Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, |
7370 | const UnqualifiedId &Name, ParsedType ObjectType, bool EnteringContext, |
7371 | TemplateTy &Template, bool AllowInjectedClassName = false); |
7372 | |
7373 | DeclResult ActOnClassTemplateSpecialization( |
7374 | Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, |
7375 | SourceLocation ModulePrivateLoc, CXXScopeSpec &SS, |
7376 | TemplateIdAnnotation &TemplateId, const ParsedAttributesView &Attr, |
7377 | MultiTemplateParamsArg TemplateParameterLists, |
7378 | SkipBodyInfo *SkipBody = nullptr); |
7379 | |
7380 | bool CheckTemplatePartialSpecializationArgs(SourceLocation Loc, |
7381 | TemplateDecl *PrimaryTemplate, |
7382 | unsigned NumExplicitArgs, |
7383 | ArrayRef<TemplateArgument> Args); |
7384 | void CheckTemplatePartialSpecialization( |
7385 | ClassTemplatePartialSpecializationDecl *Partial); |
7386 | void CheckTemplatePartialSpecialization( |
7387 | VarTemplatePartialSpecializationDecl *Partial); |
7388 | |
7389 | Decl *ActOnTemplateDeclarator(Scope *S, |
7390 | MultiTemplateParamsArg TemplateParameterLists, |
7391 | Declarator &D); |
7392 | |
7393 | bool |
7394 | CheckSpecializationInstantiationRedecl(SourceLocation NewLoc, |
7395 | TemplateSpecializationKind NewTSK, |
7396 | NamedDecl *PrevDecl, |
7397 | TemplateSpecializationKind PrevTSK, |
7398 | SourceLocation PrevPtOfInstantiation, |
7399 | bool &SuppressNew); |
7400 | |
7401 | bool CheckDependentFunctionTemplateSpecialization(FunctionDecl *FD, |
7402 | const TemplateArgumentListInfo &ExplicitTemplateArgs, |
7403 | LookupResult &Previous); |
7404 | |
7405 | bool CheckFunctionTemplateSpecialization( |
7406 | FunctionDecl *FD, TemplateArgumentListInfo *ExplicitTemplateArgs, |
7407 | LookupResult &Previous, bool QualifiedFriend = false); |
7408 | bool CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous); |
7409 | void CompleteMemberSpecialization(NamedDecl *Member, LookupResult &Previous); |
7410 | |
7411 | DeclResult ActOnExplicitInstantiation( |
7412 | Scope *S, SourceLocation ExternLoc, SourceLocation TemplateLoc, |
7413 | unsigned TagSpec, SourceLocation KWLoc, const CXXScopeSpec &SS, |
7414 | TemplateTy Template, SourceLocation TemplateNameLoc, |
7415 | SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs, |
7416 | SourceLocation RAngleLoc, const ParsedAttributesView &Attr); |
7417 | |
7418 | DeclResult ActOnExplicitInstantiation(Scope *S, SourceLocation ExternLoc, |
7419 | SourceLocation TemplateLoc, |
7420 | unsigned TagSpec, SourceLocation KWLoc, |
7421 | CXXScopeSpec &SS, IdentifierInfo *Name, |
7422 | SourceLocation NameLoc, |
7423 | const ParsedAttributesView &Attr); |
7424 | |
7425 | DeclResult ActOnExplicitInstantiation(Scope *S, |
7426 | SourceLocation ExternLoc, |
7427 | SourceLocation TemplateLoc, |
7428 | Declarator &D); |
7429 | |
7430 | TemplateArgumentLoc |
7431 | SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template, |
7432 | SourceLocation TemplateLoc, |
7433 | SourceLocation RAngleLoc, |
7434 | Decl *Param, |
7435 | SmallVectorImpl<TemplateArgument> |
7436 | &Converted, |
7437 | bool &HasDefaultArg); |
7438 | |
7439 | /// Specifies the context in which a particular template |
7440 | /// argument is being checked. |
7441 | enum CheckTemplateArgumentKind { |
7442 | /// The template argument was specified in the code or was |
7443 | /// instantiated with some deduced template arguments. |
7444 | CTAK_Specified, |
7445 | |
7446 | /// The template argument was deduced via template argument |
7447 | /// deduction. |
7448 | CTAK_Deduced, |
7449 | |
7450 | /// The template argument was deduced from an array bound |
7451 | /// via template argument deduction. |
7452 | CTAK_DeducedFromArrayBound |
7453 | }; |
7454 | |
7455 | bool CheckTemplateArgument(NamedDecl *Param, |
7456 | TemplateArgumentLoc &Arg, |
7457 | NamedDecl *Template, |
7458 | SourceLocation TemplateLoc, |
7459 | SourceLocation RAngleLoc, |
7460 | unsigned ArgumentPackIndex, |
7461 | SmallVectorImpl<TemplateArgument> &Converted, |
7462 | CheckTemplateArgumentKind CTAK = CTAK_Specified); |
7463 | |
7464 | /// Check that the given template arguments can be be provided to |
7465 | /// the given template, converting the arguments along the way. |
7466 | /// |
7467 | /// \param Template The template to which the template arguments are being |
7468 | /// provided. |
7469 | /// |
7470 | /// \param TemplateLoc The location of the template name in the source. |
7471 | /// |
7472 | /// \param TemplateArgs The list of template arguments. If the template is |
7473 | /// a template template parameter, this function may extend the set of |
7474 | /// template arguments to also include substituted, defaulted template |
7475 | /// arguments. |
7476 | /// |
7477 | /// \param PartialTemplateArgs True if the list of template arguments is |
7478 | /// intentionally partial, e.g., because we're checking just the initial |
7479 | /// set of template arguments. |
7480 | /// |
7481 | /// \param Converted Will receive the converted, canonicalized template |
7482 | /// arguments. |
7483 | /// |
7484 | /// \param UpdateArgsWithConversions If \c true, update \p TemplateArgs to |
7485 | /// contain the converted forms of the template arguments as written. |
7486 | /// Otherwise, \p TemplateArgs will not be modified. |
7487 | /// |
7488 | /// \param ConstraintsNotSatisfied If provided, and an error occured, will |
7489 | /// receive true if the cause for the error is the associated constraints of |
7490 | /// the template not being satisfied by the template arguments. |
7491 | /// |
7492 | /// \returns true if an error occurred, false otherwise. |
7493 | bool CheckTemplateArgumentList(TemplateDecl *Template, |
7494 | SourceLocation TemplateLoc, |
7495 | TemplateArgumentListInfo &TemplateArgs, |
7496 | bool PartialTemplateArgs, |
7497 | SmallVectorImpl<TemplateArgument> &Converted, |
7498 | bool UpdateArgsWithConversions = true, |
7499 | bool *ConstraintsNotSatisfied = nullptr); |
7500 | |
7501 | bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param, |
7502 | TemplateArgumentLoc &Arg, |
7503 | SmallVectorImpl<TemplateArgument> &Converted); |
7504 | |
7505 | bool CheckTemplateArgument(TemplateTypeParmDecl *Param, |
7506 | TypeSourceInfo *Arg); |
7507 | ExprResult CheckTemplateArgument(NonTypeTemplateParmDecl *Param, |
7508 | QualType InstantiatedParamType, Expr *Arg, |
7509 | TemplateArgument &Converted, |
7510 | CheckTemplateArgumentKind CTAK = CTAK_Specified); |
7511 | bool CheckTemplateTemplateArgument(TemplateTemplateParmDecl *Param, |
7512 | TemplateParameterList *Params, |
7513 | TemplateArgumentLoc &Arg); |
7514 | |
7515 | ExprResult |
7516 | BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, |
7517 | QualType ParamType, |
7518 | SourceLocation Loc); |
7519 | ExprResult |
7520 | BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg, |
7521 | SourceLocation Loc); |
7522 | |
7523 | /// Enumeration describing how template parameter lists are compared |
7524 | /// for equality. |
7525 | enum TemplateParameterListEqualKind { |
7526 | /// We are matching the template parameter lists of two templates |
7527 | /// that might be redeclarations. |
7528 | /// |
7529 | /// \code |
7530 | /// template<typename T> struct X; |
7531 | /// template<typename T> struct X; |
7532 | /// \endcode |
7533 | TPL_TemplateMatch, |
7534 | |
7535 | /// We are matching the template parameter lists of two template |
7536 | /// template parameters as part of matching the template parameter lists |
7537 | /// of two templates that might be redeclarations. |
7538 | /// |
7539 | /// \code |
7540 | /// template<template<int I> class TT> struct X; |
7541 | /// template<template<int Value> class Other> struct X; |
7542 | /// \endcode |
7543 | TPL_TemplateTemplateParmMatch, |
7544 | |
7545 | /// We are matching the template parameter lists of a template |
7546 | /// template argument against the template parameter lists of a template |
7547 | /// template parameter. |
7548 | /// |
7549 | /// \code |
7550 | /// template<template<int Value> class Metafun> struct X; |
7551 | /// template<int Value> struct integer_c; |
7552 | /// X<integer_c> xic; |
7553 | /// \endcode |
7554 | TPL_TemplateTemplateArgumentMatch |
7555 | }; |
7556 | |
7557 | bool TemplateParameterListsAreEqual(TemplateParameterList *New, |
7558 | TemplateParameterList *Old, |
7559 | bool Complain, |
7560 | TemplateParameterListEqualKind Kind, |
7561 | SourceLocation TemplateArgLoc |
7562 | = SourceLocation()); |
7563 | |
7564 | bool CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams); |
7565 | |
7566 | /// Called when the parser has parsed a C++ typename |
7567 | /// specifier, e.g., "typename T::type". |
7568 | /// |
7569 | /// \param S The scope in which this typename type occurs. |
7570 | /// \param TypenameLoc the location of the 'typename' keyword |
7571 | /// \param SS the nested-name-specifier following the typename (e.g., 'T::'). |
7572 | /// \param II the identifier we're retrieving (e.g., 'type' in the example). |
7573 | /// \param IdLoc the location of the identifier. |
7574 | TypeResult |
7575 | ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, |
7576 | const CXXScopeSpec &SS, const IdentifierInfo &II, |
7577 | SourceLocation IdLoc); |
7578 | |
7579 | /// Called when the parser has parsed a C++ typename |
7580 | /// specifier that ends in a template-id, e.g., |
7581 | /// "typename MetaFun::template apply<T1, T2>". |
7582 | /// |
7583 | /// \param S The scope in which this typename type occurs. |
7584 | /// \param TypenameLoc the location of the 'typename' keyword |
7585 | /// \param SS the nested-name-specifier following the typename (e.g., 'T::'). |
7586 | /// \param TemplateLoc the location of the 'template' keyword, if any. |
7587 | /// \param TemplateName The template name. |
7588 | /// \param TemplateII The identifier used to name the template. |
7589 | /// \param TemplateIILoc The location of the template name. |
7590 | /// \param LAngleLoc The location of the opening angle bracket ('<'). |
7591 | /// \param TemplateArgs The template arguments. |
7592 | /// \param RAngleLoc The location of the closing angle bracket ('>'). |
7593 | TypeResult |
7594 | ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, |
7595 | const CXXScopeSpec &SS, |
7596 | SourceLocation TemplateLoc, |
7597 | TemplateTy TemplateName, |
7598 | IdentifierInfo *TemplateII, |
7599 | SourceLocation TemplateIILoc, |
7600 | SourceLocation LAngleLoc, |
7601 | ASTTemplateArgsPtr TemplateArgs, |
7602 | SourceLocation RAngleLoc); |
7603 | |
7604 | QualType CheckTypenameType(ElaboratedTypeKeyword Keyword, |
7605 | SourceLocation KeywordLoc, |
7606 | NestedNameSpecifierLoc QualifierLoc, |
7607 | const IdentifierInfo &II, |
7608 | SourceLocation IILoc, |
7609 | TypeSourceInfo **TSI, |
7610 | bool DeducedTSTContext); |
7611 | |
7612 | QualType CheckTypenameType(ElaboratedTypeKeyword Keyword, |
7613 | SourceLocation KeywordLoc, |
7614 | NestedNameSpecifierLoc QualifierLoc, |
7615 | const IdentifierInfo &II, |
7616 | SourceLocation IILoc, |
7617 | bool DeducedTSTContext = true); |
7618 | |
7619 | |
7620 | TypeSourceInfo *RebuildTypeInCurrentInstantiation(TypeSourceInfo *T, |
7621 | SourceLocation Loc, |
7622 | DeclarationName Name); |
7623 | bool RebuildNestedNameSpecifierInCurrentInstantiation(CXXScopeSpec &SS); |
7624 | |
7625 | ExprResult RebuildExprInCurrentInstantiation(Expr *E); |
7626 | bool RebuildTemplateParamsInCurrentInstantiation( |
7627 | TemplateParameterList *Params); |
7628 | |
7629 | std::string |
7630 | getTemplateArgumentBindingsText(const TemplateParameterList *Params, |
7631 | const TemplateArgumentList &Args); |
7632 | |
7633 | std::string |
7634 | getTemplateArgumentBindingsText(const TemplateParameterList *Params, |
7635 | const TemplateArgument *Args, |
7636 | unsigned NumArgs); |
7637 | |
7638 | //===--------------------------------------------------------------------===// |
7639 | // C++ Concepts |
7640 | //===--------------------------------------------------------------------===// |
7641 | Decl *ActOnConceptDefinition( |
7642 | Scope *S, MultiTemplateParamsArg TemplateParameterLists, |
7643 | IdentifierInfo *Name, SourceLocation NameLoc, Expr *ConstraintExpr); |
7644 | |
7645 | RequiresExprBodyDecl * |
7646 | ActOnStartRequiresExpr(SourceLocation RequiresKWLoc, |
7647 | ArrayRef<ParmVarDecl *> LocalParameters, |
7648 | Scope *BodyScope); |
7649 | void ActOnFinishRequiresExpr(); |
7650 | concepts::Requirement *ActOnSimpleRequirement(Expr *E); |
7651 | concepts::Requirement *ActOnTypeRequirement( |
7652 | SourceLocation TypenameKWLoc, CXXScopeSpec &SS, SourceLocation NameLoc, |
7653 | IdentifierInfo *TypeName, TemplateIdAnnotation *TemplateId); |
7654 | concepts::Requirement *ActOnCompoundRequirement(Expr *E, |
7655 | SourceLocation NoexceptLoc); |
7656 | concepts::Requirement * |
7657 | ActOnCompoundRequirement( |
7658 | Expr *E, SourceLocation NoexceptLoc, CXXScopeSpec &SS, |
7659 | TemplateIdAnnotation *TypeConstraint, unsigned Depth); |
7660 | concepts::Requirement *ActOnNestedRequirement(Expr *Constraint); |
7661 | concepts::ExprRequirement * |
7662 | BuildExprRequirement( |
7663 | Expr *E, bool IsSatisfied, SourceLocation NoexceptLoc, |
7664 | concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement); |
7665 | concepts::ExprRequirement * |
7666 | BuildExprRequirement( |
7667 | concepts::Requirement::SubstitutionDiagnostic *ExprSubstDiag, |
7668 | bool IsSatisfied, SourceLocation NoexceptLoc, |
7669 | concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement); |
7670 | concepts::TypeRequirement *BuildTypeRequirement(TypeSourceInfo *Type); |
7671 | concepts::TypeRequirement * |
7672 | BuildTypeRequirement( |
7673 | concepts::Requirement::SubstitutionDiagnostic *SubstDiag); |
7674 | concepts::NestedRequirement *BuildNestedRequirement(Expr *E); |
7675 | concepts::NestedRequirement * |
7676 | BuildNestedRequirement( |
7677 | concepts::Requirement::SubstitutionDiagnostic *SubstDiag); |
7678 | ExprResult ActOnRequiresExpr(SourceLocation RequiresKWLoc, |
7679 | RequiresExprBodyDecl *Body, |
7680 | ArrayRef<ParmVarDecl *> LocalParameters, |
7681 | ArrayRef<concepts::Requirement *> Requirements, |
7682 | SourceLocation ClosingBraceLoc); |
7683 | |
7684 | //===--------------------------------------------------------------------===// |
7685 | // C++ Variadic Templates (C++0x [temp.variadic]) |
7686 | //===--------------------------------------------------------------------===// |
7687 | |
7688 | /// Determine whether an unexpanded parameter pack might be permitted in this |
7689 | /// location. Useful for error recovery. |
7690 | bool isUnexpandedParameterPackPermitted(); |
7691 | |
7692 | /// The context in which an unexpanded parameter pack is |
7693 | /// being diagnosed. |
7694 | /// |
7695 | /// Note that the values of this enumeration line up with the first |
7696 | /// argument to the \c err_unexpanded_parameter_pack diagnostic. |
7697 | enum UnexpandedParameterPackContext { |
7698 | /// An arbitrary expression. |
7699 | UPPC_Expression = 0, |
7700 | |
7701 | /// The base type of a class type. |
7702 | UPPC_BaseType, |
7703 | |
7704 | /// The type of an arbitrary declaration. |
7705 | UPPC_DeclarationType, |
7706 | |
7707 | /// The type of a data member. |
7708 | UPPC_DataMemberType, |
7709 | |
7710 | /// The size of a bit-field. |
7711 | UPPC_BitFieldWidth, |
7712 | |
7713 | /// The expression in a static assertion. |
7714 | UPPC_StaticAssertExpression, |
7715 | |
7716 | /// The fixed underlying type of an enumeration. |
7717 | UPPC_FixedUnderlyingType, |
7718 | |
7719 | /// The enumerator value. |
7720 | UPPC_EnumeratorValue, |
7721 | |
7722 | /// A using declaration. |
7723 | UPPC_UsingDeclaration, |
7724 | |
7725 | /// A friend declaration. |
7726 | UPPC_FriendDeclaration, |
7727 | |
7728 | /// A declaration qualifier. |
7729 | UPPC_DeclarationQualifier, |
7730 | |
7731 | /// An initializer. |
7732 | UPPC_Initializer, |
7733 | |
7734 | /// A default argument. |
7735 | UPPC_DefaultArgument, |
7736 | |
7737 | /// The type of a non-type template parameter. |
7738 | UPPC_NonTypeTemplateParameterType, |
7739 | |
7740 | /// The type of an exception. |
7741 | UPPC_ExceptionType, |
7742 | |
7743 | /// Partial specialization. |
7744 | UPPC_PartialSpecialization, |
7745 | |
7746 | /// Microsoft __if_exists. |
7747 | UPPC_IfExists, |
7748 | |
7749 | /// Microsoft __if_not_exists. |
7750 | UPPC_IfNotExists, |
7751 | |
7752 | /// Lambda expression. |
7753 | UPPC_Lambda, |
7754 | |
7755 | /// Block expression, |
7756 | UPPC_Block, |
7757 | |
7758 | /// A type constraint, |
7759 | UPPC_TypeConstraint |
7760 | }; |
7761 | |
7762 | /// Diagnose unexpanded parameter packs. |
7763 | /// |
7764 | /// \param Loc The location at which we should emit the diagnostic. |
7765 | /// |
7766 | /// \param UPPC The context in which we are diagnosing unexpanded |
7767 | /// parameter packs. |
7768 | /// |
7769 | /// \param Unexpanded the set of unexpanded parameter packs. |
7770 | /// |
7771 | /// \returns true if an error occurred, false otherwise. |
7772 | bool DiagnoseUnexpandedParameterPacks(SourceLocation Loc, |
7773 | UnexpandedParameterPackContext UPPC, |
7774 | ArrayRef<UnexpandedParameterPack> Unexpanded); |
7775 | |
7776 | /// If the given type contains an unexpanded parameter pack, |
7777 | /// diagnose the error. |
7778 | /// |
7779 | /// \param Loc The source location where a diagnostc should be emitted. |
7780 | /// |
7781 | /// \param T The type that is being checked for unexpanded parameter |
7782 | /// packs. |
7783 | /// |
7784 | /// \returns true if an error occurred, false otherwise. |
7785 | bool DiagnoseUnexpandedParameterPack(SourceLocation Loc, TypeSourceInfo *T, |
7786 | UnexpandedParameterPackContext UPPC); |
7787 | |
7788 | /// If the given expression contains an unexpanded parameter |
7789 | /// pack, diagnose the error. |
7790 | /// |
7791 | /// \param E The expression that is being checked for unexpanded |
7792 | /// parameter packs. |
7793 | /// |
7794 | /// \returns true if an error occurred, false otherwise. |
7795 | bool DiagnoseUnexpandedParameterPack(Expr *E, |
7796 | UnexpandedParameterPackContext UPPC = UPPC_Expression); |
7797 | |
7798 | /// If the given nested-name-specifier contains an unexpanded |
7799 | /// parameter pack, diagnose the error. |
7800 | /// |
7801 | /// \param SS The nested-name-specifier that is being checked for |
7802 | /// unexpanded parameter packs. |
7803 | /// |
7804 | /// \returns true if an error occurred, false otherwise. |
7805 | bool DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS, |
7806 | UnexpandedParameterPackContext UPPC); |
7807 | |
7808 | /// If the given name contains an unexpanded parameter pack, |
7809 | /// diagnose the error. |
7810 | /// |
7811 | /// \param NameInfo The name (with source location information) that |
7812 | /// is being checked for unexpanded parameter packs. |
7813 | /// |
7814 | /// \returns true if an error occurred, false otherwise. |
7815 | bool DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo, |
7816 | UnexpandedParameterPackContext UPPC); |
7817 | |
7818 | /// If the given template name contains an unexpanded parameter pack, |
7819 | /// diagnose the error. |
7820 | /// |
7821 | /// \param Loc The location of the template name. |
7822 | /// |
7823 | /// \param Template The template name that is being checked for unexpanded |
7824 | /// parameter packs. |
7825 | /// |
7826 | /// \returns true if an error occurred, false otherwise. |
7827 | bool DiagnoseUnexpandedParameterPack(SourceLocation Loc, |
7828 | TemplateName Template, |
7829 | UnexpandedParameterPackContext UPPC); |
7830 | |
7831 | /// If the given template argument contains an unexpanded parameter |
7832 | /// pack, diagnose the error. |
7833 | /// |
7834 | /// \param Arg The template argument that is being checked for unexpanded |
7835 | /// parameter packs. |
7836 | /// |
7837 | /// \returns true if an error occurred, false otherwise. |
7838 | bool DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg, |
7839 | UnexpandedParameterPackContext UPPC); |
7840 | |
7841 | /// Collect the set of unexpanded parameter packs within the given |
7842 | /// template argument. |
7843 | /// |
7844 | /// \param Arg The template argument that will be traversed to find |
7845 | /// unexpanded parameter packs. |
7846 | void collectUnexpandedParameterPacks(TemplateArgument Arg, |
7847 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); |
7848 | |
7849 | /// Collect the set of unexpanded parameter packs within the given |
7850 | /// template argument. |
7851 | /// |
7852 | /// \param Arg The template argument that will be traversed to find |
7853 | /// unexpanded parameter packs. |
7854 | void collectUnexpandedParameterPacks(TemplateArgumentLoc Arg, |
7855 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); |
7856 | |
7857 | /// Collect the set of unexpanded parameter packs within the given |
7858 | /// type. |
7859 | /// |
7860 | /// \param T The type that will be traversed to find |
7861 | /// unexpanded parameter packs. |
7862 | void collectUnexpandedParameterPacks(QualType T, |
7863 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); |
7864 | |
7865 | /// Collect the set of unexpanded parameter packs within the given |
7866 | /// type. |
7867 | /// |
7868 | /// \param TL The type that will be traversed to find |
7869 | /// unexpanded parameter packs. |
7870 | void collectUnexpandedParameterPacks(TypeLoc TL, |
7871 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); |
7872 | |
7873 | /// Collect the set of unexpanded parameter packs within the given |
7874 | /// nested-name-specifier. |
7875 | /// |
7876 | /// \param NNS The nested-name-specifier that will be traversed to find |
7877 | /// unexpanded parameter packs. |
7878 | void collectUnexpandedParameterPacks(NestedNameSpecifierLoc NNS, |
7879 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); |
7880 | |
7881 | /// Collect the set of unexpanded parameter packs within the given |
7882 | /// name. |
7883 | /// |
7884 | /// \param NameInfo The name that will be traversed to find |
7885 | /// unexpanded parameter packs. |
7886 | void collectUnexpandedParameterPacks(const DeclarationNameInfo &NameInfo, |
7887 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); |
7888 | |
7889 | /// Invoked when parsing a template argument followed by an |
7890 | /// ellipsis, which creates a pack expansion. |
7891 | /// |
7892 | /// \param Arg The template argument preceding the ellipsis, which |
7893 | /// may already be invalid. |
7894 | /// |
7895 | /// \param EllipsisLoc The location of the ellipsis. |
7896 | ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg, |
7897 | SourceLocation EllipsisLoc); |
7898 | |
7899 | /// Invoked when parsing a type followed by an ellipsis, which |
7900 | /// creates a pack expansion. |
7901 | /// |
7902 | /// \param Type The type preceding the ellipsis, which will become |
7903 | /// the pattern of the pack expansion. |
7904 | /// |
7905 | /// \param EllipsisLoc The location of the ellipsis. |
7906 | TypeResult ActOnPackExpansion(ParsedType Type, SourceLocation EllipsisLoc); |
7907 | |
7908 | /// Construct a pack expansion type from the pattern of the pack |
7909 | /// expansion. |
7910 | TypeSourceInfo *CheckPackExpansion(TypeSourceInfo *Pattern, |
7911 | SourceLocation EllipsisLoc, |
7912 | Optional<unsigned> NumExpansions); |
7913 | |
7914 | /// Construct a pack expansion type from the pattern of the pack |
7915 | /// expansion. |
7916 | QualType CheckPackExpansion(QualType Pattern, |
7917 | SourceRange PatternRange, |
7918 | SourceLocation EllipsisLoc, |
7919 | Optional<unsigned> NumExpansions); |
7920 | |
7921 | /// Invoked when parsing an expression followed by an ellipsis, which |
7922 | /// creates a pack expansion. |
7923 | /// |
7924 | /// \param Pattern The expression preceding the ellipsis, which will become |
7925 | /// the pattern of the pack expansion. |
7926 | /// |
7927 | /// \param EllipsisLoc The location of the ellipsis. |
7928 | ExprResult ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc); |
7929 | |
7930 | /// Invoked when parsing an expression followed by an ellipsis, which |
7931 | /// creates a pack expansion. |
7932 | /// |
7933 | /// \param Pattern The expression preceding the ellipsis, which will become |
7934 | /// the pattern of the pack expansion. |
7935 | /// |
7936 | /// \param EllipsisLoc The location of the ellipsis. |
7937 | ExprResult CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc, |
7938 | Optional<unsigned> NumExpansions); |
7939 | |
7940 | /// Determine whether we could expand a pack expansion with the |
7941 | /// given set of parameter packs into separate arguments by repeatedly |
7942 | /// transforming the pattern. |
7943 | /// |
7944 | /// \param EllipsisLoc The location of the ellipsis that identifies the |
7945 | /// pack expansion. |
7946 | /// |
7947 | /// \param PatternRange The source range that covers the entire pattern of |
7948 | /// the pack expansion. |
7949 | /// |
7950 | /// \param Unexpanded The set of unexpanded parameter packs within the |
7951 | /// pattern. |
7952 | /// |
7953 | /// \param ShouldExpand Will be set to \c true if the transformer should |
7954 | /// expand the corresponding pack expansions into separate arguments. When |
7955 | /// set, \c NumExpansions must also be set. |
7956 | /// |
7957 | /// \param RetainExpansion Whether the caller should add an unexpanded |
7958 | /// pack expansion after all of the expanded arguments. This is used |
7959 | /// when extending explicitly-specified template argument packs per |
7960 | /// C++0x [temp.arg.explicit]p9. |
7961 | /// |
7962 | /// \param NumExpansions The number of separate arguments that will be in |
7963 | /// the expanded form of the corresponding pack expansion. This is both an |
7964 | /// input and an output parameter, which can be set by the caller if the |
7965 | /// number of expansions is known a priori (e.g., due to a prior substitution) |
7966 | /// and will be set by the callee when the number of expansions is known. |
7967 | /// The callee must set this value when \c ShouldExpand is \c true; it may |
7968 | /// set this value in other cases. |
7969 | /// |
7970 | /// \returns true if an error occurred (e.g., because the parameter packs |
7971 | /// are to be instantiated with arguments of different lengths), false |
7972 | /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions) |
7973 | /// must be set. |
7974 | bool CheckParameterPacksForExpansion(SourceLocation EllipsisLoc, |
7975 | SourceRange PatternRange, |
7976 | ArrayRef<UnexpandedParameterPack> Unexpanded, |
7977 | const MultiLevelTemplateArgumentList &TemplateArgs, |
7978 | bool &ShouldExpand, |
7979 | bool &RetainExpansion, |
7980 | Optional<unsigned> &NumExpansions); |
7981 | |
7982 | /// Determine the number of arguments in the given pack expansion |
7983 | /// type. |
7984 | /// |
7985 | /// This routine assumes that the number of arguments in the expansion is |
7986 | /// consistent across all of the unexpanded parameter packs in its pattern. |
7987 | /// |
7988 | /// Returns an empty Optional if the type can't be expanded. |
7989 | Optional<unsigned> getNumArgumentsInExpansion(QualType T, |
7990 | const MultiLevelTemplateArgumentList &TemplateArgs); |
7991 | |
7992 | /// Determine whether the given declarator contains any unexpanded |
7993 | /// parameter packs. |
7994 | /// |
7995 | /// This routine is used by the parser to disambiguate function declarators |
7996 | /// with an ellipsis prior to the ')', e.g., |
7997 | /// |
7998 | /// \code |
7999 | /// void f(T...); |
8000 | /// \endcode |
8001 | /// |
8002 | /// To determine whether we have an (unnamed) function parameter pack or |
8003 | /// a variadic function. |
8004 | /// |
8005 | /// \returns true if the declarator contains any unexpanded parameter packs, |
8006 | /// false otherwise. |
8007 | bool containsUnexpandedParameterPacks(Declarator &D); |
8008 | |
8009 | /// Returns the pattern of the pack expansion for a template argument. |
8010 | /// |
8011 | /// \param OrigLoc The template argument to expand. |
8012 | /// |
8013 | /// \param Ellipsis Will be set to the location of the ellipsis. |
8014 | /// |
8015 | /// \param NumExpansions Will be set to the number of expansions that will |
8016 | /// be generated from this pack expansion, if known a priori. |
8017 | TemplateArgumentLoc getTemplateArgumentPackExpansionPattern( |
8018 | TemplateArgumentLoc OrigLoc, |
8019 | SourceLocation &Ellipsis, |
8020 | Optional<unsigned> &NumExpansions) const; |
8021 | |
8022 | /// Given a template argument that contains an unexpanded parameter pack, but |
8023 | /// which has already been substituted, attempt to determine the number of |
8024 | /// elements that will be produced once this argument is fully-expanded. |
8025 | /// |
8026 | /// This is intended for use when transforming 'sizeof...(Arg)' in order to |
8027 | /// avoid actually expanding the pack where possible. |
8028 | Optional<unsigned> getFullyPackExpandedSize(TemplateArgument Arg); |
8029 | |
8030 | //===--------------------------------------------------------------------===// |
8031 | // C++ Template Argument Deduction (C++ [temp.deduct]) |
8032 | //===--------------------------------------------------------------------===// |
8033 | |
8034 | /// Adjust the type \p ArgFunctionType to match the calling convention, |
8035 | /// noreturn, and optionally the exception specification of \p FunctionType. |
8036 | /// Deduction often wants to ignore these properties when matching function |
8037 | /// types. |
8038 | QualType adjustCCAndNoReturn(QualType ArgFunctionType, QualType FunctionType, |
8039 | bool AdjustExceptionSpec = false); |
8040 | |
8041 | /// Describes the result of template argument deduction. |
8042 | /// |
8043 | /// The TemplateDeductionResult enumeration describes the result of |
8044 | /// template argument deduction, as returned from |
8045 | /// DeduceTemplateArguments(). The separate TemplateDeductionInfo |
8046 | /// structure provides additional information about the results of |
8047 | /// template argument deduction, e.g., the deduced template argument |
8048 | /// list (if successful) or the specific template parameters or |
8049 | /// deduced arguments that were involved in the failure. |
8050 | enum TemplateDeductionResult { |
8051 | /// Template argument deduction was successful. |
8052 | TDK_Success = 0, |
8053 | /// The declaration was invalid; do nothing. |
8054 | TDK_Invalid, |
8055 | /// Template argument deduction exceeded the maximum template |
8056 | /// instantiation depth (which has already been diagnosed). |
8057 | TDK_InstantiationDepth, |
8058 | /// Template argument deduction did not deduce a value |
8059 | /// for every template parameter. |
8060 | TDK_Incomplete, |
8061 | /// Template argument deduction did not deduce a value for every |
8062 | /// expansion of an expanded template parameter pack. |
8063 | TDK_IncompletePack, |
8064 | /// Template argument deduction produced inconsistent |
8065 | /// deduced values for the given template parameter. |
8066 | TDK_Inconsistent, |
8067 | /// Template argument deduction failed due to inconsistent |
8068 | /// cv-qualifiers on a template parameter type that would |
8069 | /// otherwise be deduced, e.g., we tried to deduce T in "const T" |
8070 | /// but were given a non-const "X". |
8071 | TDK_Underqualified, |
8072 | /// Substitution of the deduced template argument values |
8073 | /// resulted in an error. |
8074 | TDK_SubstitutionFailure, |
8075 | /// After substituting deduced template arguments, a dependent |
8076 | /// parameter type did not match the corresponding argument. |
8077 | TDK_DeducedMismatch, |
8078 | /// After substituting deduced template arguments, an element of |
8079 | /// a dependent parameter type did not match the corresponding element |
8080 | /// of the corresponding argument (when deducing from an initializer list). |
8081 | TDK_DeducedMismatchNested, |
8082 | /// A non-depnedent component of the parameter did not match the |
8083 | /// corresponding component of the argument. |
8084 | TDK_NonDeducedMismatch, |
8085 | /// When performing template argument deduction for a function |
8086 | /// template, there were too many call arguments. |
8087 | TDK_TooManyArguments, |
8088 | /// When performing template argument deduction for a function |
8089 | /// template, there were too few call arguments. |
8090 | TDK_TooFewArguments, |
8091 | /// The explicitly-specified template arguments were not valid |
8092 | /// template arguments for the given template. |
8093 | TDK_InvalidExplicitArguments, |
8094 | /// Checking non-dependent argument conversions failed. |
8095 | TDK_NonDependentConversionFailure, |
8096 | /// The deduced arguments did not satisfy the constraints associated |
8097 | /// with the template. |
8098 | TDK_ConstraintsNotSatisfied, |
8099 | /// Deduction failed; that's all we know. |
8100 | TDK_MiscellaneousDeductionFailure, |
8101 | /// CUDA Target attributes do not match. |
8102 | TDK_CUDATargetMismatch |
8103 | }; |
8104 | |
8105 | TemplateDeductionResult |
8106 | DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, |
8107 | const TemplateArgumentList &TemplateArgs, |
8108 | sema::TemplateDeductionInfo &Info); |
8109 | |
8110 | TemplateDeductionResult |
8111 | DeduceTemplateArguments(VarTemplatePartialSpecializationDecl *Partial, |
8112 | const TemplateArgumentList &TemplateArgs, |
8113 | sema::TemplateDeductionInfo &Info); |
8114 | |
8115 | TemplateDeductionResult SubstituteExplicitTemplateArguments( |
8116 | FunctionTemplateDecl *FunctionTemplate, |
8117 | TemplateArgumentListInfo &ExplicitTemplateArgs, |
8118 | SmallVectorImpl<DeducedTemplateArgument> &Deduced, |
8119 | SmallVectorImpl<QualType> &ParamTypes, QualType *FunctionType, |
8120 | sema::TemplateDeductionInfo &Info); |
8121 | |
8122 | /// brief A function argument from which we performed template argument |
8123 | // deduction for a call. |
8124 | struct OriginalCallArg { |
8125 | OriginalCallArg(QualType OriginalParamType, bool DecomposedParam, |
8126 | unsigned ArgIdx, QualType OriginalArgType) |
8127 | : OriginalParamType(OriginalParamType), |
8128 | DecomposedParam(DecomposedParam), ArgIdx(ArgIdx), |
8129 | OriginalArgType(OriginalArgType) {} |
8130 | |
8131 | QualType OriginalParamType; |
8132 | bool DecomposedParam; |
8133 | unsigned ArgIdx; |
8134 | QualType OriginalArgType; |
8135 | }; |
8136 | |
8137 | TemplateDeductionResult FinishTemplateArgumentDeduction( |
8138 | FunctionTemplateDecl *FunctionTemplate, |
8139 | SmallVectorImpl<DeducedTemplateArgument> &Deduced, |
8140 | unsigned NumExplicitlySpecified, FunctionDecl *&Specialization, |
8141 | sema::TemplateDeductionInfo &Info, |
8142 | SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs = nullptr, |
8143 | bool PartialOverloading = false, |
8144 | llvm::function_ref<bool()> CheckNonDependent = []{ return false; }); |
8145 | |
8146 | TemplateDeductionResult DeduceTemplateArguments( |
8147 | FunctionTemplateDecl *FunctionTemplate, |
8148 | TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args, |
8149 | FunctionDecl *&Specialization, sema::TemplateDeductionInfo &Info, |
8150 | bool PartialOverloading, |
8151 | llvm::function_ref<bool(ArrayRef<QualType>)> CheckNonDependent); |
8152 | |
8153 | TemplateDeductionResult |
8154 | DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, |
8155 | TemplateArgumentListInfo *ExplicitTemplateArgs, |
8156 | QualType ArgFunctionType, |
8157 | FunctionDecl *&Specialization, |
8158 | sema::TemplateDeductionInfo &Info, |
8159 | bool IsAddressOfFunction = false); |
8160 | |
8161 | TemplateDeductionResult |
8162 | DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, |
8163 | QualType ToType, |
8164 | CXXConversionDecl *&Specialization, |
8165 | sema::TemplateDeductionInfo &Info); |
8166 | |
8167 | TemplateDeductionResult |
8168 | DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, |
8169 | TemplateArgumentListInfo *ExplicitTemplateArgs, |
8170 | FunctionDecl *&Specialization, |
8171 | sema::TemplateDeductionInfo &Info, |
8172 | bool IsAddressOfFunction = false); |
8173 | |
8174 | /// Substitute Replacement for \p auto in \p TypeWithAuto |
8175 | QualType SubstAutoType(QualType TypeWithAuto, QualType Replacement); |
8176 | /// Substitute Replacement for auto in TypeWithAuto |
8177 | TypeSourceInfo* SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto, |
8178 | QualType Replacement); |
8179 | /// Completely replace the \c auto in \p TypeWithAuto by |
8180 | /// \p Replacement. This does not retain any \c auto type sugar. |
8181 | QualType ReplaceAutoType(QualType TypeWithAuto, QualType Replacement); |
8182 | TypeSourceInfo *ReplaceAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto, |
8183 | QualType Replacement); |
8184 | |
8185 | /// Result type of DeduceAutoType. |
8186 | enum DeduceAutoResult { |
8187 | DAR_Succeeded, |
8188 | DAR_Failed, |
8189 | DAR_FailedAlreadyDiagnosed |
8190 | }; |
8191 | |
8192 | DeduceAutoResult |
8193 | DeduceAutoType(TypeSourceInfo *AutoType, Expr *&Initializer, QualType &Result, |
8194 | Optional<unsigned> DependentDeductionDepth = None, |
8195 | bool IgnoreConstraints = false); |
8196 | DeduceAutoResult |
8197 | DeduceAutoType(TypeLoc AutoTypeLoc, Expr *&Initializer, QualType &Result, |
8198 | Optional<unsigned> DependentDeductionDepth = None, |
8199 | bool IgnoreConstraints = false); |
8200 | void DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init); |
8201 | bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc, |
8202 | bool Diagnose = true); |
8203 | |
8204 | /// Declare implicit deduction guides for a class template if we've |
8205 | /// not already done so. |
8206 | void DeclareImplicitDeductionGuides(TemplateDecl *Template, |
8207 | SourceLocation Loc); |
8208 | |
8209 | QualType DeduceTemplateSpecializationFromInitializer( |
8210 | TypeSourceInfo *TInfo, const InitializedEntity &Entity, |
8211 | const InitializationKind &Kind, MultiExprArg Init); |
8212 | |
8213 | QualType deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name, |
8214 | QualType Type, TypeSourceInfo *TSI, |
8215 | SourceRange Range, bool DirectInit, |
8216 | Expr *Init); |
8217 | |
8218 | TypeLoc getReturnTypeLoc(FunctionDecl *FD) const; |
8219 | |
8220 | bool DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD, |
8221 | SourceLocation ReturnLoc, |
8222 | Expr *&RetExpr, AutoType *AT); |
8223 | |
8224 | FunctionTemplateDecl *getMoreSpecializedTemplate( |
8225 | FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc, |
8226 | TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1, |
8227 | unsigned NumCallArguments2, bool Reversed = false); |
8228 | UnresolvedSetIterator |
8229 | getMostSpecialized(UnresolvedSetIterator SBegin, UnresolvedSetIterator SEnd, |
8230 | TemplateSpecCandidateSet &FailedCandidates, |
8231 | SourceLocation Loc, |
8232 | const PartialDiagnostic &NoneDiag, |
8233 | const PartialDiagnostic &AmbigDiag, |
8234 | const PartialDiagnostic &CandidateDiag, |
8235 | bool Complain = true, QualType TargetType = QualType()); |
8236 | |
8237 | ClassTemplatePartialSpecializationDecl * |
8238 | getMoreSpecializedPartialSpecialization( |
8239 | ClassTemplatePartialSpecializationDecl *PS1, |
8240 | ClassTemplatePartialSpecializationDecl *PS2, |
8241 | SourceLocation Loc); |
8242 | |
8243 | bool isMoreSpecializedThanPrimary(ClassTemplatePartialSpecializationDecl *T, |
8244 | sema::TemplateDeductionInfo &Info); |
8245 | |
8246 | VarTemplatePartialSpecializationDecl *getMoreSpecializedPartialSpecialization( |
8247 | VarTemplatePartialSpecializationDecl *PS1, |
8248 | VarTemplatePartialSpecializationDecl *PS2, SourceLocation Loc); |
8249 | |
8250 | bool isMoreSpecializedThanPrimary(VarTemplatePartialSpecializationDecl *T, |
8251 | sema::TemplateDeductionInfo &Info); |
8252 | |
8253 | bool isTemplateTemplateParameterAtLeastAsSpecializedAs( |
8254 | TemplateParameterList *PParam, TemplateDecl *AArg, SourceLocation Loc); |
8255 | |
8256 | void MarkUsedTemplateParameters(const Expr *E, bool OnlyDeduced, |
8257 | unsigned Depth, llvm::SmallBitVector &Used); |
8258 | |
8259 | void MarkUsedTemplateParameters(const TemplateArgumentList &TemplateArgs, |
8260 | bool OnlyDeduced, |
8261 | unsigned Depth, |
8262 | llvm::SmallBitVector &Used); |
8263 | void MarkDeducedTemplateParameters( |
8264 | const FunctionTemplateDecl *FunctionTemplate, |
8265 | llvm::SmallBitVector &Deduced) { |
8266 | return MarkDeducedTemplateParameters(Context, FunctionTemplate, Deduced); |
8267 | } |
8268 | static void MarkDeducedTemplateParameters(ASTContext &Ctx, |
8269 | const FunctionTemplateDecl *FunctionTemplate, |
8270 | llvm::SmallBitVector &Deduced); |
8271 | |
8272 | //===--------------------------------------------------------------------===// |
8273 | // C++ Template Instantiation |
8274 | // |
8275 | |
8276 | MultiLevelTemplateArgumentList |
8277 | getTemplateInstantiationArgs(NamedDecl *D, |
8278 | const TemplateArgumentList *Innermost = nullptr, |
8279 | bool RelativeToPrimary = false, |
8280 | const FunctionDecl *Pattern = nullptr); |
8281 | |
8282 | /// A context in which code is being synthesized (where a source location |
8283 | /// alone is not sufficient to identify the context). This covers template |
8284 | /// instantiation and various forms of implicitly-generated functions. |
8285 | struct CodeSynthesisContext { |
8286 | /// The kind of template instantiation we are performing |
8287 | enum SynthesisKind { |
8288 | /// We are instantiating a template declaration. The entity is |
8289 | /// the declaration we're instantiating (e.g., a CXXRecordDecl). |
8290 | TemplateInstantiation, |
8291 | |
8292 | /// We are instantiating a default argument for a template |
8293 | /// parameter. The Entity is the template parameter whose argument is |
8294 | /// being instantiated, the Template is the template, and the |
8295 | /// TemplateArgs/NumTemplateArguments provide the template arguments as |
8296 | /// specified. |
8297 | DefaultTemplateArgumentInstantiation, |
8298 | |
8299 | /// We are instantiating a default argument for a function. |
8300 | /// The Entity is the ParmVarDecl, and TemplateArgs/NumTemplateArgs |
8301 | /// provides the template arguments as specified. |
8302 | DefaultFunctionArgumentInstantiation, |
8303 | |
8304 | /// We are substituting explicit template arguments provided for |
8305 | /// a function template. The entity is a FunctionTemplateDecl. |
8306 | ExplicitTemplateArgumentSubstitution, |
8307 | |
8308 | /// We are substituting template argument determined as part of |
8309 | /// template argument deduction for either a class template |
8310 | /// partial specialization or a function template. The |
8311 | /// Entity is either a {Class|Var}TemplatePartialSpecializationDecl or |
8312 | /// a TemplateDecl. |
8313 | DeducedTemplateArgumentSubstitution, |
8314 | |
8315 | /// We are substituting prior template arguments into a new |
8316 | /// template parameter. The template parameter itself is either a |
8317 | /// NonTypeTemplateParmDecl or a TemplateTemplateParmDecl. |
8318 | PriorTemplateArgumentSubstitution, |
8319 | |
8320 | /// We are checking the validity of a default template argument that |
8321 | /// has been used when naming a template-id. |
8322 | DefaultTemplateArgumentChecking, |
8323 | |
8324 | /// We are computing the exception specification for a defaulted special |
8325 | /// member function. |
8326 | ExceptionSpecEvaluation, |
8327 | |
8328 | /// We are instantiating the exception specification for a function |
8329 | /// template which was deferred until it was needed. |
8330 | ExceptionSpecInstantiation, |
8331 | |
8332 | /// We are instantiating a requirement of a requires expression. |
8333 | RequirementInstantiation, |
8334 | |
8335 | /// We are checking the satisfaction of a nested requirement of a requires |
8336 | /// expression. |
8337 | NestedRequirementConstraintsCheck, |
8338 | |
8339 | /// We are declaring an implicit special member function. |
8340 | DeclaringSpecialMember, |
8341 | |
8342 | /// We are declaring an implicit 'operator==' for a defaulted |
8343 | /// 'operator<=>'. |
8344 | DeclaringImplicitEqualityComparison, |
8345 | |
8346 | /// We are defining a synthesized function (such as a defaulted special |
8347 | /// member). |
8348 | DefiningSynthesizedFunction, |
8349 | |
8350 | // We are checking the constraints associated with a constrained entity or |
8351 | // the constraint expression of a concept. This includes the checks that |
8352 | // atomic constraints have the type 'bool' and that they can be constant |
8353 | // evaluated. |
8354 | ConstraintsCheck, |
8355 | |
8356 | // We are substituting template arguments into a constraint expression. |
8357 | ConstraintSubstitution, |
8358 | |
8359 | // We are normalizing a constraint expression. |
8360 | ConstraintNormalization, |
8361 | |
8362 | // We are substituting into the parameter mapping of an atomic constraint |
8363 | // during normalization. |
8364 | ParameterMappingSubstitution, |
8365 | |
8366 | /// We are rewriting a comparison operator in terms of an operator<=>. |
8367 | RewritingOperatorAsSpaceship, |
8368 | |
8369 | /// We are initializing a structured binding. |
8370 | InitializingStructuredBinding, |
8371 | |
8372 | /// We are marking a class as __dllexport. |
8373 | MarkingClassDllexported, |
8374 | |
8375 | /// Added for Template instantiation observation. |
8376 | /// Memoization means we are _not_ instantiating a template because |
8377 | /// it is already instantiated (but we entered a context where we |
8378 | /// would have had to if it was not already instantiated). |
8379 | Memoization |
8380 | } Kind; |
8381 | |
8382 | /// Was the enclosing context a non-instantiation SFINAE context? |
8383 | bool SavedInNonInstantiationSFINAEContext; |
8384 | |
8385 | /// The point of instantiation or synthesis within the source code. |
8386 | SourceLocation PointOfInstantiation; |
8387 | |
8388 | /// The entity that is being synthesized. |
8389 | Decl *Entity; |
8390 | |
8391 | /// The template (or partial specialization) in which we are |
8392 | /// performing the instantiation, for substitutions of prior template |
8393 | /// arguments. |
8394 | NamedDecl *Template; |
8395 | |
8396 | /// The list of template arguments we are substituting, if they |
8397 | /// are not part of the entity. |
8398 | const TemplateArgument *TemplateArgs; |
8399 | |
8400 | // FIXME: Wrap this union around more members, or perhaps store the |
8401 | // kind-specific members in the RAII object owning the context. |
8402 | union { |
8403 | /// The number of template arguments in TemplateArgs. |
8404 | unsigned NumTemplateArgs; |
8405 | |
8406 | /// The special member being declared or defined. |
8407 | CXXSpecialMember SpecialMember; |
8408 | }; |
8409 | |
8410 | ArrayRef<TemplateArgument> template_arguments() const { |
8411 | assert(Kind != DeclaringSpecialMember)((Kind != DeclaringSpecialMember) ? static_cast<void> ( 0) : __assert_fail ("Kind != DeclaringSpecialMember", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/include/clang/Sema/Sema.h" , 8411, __PRETTY_FUNCTION__)); |
8412 | return {TemplateArgs, NumTemplateArgs}; |
8413 | } |
8414 | |
8415 | /// The template deduction info object associated with the |
8416 | /// substitution or checking of explicit or deduced template arguments. |
8417 | sema::TemplateDeductionInfo *DeductionInfo; |
8418 | |
8419 | /// The source range that covers the construct that cause |
8420 | /// the instantiation, e.g., the template-id that causes a class |
8421 | /// template instantiation. |
8422 | SourceRange InstantiationRange; |
8423 | |
8424 | CodeSynthesisContext() |
8425 | : Kind(TemplateInstantiation), |
8426 | SavedInNonInstantiationSFINAEContext(false), Entity(nullptr), |
8427 | Template(nullptr), TemplateArgs(nullptr), NumTemplateArgs(0), |
8428 | DeductionInfo(nullptr) {} |
8429 | |
8430 | /// Determines whether this template is an actual instantiation |
8431 | /// that should be counted toward the maximum instantiation depth. |
8432 | bool isInstantiationRecord() const; |
8433 | }; |
8434 | |
8435 | /// List of active code synthesis contexts. |
8436 | /// |
8437 | /// This vector is treated as a stack. As synthesis of one entity requires |
8438 | /// synthesis of another, additional contexts are pushed onto the stack. |
8439 | SmallVector<CodeSynthesisContext, 16> CodeSynthesisContexts; |
8440 | |
8441 | /// Specializations whose definitions are currently being instantiated. |
8442 | llvm::DenseSet<std::pair<Decl *, unsigned>> InstantiatingSpecializations; |
8443 | |
8444 | /// Non-dependent types used in templates that have already been instantiated |
8445 | /// by some template instantiation. |
8446 | llvm::DenseSet<QualType> InstantiatedNonDependentTypes; |
8447 | |
8448 | /// Extra modules inspected when performing a lookup during a template |
8449 | /// instantiation. Computed lazily. |
8450 | SmallVector<Module*, 16> CodeSynthesisContextLookupModules; |
8451 | |
8452 | /// Cache of additional modules that should be used for name lookup |
8453 | /// within the current template instantiation. Computed lazily; use |
8454 | /// getLookupModules() to get a complete set. |
8455 | llvm::DenseSet<Module*> LookupModulesCache; |
8456 | |
8457 | /// Get the set of additional modules that should be checked during |
8458 | /// name lookup. A module and its imports become visible when instanting a |
8459 | /// template defined within it. |
8460 | llvm::DenseSet<Module*> &getLookupModules(); |
8461 | |
8462 | /// Map from the most recent declaration of a namespace to the most |
8463 | /// recent visible declaration of that namespace. |
8464 | llvm::DenseMap<NamedDecl*, NamedDecl*> VisibleNamespaceCache; |
8465 | |
8466 | /// Whether we are in a SFINAE context that is not associated with |
8467 | /// template instantiation. |
8468 | /// |
8469 | /// This is used when setting up a SFINAE trap (\c see SFINAETrap) outside |
8470 | /// of a template instantiation or template argument deduction. |
8471 | bool InNonInstantiationSFINAEContext; |
8472 | |
8473 | /// The number of \p CodeSynthesisContexts that are not template |
8474 | /// instantiations and, therefore, should not be counted as part of the |
8475 | /// instantiation depth. |
8476 | /// |
8477 | /// When the instantiation depth reaches the user-configurable limit |
8478 | /// \p LangOptions::InstantiationDepth we will abort instantiation. |
8479 | // FIXME: Should we have a similar limit for other forms of synthesis? |
8480 | unsigned NonInstantiationEntries; |
8481 | |
8482 | /// The depth of the context stack at the point when the most recent |
8483 | /// error or warning was produced. |
8484 | /// |
8485 | /// This value is used to suppress printing of redundant context stacks |
8486 | /// when there are multiple errors or warnings in the same instantiation. |
8487 | // FIXME: Does this belong in Sema? It's tough to implement it anywhere else. |
8488 | unsigned LastEmittedCodeSynthesisContextDepth = 0; |
8489 | |
8490 | /// The template instantiation callbacks to trace or track |
8491 | /// instantiations (objects can be chained). |
8492 | /// |
8493 | /// This callbacks is used to print, trace or track template |
8494 | /// instantiations as they are being constructed. |
8495 | std::vector<std::unique_ptr<TemplateInstantiationCallback>> |
8496 | TemplateInstCallbacks; |
8497 | |
8498 | /// The current index into pack expansion arguments that will be |
8499 | /// used for substitution of parameter packs. |
8500 | /// |
8501 | /// The pack expansion index will be -1 to indicate that parameter packs |
8502 | /// should be instantiated as themselves. Otherwise, the index specifies |
8503 | /// which argument within the parameter pack will be used for substitution. |
8504 | int ArgumentPackSubstitutionIndex; |
8505 | |
8506 | /// RAII object used to change the argument pack substitution index |
8507 | /// within a \c Sema object. |
8508 | /// |
8509 | /// See \c ArgumentPackSubstitutionIndex for more information. |
8510 | class ArgumentPackSubstitutionIndexRAII { |
8511 | Sema &Self; |
8512 | int OldSubstitutionIndex; |
8513 | |
8514 | public: |
8515 | ArgumentPackSubstitutionIndexRAII(Sema &Self, int NewSubstitutionIndex) |
8516 | : Self(Self), OldSubstitutionIndex(Self.ArgumentPackSubstitutionIndex) { |
8517 | Self.ArgumentPackSubstitutionIndex = NewSubstitutionIndex; |
8518 | } |
8519 | |
8520 | ~ArgumentPackSubstitutionIndexRAII() { |
8521 | Self.ArgumentPackSubstitutionIndex = OldSubstitutionIndex; |
8522 | } |
8523 | }; |
8524 | |
8525 | friend class ArgumentPackSubstitutionRAII; |
8526 | |
8527 | /// For each declaration that involved template argument deduction, the |
8528 | /// set of diagnostics that were suppressed during that template argument |
8529 | /// deduction. |
8530 | /// |
8531 | /// FIXME: Serialize this structure to the AST file. |
8532 | typedef llvm::DenseMap<Decl *, SmallVector<PartialDiagnosticAt, 1> > |
8533 | SuppressedDiagnosticsMap; |
8534 | SuppressedDiagnosticsMap SuppressedDiagnostics; |
8535 | |
8536 | /// A stack object to be created when performing template |
8537 | /// instantiation. |
8538 | /// |
8539 | /// Construction of an object of type \c InstantiatingTemplate |
8540 | /// pushes the current instantiation onto the stack of active |
8541 | /// instantiations. If the size of this stack exceeds the maximum |
8542 | /// number of recursive template instantiations, construction |
8543 | /// produces an error and evaluates true. |
8544 | /// |
8545 | /// Destruction of this object will pop the named instantiation off |
8546 | /// the stack. |
8547 | struct InstantiatingTemplate { |
8548 | /// Note that we are instantiating a class template, |
8549 | /// function template, variable template, alias template, |
8550 | /// or a member thereof. |
8551 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8552 | Decl *Entity, |
8553 | SourceRange InstantiationRange = SourceRange()); |
8554 | |
8555 | struct ExceptionSpecification {}; |
8556 | /// Note that we are instantiating an exception specification |
8557 | /// of a function template. |
8558 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8559 | FunctionDecl *Entity, ExceptionSpecification, |
8560 | SourceRange InstantiationRange = SourceRange()); |
8561 | |
8562 | /// Note that we are instantiating a default argument in a |
8563 | /// template-id. |
8564 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8565 | TemplateParameter Param, TemplateDecl *Template, |
8566 | ArrayRef<TemplateArgument> TemplateArgs, |
8567 | SourceRange InstantiationRange = SourceRange()); |
8568 | |
8569 | /// Note that we are substituting either explicitly-specified or |
8570 | /// deduced template arguments during function template argument deduction. |
8571 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8572 | FunctionTemplateDecl *FunctionTemplate, |
8573 | ArrayRef<TemplateArgument> TemplateArgs, |
8574 | CodeSynthesisContext::SynthesisKind Kind, |
8575 | sema::TemplateDeductionInfo &DeductionInfo, |
8576 | SourceRange InstantiationRange = SourceRange()); |
8577 | |
8578 | /// Note that we are instantiating as part of template |
8579 | /// argument deduction for a class template declaration. |
8580 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8581 | TemplateDecl *Template, |
8582 | ArrayRef<TemplateArgument> TemplateArgs, |
8583 | sema::TemplateDeductionInfo &DeductionInfo, |
8584 | SourceRange InstantiationRange = SourceRange()); |
8585 | |
8586 | /// Note that we are instantiating as part of template |
8587 | /// argument deduction for a class template partial |
8588 | /// specialization. |
8589 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8590 | ClassTemplatePartialSpecializationDecl *PartialSpec, |
8591 | ArrayRef<TemplateArgument> TemplateArgs, |
8592 | sema::TemplateDeductionInfo &DeductionInfo, |
8593 | SourceRange InstantiationRange = SourceRange()); |
8594 | |
8595 | /// Note that we are instantiating as part of template |
8596 | /// argument deduction for a variable template partial |
8597 | /// specialization. |
8598 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8599 | VarTemplatePartialSpecializationDecl *PartialSpec, |
8600 | ArrayRef<TemplateArgument> TemplateArgs, |
8601 | sema::TemplateDeductionInfo &DeductionInfo, |
8602 | SourceRange InstantiationRange = SourceRange()); |
8603 | |
8604 | /// Note that we are instantiating a default argument for a function |
8605 | /// parameter. |
8606 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8607 | ParmVarDecl *Param, |
8608 | ArrayRef<TemplateArgument> TemplateArgs, |
8609 | SourceRange InstantiationRange = SourceRange()); |
8610 | |
8611 | /// Note that we are substituting prior template arguments into a |
8612 | /// non-type parameter. |
8613 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8614 | NamedDecl *Template, |
8615 | NonTypeTemplateParmDecl *Param, |
8616 | ArrayRef<TemplateArgument> TemplateArgs, |
8617 | SourceRange InstantiationRange); |
8618 | |
8619 | /// Note that we are substituting prior template arguments into a |
8620 | /// template template parameter. |
8621 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8622 | NamedDecl *Template, |
8623 | TemplateTemplateParmDecl *Param, |
8624 | ArrayRef<TemplateArgument> TemplateArgs, |
8625 | SourceRange InstantiationRange); |
8626 | |
8627 | /// Note that we are checking the default template argument |
8628 | /// against the template parameter for a given template-id. |
8629 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8630 | TemplateDecl *Template, |
8631 | NamedDecl *Param, |
8632 | ArrayRef<TemplateArgument> TemplateArgs, |
8633 | SourceRange InstantiationRange); |
8634 | |
8635 | struct ConstraintsCheck {}; |
8636 | /// \brief Note that we are checking the constraints associated with some |
8637 | /// constrained entity (a concept declaration or a template with associated |
8638 | /// constraints). |
8639 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8640 | ConstraintsCheck, NamedDecl *Template, |
8641 | ArrayRef<TemplateArgument> TemplateArgs, |
8642 | SourceRange InstantiationRange); |
8643 | |
8644 | struct ConstraintSubstitution {}; |
8645 | /// \brief Note that we are checking a constraint expression associated |
8646 | /// with a template declaration or as part of the satisfaction check of a |
8647 | /// concept. |
8648 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8649 | ConstraintSubstitution, NamedDecl *Template, |
8650 | sema::TemplateDeductionInfo &DeductionInfo, |
8651 | SourceRange InstantiationRange); |
8652 | |
8653 | struct ConstraintNormalization {}; |
8654 | /// \brief Note that we are normalizing a constraint expression. |
8655 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8656 | ConstraintNormalization, NamedDecl *Template, |
8657 | SourceRange InstantiationRange); |
8658 | |
8659 | struct ParameterMappingSubstitution {}; |
8660 | /// \brief Note that we are subtituting into the parameter mapping of an |
8661 | /// atomic constraint during constraint normalization. |
8662 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8663 | ParameterMappingSubstitution, NamedDecl *Template, |
8664 | SourceRange InstantiationRange); |
8665 | |
8666 | /// \brief Note that we are substituting template arguments into a part of |
8667 | /// a requirement of a requires expression. |
8668 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8669 | concepts::Requirement *Req, |
8670 | sema::TemplateDeductionInfo &DeductionInfo, |
8671 | SourceRange InstantiationRange = SourceRange()); |
8672 | |
8673 | /// \brief Note that we are checking the satisfaction of the constraint |
8674 | /// expression inside of a nested requirement. |
8675 | InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, |
8676 | concepts::NestedRequirement *Req, ConstraintsCheck, |
8677 | SourceRange InstantiationRange = SourceRange()); |
8678 | |
8679 | /// Note that we have finished instantiating this template. |
8680 | void Clear(); |
8681 | |
8682 | ~InstantiatingTemplate() { Clear(); } |
8683 | |
8684 | /// Determines whether we have exceeded the maximum |
8685 | /// recursive template instantiations. |
8686 | bool isInvalid() const { return Invalid; } |
8687 | |
8688 | /// Determine whether we are already instantiating this |
8689 | /// specialization in some surrounding active instantiation. |
8690 | bool isAlreadyInstantiating() const { return AlreadyInstantiating; } |
8691 | |
8692 | private: |
8693 | Sema &SemaRef; |
8694 | bool Invalid; |
8695 | bool AlreadyInstantiating; |
8696 | bool CheckInstantiationDepth(SourceLocation PointOfInstantiation, |
8697 | SourceRange InstantiationRange); |
8698 | |
8699 | InstantiatingTemplate( |
8700 | Sema &SemaRef, CodeSynthesisContext::SynthesisKind Kind, |
8701 | SourceLocation PointOfInstantiation, SourceRange InstantiationRange, |
8702 | Decl *Entity, NamedDecl *Template = nullptr, |
8703 | ArrayRef<TemplateArgument> TemplateArgs = None, |
8704 | sema::TemplateDeductionInfo *DeductionInfo = nullptr); |
8705 | |
8706 | InstantiatingTemplate(const InstantiatingTemplate&) = delete; |
8707 | |
8708 | InstantiatingTemplate& |
8709 | operator=(const InstantiatingTemplate&) = delete; |
8710 | }; |
8711 | |
8712 | void pushCodeSynthesisContext(CodeSynthesisContext Ctx); |
8713 | void popCodeSynthesisContext(); |
8714 | |
8715 | /// Determine whether we are currently performing template instantiation. |
8716 | bool inTemplateInstantiation() const { |
8717 | return CodeSynthesisContexts.size() > NonInstantiationEntries; |
8718 | } |
8719 | |
8720 | void PrintContextStack() { |
8721 | if (!CodeSynthesisContexts.empty() && |
8722 | CodeSynthesisContexts.size() != LastEmittedCodeSynthesisContextDepth) { |
8723 | PrintInstantiationStack(); |
8724 | LastEmittedCodeSynthesisContextDepth = CodeSynthesisContexts.size(); |
8725 | } |
8726 | if (PragmaAttributeCurrentTargetDecl) |
8727 | PrintPragmaAttributeInstantiationPoint(); |
8728 | } |
8729 | void PrintInstantiationStack(); |
8730 | |
8731 | void PrintPragmaAttributeInstantiationPoint(); |
8732 | |
8733 | /// Determines whether we are currently in a context where |
8734 | /// template argument substitution failures are not considered |
8735 | /// errors. |
8736 | /// |
8737 | /// \returns An empty \c Optional if we're not in a SFINAE context. |
8738 | /// Otherwise, contains a pointer that, if non-NULL, contains the nearest |
8739 | /// template-deduction context object, which can be used to capture |
8740 | /// diagnostics that will be suppressed. |
8741 | Optional<sema::TemplateDeductionInfo *> isSFINAEContext() const; |
8742 | |
8743 | /// Determines whether we are currently in a context that |
8744 | /// is not evaluated as per C++ [expr] p5. |
8745 | bool isUnevaluatedContext() const { |
8746 | 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~++20200806111125+5446ec85070/clang/include/clang/Sema/Sema.h" , 8747, __PRETTY_FUNCTION__)) |
8747 | "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~++20200806111125+5446ec85070/clang/include/clang/Sema/Sema.h" , 8747, __PRETTY_FUNCTION__)); |
8748 | return ExprEvalContexts.back().isUnevaluated(); |
8749 | } |
8750 | |
8751 | /// RAII class used to determine whether SFINAE has |
8752 | /// trapped any errors that occur during template argument |
8753 | /// deduction. |
8754 | class SFINAETrap { |
8755 | Sema &SemaRef; |
8756 | unsigned PrevSFINAEErrors; |
8757 | bool PrevInNonInstantiationSFINAEContext; |
8758 | bool PrevAccessCheckingSFINAE; |
8759 | bool PrevLastDiagnosticIgnored; |
8760 | |
8761 | public: |
8762 | explicit SFINAETrap(Sema &SemaRef, bool AccessCheckingSFINAE = false) |
8763 | : SemaRef(SemaRef), PrevSFINAEErrors(SemaRef.NumSFINAEErrors), |
8764 | PrevInNonInstantiationSFINAEContext( |
8765 | SemaRef.InNonInstantiationSFINAEContext), |
8766 | PrevAccessCheckingSFINAE(SemaRef.AccessCheckingSFINAE), |
8767 | PrevLastDiagnosticIgnored( |
8768 | SemaRef.getDiagnostics().isLastDiagnosticIgnored()) |
8769 | { |
8770 | if (!SemaRef.isSFINAEContext()) |
8771 | SemaRef.InNonInstantiationSFINAEContext = true; |
8772 | SemaRef.AccessCheckingSFINAE = AccessCheckingSFINAE; |
8773 | } |
8774 | |
8775 | ~SFINAETrap() { |
8776 | SemaRef.NumSFINAEErrors = PrevSFINAEErrors; |
8777 | SemaRef.InNonInstantiationSFINAEContext |
8778 | = PrevInNonInstantiationSFINAEContext; |
8779 | SemaRef.AccessCheckingSFINAE = PrevAccessCheckingSFINAE; |
8780 | SemaRef.getDiagnostics().setLastDiagnosticIgnored( |
8781 | PrevLastDiagnosticIgnored); |
8782 | } |
8783 | |
8784 | /// Determine whether any SFINAE errors have been trapped. |
8785 | bool hasErrorOccurred() const { |
8786 | return SemaRef.NumSFINAEErrors > PrevSFINAEErrors; |
8787 | } |
8788 | }; |
8789 | |
8790 | /// RAII class used to indicate that we are performing provisional |
8791 | /// semantic analysis to determine the validity of a construct, so |
8792 | /// typo-correction and diagnostics in the immediate context (not within |
8793 | /// implicitly-instantiated templates) should be suppressed. |
8794 | class TentativeAnalysisScope { |
8795 | Sema &SemaRef; |
8796 | // FIXME: Using a SFINAETrap for this is a hack. |
8797 | SFINAETrap Trap; |
8798 | bool PrevDisableTypoCorrection; |
8799 | public: |
8800 | explicit TentativeAnalysisScope(Sema &SemaRef) |
8801 | : SemaRef(SemaRef), Trap(SemaRef, true), |
8802 | PrevDisableTypoCorrection(SemaRef.DisableTypoCorrection) { |
8803 | SemaRef.DisableTypoCorrection = true; |
8804 | } |
8805 | ~TentativeAnalysisScope() { |
8806 | SemaRef.DisableTypoCorrection = PrevDisableTypoCorrection; |
8807 | } |
8808 | }; |
8809 | |
8810 | /// The current instantiation scope used to store local |
8811 | /// variables. |
8812 | LocalInstantiationScope *CurrentInstantiationScope; |
8813 | |
8814 | /// Tracks whether we are in a context where typo correction is |
8815 | /// disabled. |
8816 | bool DisableTypoCorrection; |
8817 | |
8818 | /// The number of typos corrected by CorrectTypo. |
8819 | unsigned TyposCorrected; |
8820 | |
8821 | typedef llvm::SmallSet<SourceLocation, 2> SrcLocSet; |
8822 | typedef llvm::DenseMap<IdentifierInfo *, SrcLocSet> IdentifierSourceLocations; |
8823 | |
8824 | /// A cache containing identifiers for which typo correction failed and |
8825 | /// their locations, so that repeated attempts to correct an identifier in a |
8826 | /// given location are ignored if typo correction already failed for it. |
8827 | IdentifierSourceLocations TypoCorrectionFailures; |
8828 | |
8829 | /// Worker object for performing CFG-based warnings. |
8830 | sema::AnalysisBasedWarnings AnalysisWarnings; |
8831 | threadSafety::BeforeSet *ThreadSafetyDeclCache; |
8832 | |
8833 | /// An entity for which implicit template instantiation is required. |
8834 | /// |
8835 | /// The source location associated with the declaration is the first place in |
8836 | /// the source code where the declaration was "used". It is not necessarily |
8837 | /// the point of instantiation (which will be either before or after the |
8838 | /// namespace-scope declaration that triggered this implicit instantiation), |
8839 | /// However, it is the location that diagnostics should generally refer to, |
8840 | /// because users will need to know what code triggered the instantiation. |
8841 | typedef std::pair<ValueDecl *, SourceLocation> PendingImplicitInstantiation; |
8842 | |
8843 | /// The queue of implicit template instantiations that are required |
8844 | /// but have not yet been performed. |
8845 | std::deque<PendingImplicitInstantiation> PendingInstantiations; |
8846 | |
8847 | /// Queue of implicit template instantiations that cannot be performed |
8848 | /// eagerly. |
8849 | SmallVector<PendingImplicitInstantiation, 1> LateParsedInstantiations; |
8850 | |
8851 | class GlobalEagerInstantiationScope { |
8852 | public: |
8853 | GlobalEagerInstantiationScope(Sema &S, bool Enabled) |
8854 | : S(S), Enabled(Enabled) { |
8855 | if (!Enabled) return; |
8856 | |
8857 | SavedPendingInstantiations.swap(S.PendingInstantiations); |
8858 | SavedVTableUses.swap(S.VTableUses); |
8859 | } |
8860 | |
8861 | void perform() { |
8862 | if (Enabled) { |
8863 | S.DefineUsedVTables(); |
8864 | S.PerformPendingInstantiations(); |
8865 | } |
8866 | } |
8867 | |
8868 | ~GlobalEagerInstantiationScope() { |
8869 | if (!Enabled) return; |
8870 | |
8871 | // Restore the set of pending vtables. |
8872 | 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~++20200806111125+5446ec85070/clang/include/clang/Sema/Sema.h" , 8873, __PRETTY_FUNCTION__)) |
8873 | "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~++20200806111125+5446ec85070/clang/include/clang/Sema/Sema.h" , 8873, __PRETTY_FUNCTION__)); |
8874 | S.VTableUses.swap(SavedVTableUses); |
8875 | |
8876 | // Restore the set of pending implicit instantiations. |
8877 | if (S.TUKind != TU_Prefix || !S.LangOpts.PCHInstantiateTemplates) { |
8878 | 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~++20200806111125+5446ec85070/clang/include/clang/Sema/Sema.h" , 8879, __PRETTY_FUNCTION__)) |
8879 | "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~++20200806111125+5446ec85070/clang/include/clang/Sema/Sema.h" , 8879, __PRETTY_FUNCTION__)); |
8880 | S.PendingInstantiations.swap(SavedPendingInstantiations); |
8881 | } else { |
8882 | // Template instantiations in the PCH may be delayed until the TU. |
8883 | S.PendingInstantiations.swap(SavedPendingInstantiations); |
8884 | S.PendingInstantiations.insert(S.PendingInstantiations.end(), |
8885 | SavedPendingInstantiations.begin(), |
8886 | SavedPendingInstantiations.end()); |
8887 | } |
8888 | } |
8889 | |
8890 | private: |
8891 | Sema &S; |
8892 | SmallVector<VTableUse, 16> SavedVTableUses; |
8893 | std::deque<PendingImplicitInstantiation> SavedPendingInstantiations; |
8894 | bool Enabled; |
8895 | }; |
8896 | |
8897 | /// The queue of implicit template instantiations that are required |
8898 | /// and must be performed within the current local scope. |
8899 | /// |
8900 | /// This queue is only used for member functions of local classes in |
8901 | /// templates, which must be instantiated in the same scope as their |
8902 | /// enclosing function, so that they can reference function-local |
8903 | /// types, static variables, enumerators, etc. |
8904 | std::deque<PendingImplicitInstantiation> PendingLocalImplicitInstantiations; |
8905 | |
8906 | class LocalEagerInstantiationScope { |
8907 | public: |
8908 | LocalEagerInstantiationScope(Sema &S) : S(S) { |
8909 | SavedPendingLocalImplicitInstantiations.swap( |
8910 | S.PendingLocalImplicitInstantiations); |
8911 | } |
8912 | |
8913 | void perform() { S.PerformPendingInstantiations(/*LocalOnly=*/true); } |
8914 | |
8915 | ~LocalEagerInstantiationScope() { |
8916 | 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~++20200806111125+5446ec85070/clang/include/clang/Sema/Sema.h" , 8917, __PRETTY_FUNCTION__)) |
8917 | "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~++20200806111125+5446ec85070/clang/include/clang/Sema/Sema.h" , 8917, __PRETTY_FUNCTION__)); |
8918 | SavedPendingLocalImplicitInstantiations.swap( |
8919 | S.PendingLocalImplicitInstantiations); |
8920 | } |
8921 | |
8922 | private: |
8923 | Sema &S; |
8924 | std::deque<PendingImplicitInstantiation> |
8925 | SavedPendingLocalImplicitInstantiations; |
8926 | }; |
8927 | |
8928 | /// A helper class for building up ExtParameterInfos. |
8929 | class ExtParameterInfoBuilder { |
8930 | SmallVector<FunctionProtoType::ExtParameterInfo, 16> Infos; |
8931 | bool HasInteresting = false; |
8932 | |
8933 | public: |
8934 | /// Set the ExtParameterInfo for the parameter at the given index, |
8935 | /// |
8936 | void set(unsigned index, FunctionProtoType::ExtParameterInfo info) { |
8937 | assert(Infos.size() <= index)((Infos.size() <= index) ? static_cast<void> (0) : __assert_fail ("Infos.size() <= index", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/include/clang/Sema/Sema.h" , 8937, __PRETTY_FUNCTION__)); |
8938 | Infos.resize(index); |
8939 | Infos.push_back(info); |
8940 | |
8941 | if (!HasInteresting) |
8942 | HasInteresting = (info != FunctionProtoType::ExtParameterInfo()); |
8943 | } |
8944 | |
8945 | /// Return a pointer (suitable for setting in an ExtProtoInfo) to the |
8946 | /// ExtParameterInfo array we've built up. |
8947 | const FunctionProtoType::ExtParameterInfo * |
8948 | getPointerOrNull(unsigned numParams) { |
8949 | if (!HasInteresting) return nullptr; |
8950 | Infos.resize(numParams); |
8951 | return Infos.data(); |
8952 | } |
8953 | }; |
8954 | |
8955 | void PerformPendingInstantiations(bool LocalOnly = false); |
8956 | |
8957 | TypeSourceInfo *SubstType(TypeSourceInfo *T, |
8958 | const MultiLevelTemplateArgumentList &TemplateArgs, |
8959 | SourceLocation Loc, DeclarationName Entity, |
8960 | bool AllowDeducedTST = false); |
8961 | |
8962 | QualType SubstType(QualType T, |
8963 | const MultiLevelTemplateArgumentList &TemplateArgs, |
8964 | SourceLocation Loc, DeclarationName Entity); |
8965 | |
8966 | TypeSourceInfo *SubstType(TypeLoc TL, |
8967 | const MultiLevelTemplateArgumentList &TemplateArgs, |
8968 | SourceLocation Loc, DeclarationName Entity); |
8969 | |
8970 | TypeSourceInfo *SubstFunctionDeclType(TypeSourceInfo *T, |
8971 | const MultiLevelTemplateArgumentList &TemplateArgs, |
8972 | SourceLocation Loc, |
8973 | DeclarationName Entity, |
8974 | CXXRecordDecl *ThisContext, |
8975 | Qualifiers ThisTypeQuals); |
8976 | void SubstExceptionSpec(FunctionDecl *New, const FunctionProtoType *Proto, |
8977 | const MultiLevelTemplateArgumentList &Args); |
8978 | bool SubstExceptionSpec(SourceLocation Loc, |
8979 | FunctionProtoType::ExceptionSpecInfo &ESI, |
8980 | SmallVectorImpl<QualType> &ExceptionStorage, |
8981 | const MultiLevelTemplateArgumentList &Args); |
8982 | ParmVarDecl *SubstParmVarDecl(ParmVarDecl *D, |
8983 | const MultiLevelTemplateArgumentList &TemplateArgs, |
8984 | int indexAdjustment, |
8985 | Optional<unsigned> NumExpansions, |
8986 | bool ExpectParameterPack); |
8987 | bool SubstParmTypes(SourceLocation Loc, ArrayRef<ParmVarDecl *> Params, |
8988 | const FunctionProtoType::ExtParameterInfo *ExtParamInfos, |
8989 | const MultiLevelTemplateArgumentList &TemplateArgs, |
8990 | SmallVectorImpl<QualType> &ParamTypes, |
8991 | SmallVectorImpl<ParmVarDecl *> *OutParams, |
8992 | ExtParameterInfoBuilder &ParamInfos); |
8993 | ExprResult SubstExpr(Expr *E, |
8994 | const MultiLevelTemplateArgumentList &TemplateArgs); |
8995 | |
8996 | /// Substitute the given template arguments into a list of |
8997 | /// expressions, expanding pack expansions if required. |
8998 | /// |
8999 | /// \param Exprs The list of expressions to substitute into. |
9000 | /// |
9001 | /// \param IsCall Whether this is some form of call, in which case |
9002 | /// default arguments will be dropped. |
9003 | /// |
9004 | /// \param TemplateArgs The set of template arguments to substitute. |
9005 | /// |
9006 | /// \param Outputs Will receive all of the substituted arguments. |
9007 | /// |
9008 | /// \returns true if an error occurred, false otherwise. |
9009 | bool SubstExprs(ArrayRef<Expr *> Exprs, bool IsCall, |
9010 | const MultiLevelTemplateArgumentList &TemplateArgs, |
9011 | SmallVectorImpl<Expr *> &Outputs); |
9012 | |
9013 | StmtResult SubstStmt(Stmt *S, |
9014 | const MultiLevelTemplateArgumentList &TemplateArgs); |
9015 | |
9016 | TemplateParameterList * |
9017 | SubstTemplateParams(TemplateParameterList *Params, DeclContext *Owner, |
9018 | const MultiLevelTemplateArgumentList &TemplateArgs); |
9019 | |
9020 | bool |
9021 | SubstTemplateArguments(ArrayRef<TemplateArgumentLoc> Args, |
9022 | const MultiLevelTemplateArgumentList &TemplateArgs, |
9023 | TemplateArgumentListInfo &Outputs); |
9024 | |
9025 | |
9026 | Decl *SubstDecl(Decl *D, DeclContext *Owner, |
9027 | const MultiLevelTemplateArgumentList &TemplateArgs); |
9028 | |
9029 | /// Substitute the name and return type of a defaulted 'operator<=>' to form |
9030 | /// an implicit 'operator=='. |
9031 | FunctionDecl *SubstSpaceshipAsEqualEqual(CXXRecordDecl *RD, |
9032 | FunctionDecl *Spaceship); |
9033 | |
9034 | ExprResult SubstInitializer(Expr *E, |
9035 | const MultiLevelTemplateArgumentList &TemplateArgs, |
9036 | bool CXXDirectInit); |
9037 | |
9038 | bool |
9039 | SubstBaseSpecifiers(CXXRecordDecl *Instantiation, |
9040 | CXXRecordDecl *Pattern, |
9041 | const MultiLevelTemplateArgumentList &TemplateArgs); |
9042 | |
9043 | bool |
9044 | InstantiateClass(SourceLocation PointOfInstantiation, |
9045 | CXXRecordDecl *Instantiation, CXXRecordDecl *Pattern, |
9046 | const MultiLevelTemplateArgumentList &TemplateArgs, |
9047 | TemplateSpecializationKind TSK, |
9048 | bool Complain = true); |
9049 | |
9050 | bool InstantiateEnum(SourceLocation PointOfInstantiation, |
9051 | EnumDecl *Instantiation, EnumDecl *Pattern, |
9052 | const MultiLevelTemplateArgumentList &TemplateArgs, |
9053 | TemplateSpecializationKind TSK); |
9054 | |
9055 | bool InstantiateInClassInitializer( |
9056 | SourceLocation PointOfInstantiation, FieldDecl *Instantiation, |
9057 | FieldDecl *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs); |
9058 | |
9059 | struct LateInstantiatedAttribute { |
9060 | const Attr *TmplAttr; |
9061 | LocalInstantiationScope *Scope; |
9062 | Decl *NewDecl; |
9063 | |
9064 | LateInstantiatedAttribute(const Attr *A, LocalInstantiationScope *S, |
9065 | Decl *D) |
9066 | : TmplAttr(A), Scope(S), NewDecl(D) |
9067 | { } |
9068 | }; |
9069 | typedef SmallVector<LateInstantiatedAttribute, 16> LateInstantiatedAttrVec; |
9070 | |
9071 | void InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, |
9072 | const Decl *Pattern, Decl *Inst, |
9073 | LateInstantiatedAttrVec *LateAttrs = nullptr, |
9074 | LocalInstantiationScope *OuterMostScope = nullptr); |
9075 | |
9076 | void |
9077 | InstantiateAttrsForDecl(const MultiLevelTemplateArgumentList &TemplateArgs, |
9078 | const Decl *Pattern, Decl *Inst, |
9079 | LateInstantiatedAttrVec *LateAttrs = nullptr, |
9080 | LocalInstantiationScope *OuterMostScope = nullptr); |
9081 | |
9082 | bool usesPartialOrExplicitSpecialization( |
9083 | SourceLocation Loc, ClassTemplateSpecializationDecl *ClassTemplateSpec); |
9084 | |
9085 | bool |
9086 | InstantiateClassTemplateSpecialization(SourceLocation PointOfInstantiation, |
9087 | ClassTemplateSpecializationDecl *ClassTemplateSpec, |
9088 | TemplateSpecializationKind TSK, |
9089 | bool Complain = true); |
9090 | |
9091 | void InstantiateClassMembers(SourceLocation PointOfInstantiation, |
9092 | CXXRecordDecl *Instantiation, |
9093 | const MultiLevelTemplateArgumentList &TemplateArgs, |
9094 | TemplateSpecializationKind TSK); |
9095 | |
9096 | void InstantiateClassTemplateSpecializationMembers( |
9097 | SourceLocation PointOfInstantiation, |
9098 | ClassTemplateSpecializationDecl *ClassTemplateSpec, |
9099 | TemplateSpecializationKind TSK); |
9100 | |
9101 | NestedNameSpecifierLoc |
9102 | SubstNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, |
9103 | const MultiLevelTemplateArgumentList &TemplateArgs); |
9104 | |
9105 | DeclarationNameInfo |
9106 | SubstDeclarationNameInfo(const DeclarationNameInfo &NameInfo, |
9107 | const MultiLevelTemplateArgumentList &TemplateArgs); |
9108 | TemplateName |
9109 | SubstTemplateName(NestedNameSpecifierLoc QualifierLoc, TemplateName Name, |
9110 | SourceLocation Loc, |
9111 | const MultiLevelTemplateArgumentList &TemplateArgs); |
9112 | bool Subst(const TemplateArgumentLoc *Args, unsigned NumArgs, |
9113 | TemplateArgumentListInfo &Result, |
9114 | const MultiLevelTemplateArgumentList &TemplateArgs); |
9115 | |
9116 | bool InstantiateDefaultArgument(SourceLocation CallLoc, FunctionDecl *FD, |
9117 | ParmVarDecl *Param); |
9118 | void InstantiateExceptionSpec(SourceLocation PointOfInstantiation, |
9119 | FunctionDecl *Function); |
9120 | bool CheckInstantiatedFunctionTemplateConstraints( |
9121 | SourceLocation PointOfInstantiation, FunctionDecl *Decl, |
9122 | ArrayRef<TemplateArgument> TemplateArgs, |
9123 | ConstraintSatisfaction &Satisfaction); |
9124 | FunctionDecl *InstantiateFunctionDeclaration(FunctionTemplateDecl *FTD, |
9125 | const TemplateArgumentList *Args, |
9126 | SourceLocation Loc); |
9127 | void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, |
9128 | FunctionDecl *Function, |
9129 | bool Recursive = false, |
9130 | bool DefinitionRequired = false, |
9131 | bool AtEndOfTU = false); |
9132 | VarTemplateSpecializationDecl *BuildVarTemplateInstantiation( |
9133 | VarTemplateDecl *VarTemplate, VarDecl *FromVar, |
9134 | const TemplateArgumentList &TemplateArgList, |
9135 | const TemplateArgumentListInfo &TemplateArgsInfo, |
9136 | SmallVectorImpl<TemplateArgument> &Converted, |
9137 | SourceLocation PointOfInstantiation, void *InsertPos, |
9138 | LateInstantiatedAttrVec *LateAttrs = nullptr, |
9139 | LocalInstantiationScope *StartingScope = nullptr); |
9140 | VarTemplateSpecializationDecl *CompleteVarTemplateSpecializationDecl( |
9141 | VarTemplateSpecializationDecl *VarSpec, VarDecl *PatternDecl, |
9142 | const MultiLevelTemplateArgumentList &TemplateArgs); |
9143 | void |
9144 | BuildVariableInstantiation(VarDecl *NewVar, VarDecl *OldVar, |
9145 | const MultiLevelTemplateArgumentList &TemplateArgs, |
9146 | LateInstantiatedAttrVec *LateAttrs, |
9147 | DeclContext *Owner, |
9148 | LocalInstantiationScope *StartingScope, |
9149 | bool InstantiatingVarTemplate = false, |
9150 | VarTemplateSpecializationDecl *PrevVTSD = nullptr); |
9151 | |
9152 | VarDecl *getVarTemplateSpecialization( |
9153 | VarTemplateDecl *VarTempl, const TemplateArgumentListInfo *TemplateArgs, |
9154 | const DeclarationNameInfo &MemberNameInfo, SourceLocation TemplateKWLoc); |
9155 | |
9156 | void InstantiateVariableInitializer( |
9157 | VarDecl *Var, VarDecl *OldVar, |
9158 | const MultiLevelTemplateArgumentList &TemplateArgs); |
9159 | void InstantiateVariableDefinition(SourceLocation PointOfInstantiation, |
9160 | VarDecl *Var, bool Recursive = false, |
9161 | bool DefinitionRequired = false, |
9162 | bool AtEndOfTU = false); |
9163 | |
9164 | void InstantiateMemInitializers(CXXConstructorDecl *New, |
9165 | const CXXConstructorDecl *Tmpl, |
9166 | const MultiLevelTemplateArgumentList &TemplateArgs); |
9167 | |
9168 | NamedDecl *FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, |
9169 | const MultiLevelTemplateArgumentList &TemplateArgs, |
9170 | bool FindingInstantiatedContext = false); |
9171 | DeclContext *FindInstantiatedContext(SourceLocation Loc, DeclContext *DC, |
9172 | const MultiLevelTemplateArgumentList &TemplateArgs); |
9173 | |
9174 | // Objective-C declarations. |
9175 | enum ObjCContainerKind { |
9176 | OCK_None = -1, |
9177 | OCK_Interface = 0, |
9178 | OCK_Protocol, |
9179 | OCK_Category, |
9180 | OCK_ClassExtension, |
9181 | OCK_Implementation, |
9182 | OCK_CategoryImplementation |
9183 | }; |
9184 | ObjCContainerKind getObjCContainerKind() const; |
9185 | |
9186 | DeclResult actOnObjCTypeParam(Scope *S, |
9187 | ObjCTypeParamVariance variance, |
9188 | SourceLocation varianceLoc, |
9189 | unsigned index, |
9190 | IdentifierInfo *paramName, |
9191 | SourceLocation paramLoc, |
9192 | SourceLocation colonLoc, |
9193 | ParsedType typeBound); |
9194 | |
9195 | ObjCTypeParamList *actOnObjCTypeParamList(Scope *S, SourceLocation lAngleLoc, |
9196 | ArrayRef<Decl *> typeParams, |
9197 | SourceLocation rAngleLoc); |
9198 | void popObjCTypeParamList(Scope *S, ObjCTypeParamList *typeParamList); |
9199 | |
9200 | Decl *ActOnStartClassInterface( |
9201 | Scope *S, SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName, |
9202 | SourceLocation ClassLoc, ObjCTypeParamList *typeParamList, |
9203 | IdentifierInfo *SuperName, SourceLocation SuperLoc, |
9204 | ArrayRef<ParsedType> SuperTypeArgs, SourceRange SuperTypeArgsRange, |
9205 | Decl *const *ProtoRefs, unsigned NumProtoRefs, |
9206 | const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, |
9207 | const ParsedAttributesView &AttrList); |
9208 | |
9209 | void ActOnSuperClassOfClassInterface(Scope *S, |
9210 | SourceLocation AtInterfaceLoc, |
9211 | ObjCInterfaceDecl *IDecl, |
9212 | IdentifierInfo *ClassName, |
9213 | SourceLocation ClassLoc, |
9214 | IdentifierInfo *SuperName, |
9215 | SourceLocation SuperLoc, |
9216 | ArrayRef<ParsedType> SuperTypeArgs, |
9217 | SourceRange SuperTypeArgsRange); |
9218 | |
9219 | void ActOnTypedefedProtocols(SmallVectorImpl<Decl *> &ProtocolRefs, |
9220 | SmallVectorImpl<SourceLocation> &ProtocolLocs, |
9221 | IdentifierInfo *SuperName, |
9222 | SourceLocation SuperLoc); |
9223 | |
9224 | Decl *ActOnCompatibilityAlias( |
9225 | SourceLocation AtCompatibilityAliasLoc, |
9226 | IdentifierInfo *AliasName, SourceLocation AliasLocation, |
9227 | IdentifierInfo *ClassName, SourceLocation ClassLocation); |
9228 | |
9229 | bool CheckForwardProtocolDeclarationForCircularDependency( |
9230 | IdentifierInfo *PName, |
9231 | SourceLocation &PLoc, SourceLocation PrevLoc, |
9232 | const ObjCList<ObjCProtocolDecl> &PList); |
9233 | |
9234 | Decl *ActOnStartProtocolInterface( |
9235 | SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName, |
9236 | SourceLocation ProtocolLoc, Decl *const *ProtoRefNames, |
9237 | unsigned NumProtoRefs, const SourceLocation *ProtoLocs, |
9238 | SourceLocation EndProtoLoc, const ParsedAttributesView &AttrList); |
9239 | |
9240 | Decl *ActOnStartCategoryInterface( |
9241 | SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName, |
9242 | SourceLocation ClassLoc, ObjCTypeParamList *typeParamList, |
9243 | IdentifierInfo *CategoryName, SourceLocation CategoryLoc, |
9244 | Decl *const *ProtoRefs, unsigned NumProtoRefs, |
9245 | const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, |
9246 | const ParsedAttributesView &AttrList); |
9247 | |
9248 | Decl *ActOnStartClassImplementation(SourceLocation AtClassImplLoc, |
9249 | IdentifierInfo *ClassName, |
9250 | SourceLocation ClassLoc, |
9251 | IdentifierInfo *SuperClassname, |
9252 | SourceLocation SuperClassLoc, |
9253 | const ParsedAttributesView &AttrList); |
9254 | |
9255 | Decl *ActOnStartCategoryImplementation(SourceLocation AtCatImplLoc, |
9256 | IdentifierInfo *ClassName, |
9257 | SourceLocation ClassLoc, |
9258 | IdentifierInfo *CatName, |
9259 | SourceLocation CatLoc, |
9260 | const ParsedAttributesView &AttrList); |
9261 | |
9262 | DeclGroupPtrTy ActOnFinishObjCImplementation(Decl *ObjCImpDecl, |
9263 | ArrayRef<Decl *> Decls); |
9264 | |
9265 | DeclGroupPtrTy ActOnForwardClassDeclaration(SourceLocation Loc, |
9266 | IdentifierInfo **IdentList, |
9267 | SourceLocation *IdentLocs, |
9268 | ArrayRef<ObjCTypeParamList *> TypeParamLists, |
9269 | unsigned NumElts); |
9270 | |
9271 | DeclGroupPtrTy |
9272 | ActOnForwardProtocolDeclaration(SourceLocation AtProtoclLoc, |
9273 | ArrayRef<IdentifierLocPair> IdentList, |
9274 | const ParsedAttributesView &attrList); |
9275 | |
9276 | void FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer, |
9277 | ArrayRef<IdentifierLocPair> ProtocolId, |
9278 | SmallVectorImpl<Decl *> &Protocols); |
9279 | |
9280 | void DiagnoseTypeArgsAndProtocols(IdentifierInfo *ProtocolId, |
9281 | SourceLocation ProtocolLoc, |
9282 | IdentifierInfo *TypeArgId, |
9283 | SourceLocation TypeArgLoc, |
9284 | bool SelectProtocolFirst = false); |
9285 | |
9286 | /// Given a list of identifiers (and their locations), resolve the |
9287 | /// names to either Objective-C protocol qualifiers or type |
9288 | /// arguments, as appropriate. |
9289 | void actOnObjCTypeArgsOrProtocolQualifiers( |
9290 | Scope *S, |
9291 | ParsedType baseType, |
9292 | SourceLocation lAngleLoc, |
9293 | ArrayRef<IdentifierInfo *> identifiers, |
9294 | ArrayRef<SourceLocation> identifierLocs, |
9295 | SourceLocation rAngleLoc, |
9296 | SourceLocation &typeArgsLAngleLoc, |
9297 | SmallVectorImpl<ParsedType> &typeArgs, |
9298 | SourceLocation &typeArgsRAngleLoc, |
9299 | SourceLocation &protocolLAngleLoc, |
9300 | SmallVectorImpl<Decl *> &protocols, |
9301 | SourceLocation &protocolRAngleLoc, |
9302 | bool warnOnIncompleteProtocols); |
9303 | |
9304 | /// Build a an Objective-C protocol-qualified 'id' type where no |
9305 | /// base type was specified. |
9306 | TypeResult actOnObjCProtocolQualifierType( |
9307 | SourceLocation lAngleLoc, |
9308 | ArrayRef<Decl *> protocols, |
9309 | ArrayRef<SourceLocation> protocolLocs, |
9310 | SourceLocation rAngleLoc); |
9311 | |
9312 | /// Build a specialized and/or protocol-qualified Objective-C type. |
9313 | TypeResult actOnObjCTypeArgsAndProtocolQualifiers( |
9314 | Scope *S, |
9315 | SourceLocation Loc, |
9316 | ParsedType BaseType, |
9317 | SourceLocation TypeArgsLAngleLoc, |
9318 | ArrayRef<ParsedType> TypeArgs, |
9319 | SourceLocation TypeArgsRAngleLoc, |
9320 | SourceLocation ProtocolLAngleLoc, |
9321 | ArrayRef<Decl *> Protocols, |
9322 | ArrayRef<SourceLocation> ProtocolLocs, |
9323 | SourceLocation ProtocolRAngleLoc); |
9324 | |
9325 | /// Build an Objective-C type parameter type. |
9326 | QualType BuildObjCTypeParamType(const ObjCTypeParamDecl *Decl, |
9327 | SourceLocation ProtocolLAngleLoc, |
9328 | ArrayRef<ObjCProtocolDecl *> Protocols, |
9329 | ArrayRef<SourceLocation> ProtocolLocs, |
9330 | SourceLocation ProtocolRAngleLoc, |
9331 | bool FailOnError = false); |
9332 | |
9333 | /// Build an Objective-C object pointer type. |
9334 | QualType BuildObjCObjectType(QualType BaseType, |
9335 | SourceLocation Loc, |
9336 | SourceLocation TypeArgsLAngleLoc, |
9337 | ArrayRef<TypeSourceInfo *> TypeArgs, |
9338 | SourceLocation TypeArgsRAngleLoc, |
9339 | SourceLocation ProtocolLAngleLoc, |
9340 | ArrayRef<ObjCProtocolDecl *> Protocols, |
9341 | ArrayRef<SourceLocation> ProtocolLocs, |
9342 | SourceLocation ProtocolRAngleLoc, |
9343 | bool FailOnError = false); |
9344 | |
9345 | /// Ensure attributes are consistent with type. |
9346 | /// \param [in, out] Attributes The attributes to check; they will |
9347 | /// be modified to be consistent with \p PropertyTy. |
9348 | void CheckObjCPropertyAttributes(Decl *PropertyPtrTy, |
9349 | SourceLocation Loc, |
9350 | unsigned &Attributes, |
9351 | bool propertyInPrimaryClass); |
9352 | |
9353 | /// Process the specified property declaration and create decls for the |
9354 | /// setters and getters as needed. |
9355 | /// \param property The property declaration being processed |
9356 | void ProcessPropertyDecl(ObjCPropertyDecl *property); |
9357 | |
9358 | |
9359 | void DiagnosePropertyMismatch(ObjCPropertyDecl *Property, |
9360 | ObjCPropertyDecl *SuperProperty, |
9361 | const IdentifierInfo *Name, |
9362 | bool OverridingProtocolProperty); |
9363 | |
9364 | void DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT, |
9365 | ObjCInterfaceDecl *ID); |
9366 | |
9367 | Decl *ActOnAtEnd(Scope *S, SourceRange AtEnd, |
9368 | ArrayRef<Decl *> allMethods = None, |
9369 | ArrayRef<DeclGroupPtrTy> allTUVars = None); |
9370 | |
9371 | Decl *ActOnProperty(Scope *S, SourceLocation AtLoc, |
9372 | SourceLocation LParenLoc, |
9373 | FieldDeclarator &FD, ObjCDeclSpec &ODS, |
9374 | Selector GetterSel, Selector SetterSel, |
9375 | tok::ObjCKeywordKind MethodImplKind, |
9376 | DeclContext *lexicalDC = nullptr); |
9377 | |
9378 | Decl *ActOnPropertyImplDecl(Scope *S, |
9379 | SourceLocation AtLoc, |
9380 | SourceLocation PropertyLoc, |
9381 | bool ImplKind, |
9382 | IdentifierInfo *PropertyId, |
9383 | IdentifierInfo *PropertyIvar, |
9384 | SourceLocation PropertyIvarLoc, |
9385 | ObjCPropertyQueryKind QueryKind); |
9386 | |
9387 | enum ObjCSpecialMethodKind { |
9388 | OSMK_None, |
9389 | OSMK_Alloc, |
9390 | OSMK_New, |
9391 | OSMK_Copy, |
9392 | OSMK_RetainingInit, |
9393 | OSMK_NonRetainingInit |
9394 | }; |
9395 | |
9396 | struct ObjCArgInfo { |
9397 | IdentifierInfo *Name; |
9398 | SourceLocation NameLoc; |
9399 | // The Type is null if no type was specified, and the DeclSpec is invalid |
9400 | // in this case. |
9401 | ParsedType Type; |
9402 | ObjCDeclSpec DeclSpec; |
9403 | |
9404 | /// ArgAttrs - Attribute list for this argument. |
9405 | ParsedAttributesView ArgAttrs; |
9406 | }; |
9407 | |
9408 | Decl *ActOnMethodDeclaration( |
9409 | Scope *S, |
9410 | SourceLocation BeginLoc, // location of the + or -. |
9411 | SourceLocation EndLoc, // location of the ; or {. |
9412 | tok::TokenKind MethodType, ObjCDeclSpec &ReturnQT, ParsedType ReturnType, |
9413 | ArrayRef<SourceLocation> SelectorLocs, Selector Sel, |
9414 | // optional arguments. The number of types/arguments is obtained |
9415 | // from the Sel.getNumArgs(). |
9416 | ObjCArgInfo *ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo, |
9417 | unsigned CNumArgs, // c-style args |
9418 | const ParsedAttributesView &AttrList, tok::ObjCKeywordKind MethodImplKind, |
9419 | bool isVariadic, bool MethodDefinition); |
9420 | |
9421 | ObjCMethodDecl *LookupMethodInQualifiedType(Selector Sel, |
9422 | const ObjCObjectPointerType *OPT, |
9423 | bool IsInstance); |
9424 | ObjCMethodDecl *LookupMethodInObjectType(Selector Sel, QualType Ty, |
9425 | bool IsInstance); |
9426 | |
9427 | bool CheckARCMethodDecl(ObjCMethodDecl *method); |
9428 | bool inferObjCARCLifetime(ValueDecl *decl); |
9429 | |
9430 | void deduceOpenCLAddressSpace(ValueDecl *decl); |
9431 | |
9432 | ExprResult |
9433 | HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, |
9434 | Expr *BaseExpr, |
9435 | SourceLocation OpLoc, |
9436 | DeclarationName MemberName, |
9437 | SourceLocation MemberLoc, |
9438 | SourceLocation SuperLoc, QualType SuperType, |
9439 | bool Super); |
9440 | |
9441 | ExprResult |
9442 | ActOnClassPropertyRefExpr(IdentifierInfo &receiverName, |
9443 | IdentifierInfo &propertyName, |
9444 | SourceLocation receiverNameLoc, |
9445 | SourceLocation propertyNameLoc); |
9446 | |
9447 | ObjCMethodDecl *tryCaptureObjCSelf(SourceLocation Loc); |
9448 | |
9449 | /// Describes the kind of message expression indicated by a message |
9450 | /// send that starts with an identifier. |
9451 | enum ObjCMessageKind { |
9452 | /// The message is sent to 'super'. |
9453 | ObjCSuperMessage, |
9454 | /// The message is an instance message. |
9455 | ObjCInstanceMessage, |
9456 | /// The message is a class message, and the identifier is a type |
9457 | /// name. |
9458 | ObjCClassMessage |
9459 | }; |
9460 | |
9461 | ObjCMessageKind getObjCMessageKind(Scope *S, |
9462 | IdentifierInfo *Name, |
9463 | SourceLocation NameLoc, |
9464 | bool IsSuper, |
9465 | bool HasTrailingDot, |
9466 | ParsedType &ReceiverType); |
9467 | |
9468 | ExprResult ActOnSuperMessage(Scope *S, SourceLocation SuperLoc, |
9469 | Selector Sel, |
9470 | SourceLocation LBracLoc, |
9471 | ArrayRef<SourceLocation> SelectorLocs, |
9472 | SourceLocation RBracLoc, |
9473 | MultiExprArg Args); |
9474 | |
9475 | ExprResult BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, |
9476 | QualType ReceiverType, |
9477 | SourceLocation SuperLoc, |
9478 | Selector Sel, |
9479 | ObjCMethodDecl *Method, |
9480 | SourceLocation LBracLoc, |
9481 | ArrayRef<SourceLocation> SelectorLocs, |
9482 | SourceLocation RBracLoc, |
9483 | MultiExprArg Args, |
9484 | bool isImplicit = false); |
9485 | |
9486 | ExprResult BuildClassMessageImplicit(QualType ReceiverType, |
9487 | bool isSuperReceiver, |
9488 | SourceLocation Loc, |
9489 | Selector Sel, |
9490 | ObjCMethodDecl *Method, |
9491 | MultiExprArg Args); |
9492 | |
9493 | ExprResult ActOnClassMessage(Scope *S, |
9494 | ParsedType Receiver, |
9495 | Selector Sel, |
9496 | SourceLocation LBracLoc, |
9497 | ArrayRef<SourceLocation> SelectorLocs, |
9498 | SourceLocation RBracLoc, |
9499 | MultiExprArg Args); |
9500 | |
9501 | ExprResult BuildInstanceMessage(Expr *Receiver, |
9502 | QualType ReceiverType, |
9503 | SourceLocation SuperLoc, |
9504 | Selector Sel, |
9505 | ObjCMethodDecl *Method, |
9506 | SourceLocation LBracLoc, |
9507 | ArrayRef<SourceLocation> SelectorLocs, |
9508 | SourceLocation RBracLoc, |
9509 | MultiExprArg Args, |
9510 | bool isImplicit = false); |
9511 | |
9512 | ExprResult BuildInstanceMessageImplicit(Expr *Receiver, |
9513 | QualType ReceiverType, |
9514 | SourceLocation Loc, |
9515 | Selector Sel, |
9516 | ObjCMethodDecl *Method, |
9517 | MultiExprArg Args); |
9518 | |
9519 | ExprResult ActOnInstanceMessage(Scope *S, |
9520 | Expr *Receiver, |
9521 | Selector Sel, |
9522 | SourceLocation LBracLoc, |
9523 | ArrayRef<SourceLocation> SelectorLocs, |
9524 | SourceLocation RBracLoc, |
9525 | MultiExprArg Args); |
9526 | |
9527 | ExprResult BuildObjCBridgedCast(SourceLocation LParenLoc, |
9528 | ObjCBridgeCastKind Kind, |
9529 | SourceLocation BridgeKeywordLoc, |
9530 | TypeSourceInfo *TSInfo, |
9531 | Expr *SubExpr); |
9532 | |
9533 | ExprResult ActOnObjCBridgedCast(Scope *S, |
9534 | SourceLocation LParenLoc, |
9535 | ObjCBridgeCastKind Kind, |
9536 | SourceLocation BridgeKeywordLoc, |
9537 | ParsedType Type, |
9538 | SourceLocation RParenLoc, |
9539 | Expr *SubExpr); |
9540 | |
9541 | void CheckTollFreeBridgeCast(QualType castType, Expr *castExpr); |
9542 | |
9543 | void CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr); |
9544 | |
9545 | bool CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr, |
9546 | CastKind &Kind); |
9547 | |
9548 | bool checkObjCBridgeRelatedComponents(SourceLocation Loc, |
9549 | QualType DestType, QualType SrcType, |
9550 | ObjCInterfaceDecl *&RelatedClass, |
9551 | ObjCMethodDecl *&ClassMethod, |
9552 | ObjCMethodDecl *&InstanceMethod, |
9553 | TypedefNameDecl *&TDNDecl, |
9554 | bool CfToNs, bool Diagnose = true); |
9555 | |
9556 | bool CheckObjCBridgeRelatedConversions(SourceLocation Loc, |
9557 | QualType DestType, QualType SrcType, |
9558 | Expr *&SrcExpr, bool Diagnose = true); |
9559 | |
9560 | bool CheckConversionToObjCLiteral(QualType DstType, Expr *&SrcExpr, |
9561 | bool Diagnose = true); |
9562 | |
9563 | bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall); |
9564 | |
9565 | /// Check whether the given new method is a valid override of the |
9566 | /// given overridden method, and set any properties that should be inherited. |
9567 | void CheckObjCMethodOverride(ObjCMethodDecl *NewMethod, |
9568 | const ObjCMethodDecl *Overridden); |
9569 | |
9570 | /// Describes the compatibility of a result type with its method. |
9571 | enum ResultTypeCompatibilityKind { |
9572 | RTC_Compatible, |
9573 | RTC_Incompatible, |
9574 | RTC_Unknown |
9575 | }; |
9576 | |
9577 | void CheckObjCMethodDirectOverrides(ObjCMethodDecl *method, |
9578 | ObjCMethodDecl *overridden); |
9579 | |
9580 | void CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod, |
9581 | ObjCInterfaceDecl *CurrentClass, |
9582 | ResultTypeCompatibilityKind RTC); |
9583 | |
9584 | enum PragmaOptionsAlignKind { |
9585 | POAK_Native, // #pragma options align=native |
9586 | POAK_Natural, // #pragma options align=natural |
9587 | POAK_Packed, // #pragma options align=packed |
9588 | POAK_Power, // #pragma options align=power |
9589 | POAK_Mac68k, // #pragma options align=mac68k |
9590 | POAK_Reset // #pragma options align=reset |
9591 | }; |
9592 | |
9593 | /// ActOnPragmaClangSection - Called on well formed \#pragma clang section |
9594 | void ActOnPragmaClangSection(SourceLocation PragmaLoc, |
9595 | PragmaClangSectionAction Action, |
9596 | PragmaClangSectionKind SecKind, StringRef SecName); |
9597 | |
9598 | /// ActOnPragmaOptionsAlign - Called on well formed \#pragma options align. |
9599 | void ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind, |
9600 | SourceLocation PragmaLoc); |
9601 | |
9602 | /// ActOnPragmaPack - Called on well formed \#pragma pack(...). |
9603 | void ActOnPragmaPack(SourceLocation PragmaLoc, PragmaMsStackAction Action, |
9604 | StringRef SlotLabel, Expr *Alignment); |
9605 | |
9606 | enum class PragmaPackDiagnoseKind { |
9607 | NonDefaultStateAtInclude, |
9608 | ChangedStateAtExit |
9609 | }; |
9610 | |
9611 | void DiagnoseNonDefaultPragmaPack(PragmaPackDiagnoseKind Kind, |
9612 | SourceLocation IncludeLoc); |
9613 | void DiagnoseUnterminatedPragmaPack(); |
9614 | |
9615 | /// ActOnPragmaMSStruct - Called on well formed \#pragma ms_struct [on|off]. |
9616 | void ActOnPragmaMSStruct(PragmaMSStructKind Kind); |
9617 | |
9618 | /// ActOnPragmaMSComment - Called on well formed |
9619 | /// \#pragma comment(kind, "arg"). |
9620 | void ActOnPragmaMSComment(SourceLocation CommentLoc, PragmaMSCommentKind Kind, |
9621 | StringRef Arg); |
9622 | |
9623 | /// ActOnPragmaMSPointersToMembers - called on well formed \#pragma |
9624 | /// pointers_to_members(representation method[, general purpose |
9625 | /// representation]). |
9626 | void ActOnPragmaMSPointersToMembers( |
9627 | LangOptions::PragmaMSPointersToMembersKind Kind, |
9628 | SourceLocation PragmaLoc); |
9629 | |
9630 | /// Called on well formed \#pragma vtordisp(). |
9631 | void ActOnPragmaMSVtorDisp(PragmaMsStackAction Action, |
9632 | SourceLocation PragmaLoc, |
9633 | MSVtorDispMode Value); |
9634 | |
9635 | enum PragmaSectionKind { |
9636 | PSK_DataSeg, |
9637 | PSK_BSSSeg, |
9638 | PSK_ConstSeg, |
9639 | PSK_CodeSeg, |
9640 | }; |
9641 | |
9642 | bool UnifySection(StringRef SectionName, |
9643 | int SectionFlags, |
9644 | DeclaratorDecl *TheDecl); |
9645 | bool UnifySection(StringRef SectionName, |
9646 | int SectionFlags, |
9647 | SourceLocation PragmaSectionLocation); |
9648 | |
9649 | /// Called on well formed \#pragma bss_seg/data_seg/const_seg/code_seg. |
9650 | void ActOnPragmaMSSeg(SourceLocation PragmaLocation, |
9651 | PragmaMsStackAction Action, |
9652 | llvm::StringRef StackSlotLabel, |
9653 | StringLiteral *SegmentName, |
9654 | llvm::StringRef PragmaName); |
9655 | |
9656 | /// Called on well formed \#pragma section(). |
9657 | void ActOnPragmaMSSection(SourceLocation PragmaLocation, |
9658 | int SectionFlags, StringLiteral *SegmentName); |
9659 | |
9660 | /// Called on well-formed \#pragma init_seg(). |
9661 | void ActOnPragmaMSInitSeg(SourceLocation PragmaLocation, |
9662 | StringLiteral *SegmentName); |
9663 | |
9664 | /// Called on #pragma clang __debug dump II |
9665 | void ActOnPragmaDump(Scope *S, SourceLocation Loc, IdentifierInfo *II); |
9666 | |
9667 | /// ActOnPragmaDetectMismatch - Call on well-formed \#pragma detect_mismatch |
9668 | void ActOnPragmaDetectMismatch(SourceLocation Loc, StringRef Name, |
9669 | StringRef Value); |
9670 | |
9671 | /// Are precise floating point semantics currently enabled? |
9672 | bool isPreciseFPEnabled() { |
9673 | return !CurFPFeatures.getAllowFPReassociate() && |
9674 | !CurFPFeatures.getNoSignedZero() && |
9675 | !CurFPFeatures.getAllowReciprocal() && |
9676 | !CurFPFeatures.getAllowApproxFunc(); |
9677 | } |
9678 | |
9679 | /// ActOnPragmaFloatControl - Call on well-formed \#pragma float_control |
9680 | void ActOnPragmaFloatControl(SourceLocation Loc, PragmaMsStackAction Action, |
9681 | PragmaFloatControlKind Value); |
9682 | |
9683 | /// ActOnPragmaUnused - Called on well-formed '\#pragma unused'. |
9684 | void ActOnPragmaUnused(const Token &Identifier, |
9685 | Scope *curScope, |
9686 | SourceLocation PragmaLoc); |
9687 | |
9688 | /// ActOnPragmaVisibility - Called on well formed \#pragma GCC visibility... . |
9689 | void ActOnPragmaVisibility(const IdentifierInfo* VisType, |
9690 | SourceLocation PragmaLoc); |
9691 | |
9692 | NamedDecl *DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II, |
9693 | SourceLocation Loc); |
9694 | void DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W); |
9695 | |
9696 | /// ActOnPragmaWeakID - Called on well formed \#pragma weak ident. |
9697 | void ActOnPragmaWeakID(IdentifierInfo* WeakName, |
9698 | SourceLocation PragmaLoc, |
9699 | SourceLocation WeakNameLoc); |
9700 | |
9701 | /// ActOnPragmaRedefineExtname - Called on well formed |
9702 | /// \#pragma redefine_extname oldname newname. |
9703 | void ActOnPragmaRedefineExtname(IdentifierInfo* WeakName, |
9704 | IdentifierInfo* AliasName, |
9705 | SourceLocation PragmaLoc, |
9706 | SourceLocation WeakNameLoc, |
9707 | SourceLocation AliasNameLoc); |
9708 | |
9709 | /// ActOnPragmaWeakAlias - Called on well formed \#pragma weak ident = ident. |
9710 | void ActOnPragmaWeakAlias(IdentifierInfo* WeakName, |
9711 | IdentifierInfo* AliasName, |
9712 | SourceLocation PragmaLoc, |
9713 | SourceLocation WeakNameLoc, |
9714 | SourceLocation AliasNameLoc); |
9715 | |
9716 | /// ActOnPragmaFPContract - Called on well formed |
9717 | /// \#pragma {STDC,OPENCL} FP_CONTRACT and |
9718 | /// \#pragma clang fp contract |
9719 | void ActOnPragmaFPContract(SourceLocation Loc, LangOptions::FPModeKind FPC); |
9720 | |
9721 | /// Called on well formed |
9722 | /// \#pragma clang fp reassociate |
9723 | void ActOnPragmaFPReassociate(SourceLocation Loc, bool IsEnabled); |
9724 | |
9725 | /// ActOnPragmaFenvAccess - Called on well formed |
9726 | /// \#pragma STDC FENV_ACCESS |
9727 | void ActOnPragmaFEnvAccess(SourceLocation Loc, bool IsEnabled); |
9728 | |
9729 | /// Called to set rounding mode for floating point operations. |
9730 | void setRoundingMode(SourceLocation Loc, llvm::RoundingMode); |
9731 | |
9732 | /// Called to set exception behavior for floating point operations. |
9733 | void setExceptionMode(SourceLocation Loc, LangOptions::FPExceptionModeKind); |
9734 | |
9735 | /// AddAlignmentAttributesForRecord - Adds any needed alignment attributes to |
9736 | /// a the record decl, to handle '\#pragma pack' and '\#pragma options align'. |
9737 | void AddAlignmentAttributesForRecord(RecordDecl *RD); |
9738 | |
9739 | /// AddMsStructLayoutForRecord - Adds ms_struct layout attribute to record. |
9740 | void AddMsStructLayoutForRecord(RecordDecl *RD); |
9741 | |
9742 | /// FreePackedContext - Deallocate and null out PackContext. |
9743 | void FreePackedContext(); |
9744 | |
9745 | /// PushNamespaceVisibilityAttr - Note that we've entered a |
9746 | /// namespace with a visibility attribute. |
9747 | void PushNamespaceVisibilityAttr(const VisibilityAttr *Attr, |
9748 | SourceLocation Loc); |
9749 | |
9750 | /// AddPushedVisibilityAttribute - If '\#pragma GCC visibility' was used, |
9751 | /// add an appropriate visibility attribute. |
9752 | void AddPushedVisibilityAttribute(Decl *RD); |
9753 | |
9754 | /// PopPragmaVisibility - Pop the top element of the visibility stack; used |
9755 | /// for '\#pragma GCC visibility' and visibility attributes on namespaces. |
9756 | void PopPragmaVisibility(bool IsNamespaceEnd, SourceLocation EndLoc); |
9757 | |
9758 | /// FreeVisContext - Deallocate and null out VisContext. |
9759 | void FreeVisContext(); |
9760 | |
9761 | /// AddCFAuditedAttribute - Check whether we're currently within |
9762 | /// '\#pragma clang arc_cf_code_audited' and, if so, consider adding |
9763 | /// the appropriate attribute. |
9764 | void AddCFAuditedAttribute(Decl *D); |
9765 | |
9766 | void ActOnPragmaAttributeAttribute(ParsedAttr &Attribute, |
9767 | SourceLocation PragmaLoc, |
9768 | attr::ParsedSubjectMatchRuleSet Rules); |
9769 | void ActOnPragmaAttributeEmptyPush(SourceLocation PragmaLoc, |
9770 | const IdentifierInfo *Namespace); |
9771 | |
9772 | /// Called on well-formed '\#pragma clang attribute pop'. |
9773 | void ActOnPragmaAttributePop(SourceLocation PragmaLoc, |
9774 | const IdentifierInfo *Namespace); |
9775 | |
9776 | /// Adds the attributes that have been specified using the |
9777 | /// '\#pragma clang attribute push' directives to the given declaration. |
9778 | void AddPragmaAttributes(Scope *S, Decl *D); |
9779 | |
9780 | void DiagnoseUnterminatedPragmaAttribute(); |
9781 | |
9782 | /// Called on well formed \#pragma clang optimize. |
9783 | void ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc); |
9784 | |
9785 | /// Get the location for the currently active "\#pragma clang optimize |
9786 | /// off". If this location is invalid, then the state of the pragma is "on". |
9787 | SourceLocation getOptimizeOffPragmaLocation() const { |
9788 | return OptimizeOffPragmaLocation; |
9789 | } |
9790 | |
9791 | /// Only called on function definitions; if there is a pragma in scope |
9792 | /// with the effect of a range-based optnone, consider marking the function |
9793 | /// with attribute optnone. |
9794 | void AddRangeBasedOptnone(FunctionDecl *FD); |
9795 | |
9796 | /// Adds the 'optnone' attribute to the function declaration if there |
9797 | /// are no conflicts; Loc represents the location causing the 'optnone' |
9798 | /// attribute to be added (usually because of a pragma). |
9799 | void AddOptnoneAttributeIfNoConflicts(FunctionDecl *FD, SourceLocation Loc); |
9800 | |
9801 | /// AddAlignedAttr - Adds an aligned attribute to a particular declaration. |
9802 | void AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E, |
9803 | bool IsPackExpansion); |
9804 | void AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, TypeSourceInfo *T, |
9805 | bool IsPackExpansion); |
9806 | |
9807 | /// AddAssumeAlignedAttr - Adds an assume_aligned attribute to a particular |
9808 | /// declaration. |
9809 | void AddAssumeAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E, |
9810 | Expr *OE); |
9811 | |
9812 | /// AddAllocAlignAttr - Adds an alloc_align attribute to a particular |
9813 | /// declaration. |
9814 | void AddAllocAlignAttr(Decl *D, const AttributeCommonInfo &CI, |
9815 | Expr *ParamExpr); |
9816 | |
9817 | /// AddAlignValueAttr - Adds an align_value attribute to a particular |
9818 | /// declaration. |
9819 | void AddAlignValueAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E); |
9820 | |
9821 | /// AddLaunchBoundsAttr - Adds a launch_bounds attribute to a particular |
9822 | /// declaration. |
9823 | void AddLaunchBoundsAttr(Decl *D, const AttributeCommonInfo &CI, |
9824 | Expr *MaxThreads, Expr *MinBlocks); |
9825 | |
9826 | /// AddModeAttr - Adds a mode attribute to a particular declaration. |
9827 | void AddModeAttr(Decl *D, const AttributeCommonInfo &CI, IdentifierInfo *Name, |
9828 | bool InInstantiation = false); |
9829 | |
9830 | void AddParameterABIAttr(Decl *D, const AttributeCommonInfo &CI, |
9831 | ParameterABI ABI); |
9832 | |
9833 | enum class RetainOwnershipKind {NS, CF, OS}; |
9834 | void AddXConsumedAttr(Decl *D, const AttributeCommonInfo &CI, |
9835 | RetainOwnershipKind K, bool IsTemplateInstantiation); |
9836 | |
9837 | /// addAMDGPUFlatWorkGroupSizeAttr - Adds an amdgpu_flat_work_group_size |
9838 | /// attribute to a particular declaration. |
9839 | void addAMDGPUFlatWorkGroupSizeAttr(Decl *D, const AttributeCommonInfo &CI, |
9840 | Expr *Min, Expr *Max); |
9841 | |
9842 | /// addAMDGPUWavePersEUAttr - Adds an amdgpu_waves_per_eu attribute to a |
9843 | /// particular declaration. |
9844 | void addAMDGPUWavesPerEUAttr(Decl *D, const AttributeCommonInfo &CI, |
9845 | Expr *Min, Expr *Max); |
9846 | |
9847 | bool checkNSReturnsRetainedReturnType(SourceLocation loc, QualType type); |
9848 | |
9849 | //===--------------------------------------------------------------------===// |
9850 | // C++ Coroutines TS |
9851 | // |
9852 | bool ActOnCoroutineBodyStart(Scope *S, SourceLocation KwLoc, |
9853 | StringRef Keyword); |
9854 | ExprResult ActOnCoawaitExpr(Scope *S, SourceLocation KwLoc, Expr *E); |
9855 | ExprResult ActOnCoyieldExpr(Scope *S, SourceLocation KwLoc, Expr *E); |
9856 | StmtResult ActOnCoreturnStmt(Scope *S, SourceLocation KwLoc, Expr *E); |
9857 | |
9858 | ExprResult BuildResolvedCoawaitExpr(SourceLocation KwLoc, Expr *E, |
9859 | bool IsImplicit = false); |
9860 | ExprResult BuildUnresolvedCoawaitExpr(SourceLocation KwLoc, Expr *E, |
9861 | UnresolvedLookupExpr* Lookup); |
9862 | ExprResult BuildCoyieldExpr(SourceLocation KwLoc, Expr *E); |
9863 | StmtResult BuildCoreturnStmt(SourceLocation KwLoc, Expr *E, |
9864 | bool IsImplicit = false); |
9865 | StmtResult BuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs); |
9866 | bool buildCoroutineParameterMoves(SourceLocation Loc); |
9867 | VarDecl *buildCoroutinePromise(SourceLocation Loc); |
9868 | void CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body); |
9869 | ClassTemplateDecl *lookupCoroutineTraits(SourceLocation KwLoc, |
9870 | SourceLocation FuncLoc); |
9871 | /// Check that the expression co_await promise.final_suspend() shall not be |
9872 | /// potentially-throwing. |
9873 | bool checkFinalSuspendNoThrow(const Stmt *FinalSuspend); |
9874 | |
9875 | //===--------------------------------------------------------------------===// |
9876 | // OpenCL extensions. |
9877 | // |
9878 | private: |
9879 | std::string CurrOpenCLExtension; |
9880 | /// Extensions required by an OpenCL type. |
9881 | llvm::DenseMap<const Type*, std::set<std::string>> OpenCLTypeExtMap; |
9882 | /// Extensions required by an OpenCL declaration. |
9883 | llvm::DenseMap<const Decl*, std::set<std::string>> OpenCLDeclExtMap; |
9884 | public: |
9885 | llvm::StringRef getCurrentOpenCLExtension() const { |
9886 | return CurrOpenCLExtension; |
9887 | } |
9888 | |
9889 | /// Check if a function declaration \p FD associates with any |
9890 | /// extensions present in OpenCLDeclExtMap and if so return the |
9891 | /// extension(s) name(s). |
9892 | std::string getOpenCLExtensionsFromDeclExtMap(FunctionDecl *FD); |
9893 | |
9894 | /// Check if a function type \p FT associates with any |
9895 | /// extensions present in OpenCLTypeExtMap and if so return the |
9896 | /// extension(s) name(s). |
9897 | std::string getOpenCLExtensionsFromTypeExtMap(FunctionType *FT); |
9898 | |
9899 | /// Find an extension in an appropriate extension map and return its name |
9900 | template<typename T, typename MapT> |
9901 | std::string getOpenCLExtensionsFromExtMap(T* FT, MapT &Map); |
9902 | |
9903 | void setCurrentOpenCLExtension(llvm::StringRef Ext) { |
9904 | CurrOpenCLExtension = std::string(Ext); |
9905 | } |
9906 | |
9907 | /// Set OpenCL extensions for a type which can only be used when these |
9908 | /// OpenCL extensions are enabled. If \p Exts is empty, do nothing. |
9909 | /// \param Exts A space separated list of OpenCL extensions. |
9910 | void setOpenCLExtensionForType(QualType T, llvm::StringRef Exts); |
9911 | |
9912 | /// Set OpenCL extensions for a declaration which can only be |
9913 | /// used when these OpenCL extensions are enabled. If \p Exts is empty, do |
9914 | /// nothing. |
9915 | /// \param Exts A space separated list of OpenCL extensions. |
9916 | void setOpenCLExtensionForDecl(Decl *FD, llvm::StringRef Exts); |
9917 | |
9918 | /// Set current OpenCL extensions for a type which can only be used |
9919 | /// when these OpenCL extensions are enabled. If current OpenCL extension is |
9920 | /// empty, do nothing. |
9921 | void setCurrentOpenCLExtensionForType(QualType T); |
9922 | |
9923 | /// Set current OpenCL extensions for a declaration which |
9924 | /// can only be used when these OpenCL extensions are enabled. If current |
9925 | /// OpenCL extension is empty, do nothing. |
9926 | void setCurrentOpenCLExtensionForDecl(Decl *FD); |
9927 | |
9928 | bool isOpenCLDisabledDecl(Decl *FD); |
9929 | |
9930 | /// Check if type \p T corresponding to declaration specifier \p DS |
9931 | /// is disabled due to required OpenCL extensions being disabled. If so, |
9932 | /// emit diagnostics. |
9933 | /// \return true if type is disabled. |
9934 | bool checkOpenCLDisabledTypeDeclSpec(const DeclSpec &DS, QualType T); |
9935 | |
9936 | /// Check if declaration \p D used by expression \p E |
9937 | /// is disabled due to required OpenCL extensions being disabled. If so, |
9938 | /// emit diagnostics. |
9939 | /// \return true if type is disabled. |
9940 | bool checkOpenCLDisabledDecl(const NamedDecl &D, const Expr &E); |
9941 | |
9942 | //===--------------------------------------------------------------------===// |
9943 | // OpenMP directives and clauses. |
9944 | // |
9945 | private: |
9946 | void *VarDataSharingAttributesStack; |
9947 | /// Number of nested '#pragma omp declare target' directives. |
9948 | unsigned DeclareTargetNestingLevel = 0; |
9949 | /// Initialization of data-sharing attributes stack. |
9950 | void InitDataSharingAttributesStack(); |
9951 | void DestroyDataSharingAttributesStack(); |
9952 | ExprResult |
9953 | VerifyPositiveIntegerConstantInClause(Expr *Op, OpenMPClauseKind CKind, |
9954 | bool StrictlyPositive = true); |
9955 | /// Returns OpenMP nesting level for current directive. |
9956 | unsigned getOpenMPNestingLevel() const; |
9957 | |
9958 | /// Adjusts the function scopes index for the target-based regions. |
9959 | void adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, |
9960 | unsigned Level) const; |
9961 | |
9962 | /// Returns the number of scopes associated with the construct on the given |
9963 | /// OpenMP level. |
9964 | int getNumberOfConstructScopes(unsigned Level) const; |
9965 | |
9966 | /// Push new OpenMP function region for non-capturing function. |
9967 | void pushOpenMPFunctionRegion(); |
9968 | |
9969 | /// Pop OpenMP function region for non-capturing function. |
9970 | void popOpenMPFunctionRegion(const sema::FunctionScopeInfo *OldFSI); |
9971 | |
9972 | /// Checks if a type or a declaration is disabled due to the owning extension |
9973 | /// being disabled, and emits diagnostic messages if it is disabled. |
9974 | /// \param D type or declaration to be checked. |
9975 | /// \param DiagLoc source location for the diagnostic message. |
9976 | /// \param DiagInfo information to be emitted for the diagnostic message. |
9977 | /// \param SrcRange source range of the declaration. |
9978 | /// \param Map maps type or declaration to the extensions. |
9979 | /// \param Selector selects diagnostic message: 0 for type and 1 for |
9980 | /// declaration. |
9981 | /// \return true if the type or declaration is disabled. |
9982 | template <typename T, typename DiagLocT, typename DiagInfoT, typename MapT> |
9983 | bool checkOpenCLDisabledTypeOrDecl(T D, DiagLocT DiagLoc, DiagInfoT DiagInfo, |
9984 | MapT &Map, unsigned Selector = 0, |
9985 | SourceRange SrcRange = SourceRange()); |
9986 | |
9987 | /// Helper to keep information about the current `omp begin/end declare |
9988 | /// variant` nesting. |
9989 | struct OMPDeclareVariantScope { |
9990 | /// The associated OpenMP context selector. |
9991 | OMPTraitInfo *TI; |
9992 | |
9993 | /// The associated OpenMP context selector mangling. |
9994 | std::string NameSuffix; |
9995 | |
9996 | OMPDeclareVariantScope(OMPTraitInfo &TI); |
9997 | }; |
9998 | |
9999 | /// The current `omp begin/end declare variant` scopes. |
10000 | SmallVector<OMPDeclareVariantScope, 4> OMPDeclareVariantScopes; |
10001 | |
10002 | /// The declarator \p D defines a function in the scope \p S which is nested |
10003 | /// in an `omp begin/end declare variant` scope. In this method we create a |
10004 | /// declaration for \p D and rename \p D according to the OpenMP context |
10005 | /// selector of the surrounding scope. |
10006 | FunctionDecl * |
10007 | ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S, |
10008 | Declarator &D); |
10009 | |
10010 | /// Register \p FD as specialization of \p BaseFD in the current `omp |
10011 | /// begin/end declare variant` scope. |
10012 | void ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( |
10013 | FunctionDecl *FD, FunctionDecl *BaseFD); |
10014 | |
10015 | public: |
10016 | |
10017 | /// Can we exit a scope at the moment. |
10018 | bool isInOpenMPDeclareVariantScope() { |
10019 | return !OMPDeclareVariantScopes.empty(); |
10020 | } |
10021 | |
10022 | /// Given the potential call expression \p Call, determine if there is a |
10023 | /// specialization via the OpenMP declare variant mechanism available. If |
10024 | /// there is, return the specialized call expression, otherwise return the |
10025 | /// original \p Call. |
10026 | ExprResult ActOnOpenMPCall(ExprResult Call, Scope *Scope, |
10027 | SourceLocation LParenLoc, MultiExprArg ArgExprs, |
10028 | SourceLocation RParenLoc, Expr *ExecConfig); |
10029 | |
10030 | /// Handle a `omp begin declare variant`. |
10031 | void ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, OMPTraitInfo &TI); |
10032 | |
10033 | /// Handle a `omp end declare variant`. |
10034 | void ActOnOpenMPEndDeclareVariant(); |
10035 | |
10036 | /// Checks if the variant/multiversion functions are compatible. |
10037 | bool areMultiversionVariantFunctionsCompatible( |
10038 | const FunctionDecl *OldFD, const FunctionDecl *NewFD, |
10039 | const PartialDiagnostic &NoProtoDiagID, |
10040 | const PartialDiagnosticAt &NoteCausedDiagIDAt, |
10041 | const PartialDiagnosticAt &NoSupportDiagIDAt, |
10042 | const PartialDiagnosticAt &DiffDiagIDAt, bool TemplatesSupported, |
10043 | bool ConstexprSupported, bool CLinkageMayDiffer); |
10044 | |
10045 | /// Function tries to capture lambda's captured variables in the OpenMP region |
10046 | /// before the original lambda is captured. |
10047 | void tryCaptureOpenMPLambdas(ValueDecl *V); |
10048 | |
10049 | /// Return true if the provided declaration \a VD should be captured by |
10050 | /// reference. |
10051 | /// \param Level Relative level of nested OpenMP construct for that the check |
10052 | /// is performed. |
10053 | /// \param OpenMPCaptureLevel Capture level within an OpenMP construct. |
10054 | bool isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, |
10055 | unsigned OpenMPCaptureLevel) const; |
10056 | |
10057 | /// Check if the specified variable is used in one of the private |
10058 | /// clauses (private, firstprivate, lastprivate, reduction etc.) in OpenMP |
10059 | /// constructs. |
10060 | VarDecl *isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo = false, |
10061 | unsigned StopAt = 0); |
10062 | ExprResult getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, |
10063 | ExprObjectKind OK, SourceLocation Loc); |
10064 | |
10065 | /// If the current region is a loop-based region, mark the start of the loop |
10066 | /// construct. |
10067 | void startOpenMPLoop(); |
10068 | |
10069 | /// If the current region is a range loop-based region, mark the start of the |
10070 | /// loop construct. |
10071 | void startOpenMPCXXRangeFor(); |
10072 | |
10073 | /// Check if the specified variable is used in 'private' clause. |
10074 | /// \param Level Relative level of nested OpenMP construct for that the check |
10075 | /// is performed. |
10076 | OpenMPClauseKind isOpenMPPrivateDecl(ValueDecl *D, unsigned Level, |
10077 | unsigned CapLevel) const; |
10078 | |
10079 | /// Sets OpenMP capture kind (OMPC_private, OMPC_firstprivate, OMPC_map etc.) |
10080 | /// for \p FD based on DSA for the provided corresponding captured declaration |
10081 | /// \p D. |
10082 | void setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, unsigned Level); |
10083 | |
10084 | /// Check if the specified variable is captured by 'target' directive. |
10085 | /// \param Level Relative level of nested OpenMP construct for that the check |
10086 | /// is performed. |
10087 | bool isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, |
10088 | unsigned CaptureLevel) const; |
10089 | |
10090 | /// Check if the specified global variable must be captured by outer capture |
10091 | /// regions. |
10092 | /// \param Level Relative level of nested OpenMP construct for that |
10093 | /// the check is performed. |
10094 | bool isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, |
10095 | unsigned CaptureLevel) const; |
10096 | |
10097 | ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc, |
10098 | Expr *Op); |
10099 | /// Called on start of new data sharing attribute block. |
10100 | void StartOpenMPDSABlock(OpenMPDirectiveKind K, |
10101 | const DeclarationNameInfo &DirName, Scope *CurScope, |
10102 | SourceLocation Loc); |
10103 | /// Start analysis of clauses. |
10104 | void StartOpenMPClause(OpenMPClauseKind K); |
10105 | /// End analysis of clauses. |
10106 | void EndOpenMPClause(); |
10107 | /// Called on end of data sharing attribute block. |
10108 | void EndOpenMPDSABlock(Stmt *CurDirective); |
10109 | |
10110 | /// Check if the current region is an OpenMP loop region and if it is, |
10111 | /// mark loop control variable, used in \p Init for loop initialization, as |
10112 | /// private by default. |
10113 | /// \param Init First part of the for loop. |
10114 | void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init); |
10115 | |
10116 | // OpenMP directives and clauses. |
10117 | /// Called on correct id-expression from the '#pragma omp |
10118 | /// threadprivate'. |
10119 | ExprResult ActOnOpenMPIdExpression(Scope *CurScope, CXXScopeSpec &ScopeSpec, |
10120 | const DeclarationNameInfo &Id, |
10121 | OpenMPDirectiveKind Kind); |
10122 | /// Called on well-formed '#pragma omp threadprivate'. |
10123 | DeclGroupPtrTy ActOnOpenMPThreadprivateDirective( |
10124 | SourceLocation Loc, |
10125 | ArrayRef<Expr *> VarList); |
10126 | /// Builds a new OpenMPThreadPrivateDecl and checks its correctness. |
10127 | OMPThreadPrivateDecl *CheckOMPThreadPrivateDecl(SourceLocation Loc, |
10128 | ArrayRef<Expr *> VarList); |
10129 | /// Called on well-formed '#pragma omp allocate'. |
10130 | DeclGroupPtrTy ActOnOpenMPAllocateDirective(SourceLocation Loc, |
10131 | ArrayRef<Expr *> VarList, |
10132 | ArrayRef<OMPClause *> Clauses, |
10133 | DeclContext *Owner = nullptr); |
10134 | /// Called on well-formed '#pragma omp requires'. |
10135 | DeclGroupPtrTy ActOnOpenMPRequiresDirective(SourceLocation Loc, |
10136 | ArrayRef<OMPClause *> ClauseList); |
10137 | /// Check restrictions on Requires directive |
10138 | OMPRequiresDecl *CheckOMPRequiresDecl(SourceLocation Loc, |
10139 | ArrayRef<OMPClause *> Clauses); |
10140 | /// Check if the specified type is allowed to be used in 'omp declare |
10141 | /// reduction' construct. |
10142 | QualType ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, |
10143 | TypeResult ParsedType); |
10144 | /// Called on start of '#pragma omp declare reduction'. |
10145 | DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveStart( |
10146 | Scope *S, DeclContext *DC, DeclarationName Name, |
10147 | ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, |
10148 | AccessSpecifier AS, Decl *PrevDeclInScope = nullptr); |
10149 | /// Initialize declare reduction construct initializer. |
10150 | void ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D); |
10151 | /// Finish current declare reduction construct initializer. |
10152 | void ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner); |
10153 | /// Initialize declare reduction construct initializer. |
10154 | /// \return omp_priv variable. |
10155 | VarDecl *ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D); |
10156 | /// Finish current declare reduction construct initializer. |
10157 | void ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, |
10158 | VarDecl *OmpPrivParm); |
10159 | /// Called at the end of '#pragma omp declare reduction'. |
10160 | DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd( |
10161 | Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid); |
10162 | |
10163 | /// Check variable declaration in 'omp declare mapper' construct. |
10164 | TypeResult ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D); |
10165 | /// Check if the specified type is allowed to be used in 'omp declare |
10166 | /// mapper' construct. |
10167 | QualType ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, |
10168 | TypeResult ParsedType); |
10169 | /// Called on start of '#pragma omp declare mapper'. |
10170 | OMPDeclareMapperDecl *ActOnOpenMPDeclareMapperDirectiveStart( |
10171 | Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, |
10172 | SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, |
10173 | Decl *PrevDeclInScope = nullptr); |
10174 | /// Build the mapper variable of '#pragma omp declare mapper'. |
10175 | void ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, |
10176 | Scope *S, QualType MapperType, |
10177 | SourceLocation StartLoc, |
10178 | DeclarationName VN); |
10179 | /// Called at the end of '#pragma omp declare mapper'. |
10180 | DeclGroupPtrTy |
10181 | ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, |
10182 | ArrayRef<OMPClause *> ClauseList); |
10183 | |
10184 | /// Called on the start of target region i.e. '#pragma omp declare target'. |
10185 | bool ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc); |
10186 | /// Called at the end of target region i.e. '#pragme omp end declare target'. |
10187 | void ActOnFinishOpenMPDeclareTargetDirective(); |
10188 | /// Searches for the provided declaration name for OpenMP declare target |
10189 | /// directive. |
10190 | NamedDecl * |
10191 | lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, |
10192 | const DeclarationNameInfo &Id, |
10193 | NamedDeclSetType &SameDirectiveDecls); |
10194 | /// Called on correct id-expression from the '#pragma omp declare target'. |
10195 | void ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc, |
10196 | OMPDeclareTargetDeclAttr::MapTypeTy MT, |
10197 | OMPDeclareTargetDeclAttr::DevTypeTy DT); |
10198 | /// Check declaration inside target region. |
10199 | void |
10200 | checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, |
10201 | SourceLocation IdLoc = SourceLocation()); |
10202 | /// Finishes analysis of the deferred functions calls that may be declared as |
10203 | /// host/nohost during device/host compilation. |
10204 | void finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, |
10205 | const FunctionDecl *Callee, |
10206 | SourceLocation Loc); |
10207 | /// Return true inside OpenMP declare target region. |
10208 | bool isInOpenMPDeclareTargetContext() const { |
10209 | return DeclareTargetNestingLevel > 0; |
10210 | } |
10211 | /// Return true inside OpenMP target region. |
10212 | bool isInOpenMPTargetExecutionDirective() const; |
10213 | |
10214 | /// Return the number of captured regions created for an OpenMP directive. |
10215 | static int getOpenMPCaptureLevels(OpenMPDirectiveKind Kind); |
10216 | |
10217 | /// Initialization of captured region for OpenMP region. |
10218 | void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope); |
10219 | /// End of OpenMP region. |
10220 | /// |
10221 | /// \param S Statement associated with the current OpenMP region. |
10222 | /// \param Clauses List of clauses for the current OpenMP region. |
10223 | /// |
10224 | /// \returns Statement for finished OpenMP region. |
10225 | StmtResult ActOnOpenMPRegionEnd(StmtResult S, ArrayRef<OMPClause *> Clauses); |
10226 | StmtResult ActOnOpenMPExecutableDirective( |
10227 | OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, |
10228 | OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, |
10229 | Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc); |
10230 | /// Called on well-formed '\#pragma omp parallel' after parsing |
10231 | /// of the associated statement. |
10232 | StmtResult ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, |
10233 | Stmt *AStmt, |
10234 | SourceLocation StartLoc, |
10235 | SourceLocation EndLoc); |
10236 | using VarsWithInheritedDSAType = |
10237 | llvm::SmallDenseMap<const ValueDecl *, const Expr *, 4>; |
10238 | /// Called on well-formed '\#pragma omp simd' after parsing |
10239 | /// of the associated statement. |
10240 | StmtResult |
10241 | ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, |
10242 | SourceLocation StartLoc, SourceLocation EndLoc, |
10243 | VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10244 | /// Called on well-formed '\#pragma omp for' after parsing |
10245 | /// of the associated statement. |
10246 | StmtResult |
10247 | ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, |
10248 | SourceLocation StartLoc, SourceLocation EndLoc, |
10249 | VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10250 | /// Called on well-formed '\#pragma omp for simd' after parsing |
10251 | /// of the associated statement. |
10252 | StmtResult |
10253 | ActOnOpenMPForSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, |
10254 | SourceLocation StartLoc, SourceLocation EndLoc, |
10255 | VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10256 | /// Called on well-formed '\#pragma omp sections' after parsing |
10257 | /// of the associated statement. |
10258 | StmtResult ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, |
10259 | Stmt *AStmt, SourceLocation StartLoc, |
10260 | SourceLocation EndLoc); |
10261 | /// Called on well-formed '\#pragma omp section' after parsing of the |
10262 | /// associated statement. |
10263 | StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc, |
10264 | SourceLocation EndLoc); |
10265 | /// Called on well-formed '\#pragma omp single' after parsing of the |
10266 | /// associated statement. |
10267 | StmtResult ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, |
10268 | Stmt *AStmt, SourceLocation StartLoc, |
10269 | SourceLocation EndLoc); |
10270 | /// Called on well-formed '\#pragma omp master' after parsing of the |
10271 | /// associated statement. |
10272 | StmtResult ActOnOpenMPMasterDirective(Stmt *AStmt, SourceLocation StartLoc, |
10273 | SourceLocation EndLoc); |
10274 | /// Called on well-formed '\#pragma omp critical' after parsing of the |
10275 | /// associated statement. |
10276 | StmtResult ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName, |
10277 | ArrayRef<OMPClause *> Clauses, |
10278 | Stmt *AStmt, SourceLocation StartLoc, |
10279 | SourceLocation EndLoc); |
10280 | /// Called on well-formed '\#pragma omp parallel for' after parsing |
10281 | /// of the associated statement. |
10282 | StmtResult ActOnOpenMPParallelForDirective( |
10283 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10284 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10285 | /// Called on well-formed '\#pragma omp parallel for simd' after |
10286 | /// parsing of the associated statement. |
10287 | StmtResult ActOnOpenMPParallelForSimdDirective( |
10288 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10289 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10290 | /// Called on well-formed '\#pragma omp parallel master' after |
10291 | /// parsing of the associated statement. |
10292 | StmtResult ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, |
10293 | Stmt *AStmt, |
10294 | SourceLocation StartLoc, |
10295 | SourceLocation EndLoc); |
10296 | /// Called on well-formed '\#pragma omp parallel sections' after |
10297 | /// parsing of the associated statement. |
10298 | StmtResult ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, |
10299 | Stmt *AStmt, |
10300 | SourceLocation StartLoc, |
10301 | SourceLocation EndLoc); |
10302 | /// Called on well-formed '\#pragma omp task' after parsing of the |
10303 | /// associated statement. |
10304 | StmtResult ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, |
10305 | Stmt *AStmt, SourceLocation StartLoc, |
10306 | SourceLocation EndLoc); |
10307 | /// Called on well-formed '\#pragma omp taskyield'. |
10308 | StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, |
10309 | SourceLocation EndLoc); |
10310 | /// Called on well-formed '\#pragma omp barrier'. |
10311 | StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc, |
10312 | SourceLocation EndLoc); |
10313 | /// Called on well-formed '\#pragma omp taskwait'. |
10314 | StmtResult ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, |
10315 | SourceLocation EndLoc); |
10316 | /// Called on well-formed '\#pragma omp taskgroup'. |
10317 | StmtResult ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, |
10318 | Stmt *AStmt, SourceLocation StartLoc, |
10319 | SourceLocation EndLoc); |
10320 | /// Called on well-formed '\#pragma omp flush'. |
10321 | StmtResult ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, |
10322 | SourceLocation StartLoc, |
10323 | SourceLocation EndLoc); |
10324 | /// Called on well-formed '\#pragma omp depobj'. |
10325 | StmtResult ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, |
10326 | SourceLocation StartLoc, |
10327 | SourceLocation EndLoc); |
10328 | /// Called on well-formed '\#pragma omp scan'. |
10329 | StmtResult ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, |
10330 | SourceLocation StartLoc, |
10331 | SourceLocation EndLoc); |
10332 | /// Called on well-formed '\#pragma omp ordered' after parsing of the |
10333 | /// associated statement. |
10334 | StmtResult ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, |
10335 | Stmt *AStmt, SourceLocation StartLoc, |
10336 | SourceLocation EndLoc); |
10337 | /// Called on well-formed '\#pragma omp atomic' after parsing of the |
10338 | /// associated statement. |
10339 | StmtResult ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, |
10340 | Stmt *AStmt, SourceLocation StartLoc, |
10341 | SourceLocation EndLoc); |
10342 | /// Called on well-formed '\#pragma omp target' after parsing of the |
10343 | /// associated statement. |
10344 | StmtResult ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, |
10345 | Stmt *AStmt, SourceLocation StartLoc, |
10346 | SourceLocation EndLoc); |
10347 | /// Called on well-formed '\#pragma omp target data' after parsing of |
10348 | /// the associated statement. |
10349 | StmtResult ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, |
10350 | Stmt *AStmt, SourceLocation StartLoc, |
10351 | SourceLocation EndLoc); |
10352 | /// Called on well-formed '\#pragma omp target enter data' after |
10353 | /// parsing of the associated statement. |
10354 | StmtResult ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, |
10355 | SourceLocation StartLoc, |
10356 | SourceLocation EndLoc, |
10357 | Stmt *AStmt); |
10358 | /// Called on well-formed '\#pragma omp target exit data' after |
10359 | /// parsing of the associated statement. |
10360 | StmtResult ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, |
10361 | SourceLocation StartLoc, |
10362 | SourceLocation EndLoc, |
10363 | Stmt *AStmt); |
10364 | /// Called on well-formed '\#pragma omp target parallel' after |
10365 | /// parsing of the associated statement. |
10366 | StmtResult ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, |
10367 | Stmt *AStmt, |
10368 | SourceLocation StartLoc, |
10369 | SourceLocation EndLoc); |
10370 | /// Called on well-formed '\#pragma omp target parallel for' after |
10371 | /// parsing of the associated statement. |
10372 | StmtResult ActOnOpenMPTargetParallelForDirective( |
10373 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10374 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10375 | /// Called on well-formed '\#pragma omp teams' after parsing of the |
10376 | /// associated statement. |
10377 | StmtResult ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, |
10378 | Stmt *AStmt, SourceLocation StartLoc, |
10379 | SourceLocation EndLoc); |
10380 | /// Called on well-formed '\#pragma omp cancellation point'. |
10381 | StmtResult |
10382 | ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, |
10383 | SourceLocation EndLoc, |
10384 | OpenMPDirectiveKind CancelRegion); |
10385 | /// Called on well-formed '\#pragma omp cancel'. |
10386 | StmtResult ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, |
10387 | SourceLocation StartLoc, |
10388 | SourceLocation EndLoc, |
10389 | OpenMPDirectiveKind CancelRegion); |
10390 | /// Called on well-formed '\#pragma omp taskloop' after parsing of the |
10391 | /// associated statement. |
10392 | StmtResult |
10393 | ActOnOpenMPTaskLoopDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, |
10394 | SourceLocation StartLoc, SourceLocation EndLoc, |
10395 | VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10396 | /// Called on well-formed '\#pragma omp taskloop simd' after parsing of |
10397 | /// the associated statement. |
10398 | StmtResult ActOnOpenMPTaskLoopSimdDirective( |
10399 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10400 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10401 | /// Called on well-formed '\#pragma omp master taskloop' after parsing of the |
10402 | /// associated statement. |
10403 | StmtResult ActOnOpenMPMasterTaskLoopDirective( |
10404 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10405 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10406 | /// Called on well-formed '\#pragma omp master taskloop simd' after parsing of |
10407 | /// the associated statement. |
10408 | StmtResult ActOnOpenMPMasterTaskLoopSimdDirective( |
10409 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10410 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10411 | /// Called on well-formed '\#pragma omp parallel master taskloop' after |
10412 | /// parsing of the associated statement. |
10413 | StmtResult ActOnOpenMPParallelMasterTaskLoopDirective( |
10414 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10415 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10416 | /// Called on well-formed '\#pragma omp parallel master taskloop simd' after |
10417 | /// parsing of the associated statement. |
10418 | StmtResult ActOnOpenMPParallelMasterTaskLoopSimdDirective( |
10419 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10420 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10421 | /// Called on well-formed '\#pragma omp distribute' after parsing |
10422 | /// of the associated statement. |
10423 | StmtResult |
10424 | ActOnOpenMPDistributeDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, |
10425 | SourceLocation StartLoc, SourceLocation EndLoc, |
10426 | VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10427 | /// Called on well-formed '\#pragma omp target update'. |
10428 | StmtResult ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, |
10429 | SourceLocation StartLoc, |
10430 | SourceLocation EndLoc, |
10431 | Stmt *AStmt); |
10432 | /// Called on well-formed '\#pragma omp distribute parallel for' after |
10433 | /// parsing of the associated statement. |
10434 | StmtResult ActOnOpenMPDistributeParallelForDirective( |
10435 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10436 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10437 | /// Called on well-formed '\#pragma omp distribute parallel for simd' |
10438 | /// after parsing of the associated statement. |
10439 | StmtResult ActOnOpenMPDistributeParallelForSimdDirective( |
10440 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10441 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10442 | /// Called on well-formed '\#pragma omp distribute simd' after |
10443 | /// parsing of the associated statement. |
10444 | StmtResult ActOnOpenMPDistributeSimdDirective( |
10445 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10446 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10447 | /// Called on well-formed '\#pragma omp target parallel for simd' after |
10448 | /// parsing of the associated statement. |
10449 | StmtResult ActOnOpenMPTargetParallelForSimdDirective( |
10450 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10451 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10452 | /// Called on well-formed '\#pragma omp target simd' after parsing of |
10453 | /// the associated statement. |
10454 | StmtResult |
10455 | ActOnOpenMPTargetSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, |
10456 | SourceLocation StartLoc, SourceLocation EndLoc, |
10457 | VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10458 | /// Called on well-formed '\#pragma omp teams distribute' after parsing of |
10459 | /// the associated statement. |
10460 | StmtResult ActOnOpenMPTeamsDistributeDirective( |
10461 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10462 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10463 | /// Called on well-formed '\#pragma omp teams distribute simd' after parsing |
10464 | /// of the associated statement. |
10465 | StmtResult ActOnOpenMPTeamsDistributeSimdDirective( |
10466 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10467 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10468 | /// Called on well-formed '\#pragma omp teams distribute parallel for simd' |
10469 | /// after parsing of the associated statement. |
10470 | StmtResult ActOnOpenMPTeamsDistributeParallelForSimdDirective( |
10471 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10472 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10473 | /// Called on well-formed '\#pragma omp teams distribute parallel for' |
10474 | /// after parsing of the associated statement. |
10475 | StmtResult ActOnOpenMPTeamsDistributeParallelForDirective( |
10476 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10477 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10478 | /// Called on well-formed '\#pragma omp target teams' after parsing of the |
10479 | /// associated statement. |
10480 | StmtResult ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, |
10481 | Stmt *AStmt, |
10482 | SourceLocation StartLoc, |
10483 | SourceLocation EndLoc); |
10484 | /// Called on well-formed '\#pragma omp target teams distribute' after parsing |
10485 | /// of the associated statement. |
10486 | StmtResult ActOnOpenMPTargetTeamsDistributeDirective( |
10487 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10488 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10489 | /// Called on well-formed '\#pragma omp target teams distribute parallel for' |
10490 | /// after parsing of the associated statement. |
10491 | StmtResult ActOnOpenMPTargetTeamsDistributeParallelForDirective( |
10492 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10493 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10494 | /// Called on well-formed '\#pragma omp target teams distribute parallel for |
10495 | /// simd' after parsing of the associated statement. |
10496 | StmtResult ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( |
10497 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10498 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10499 | /// Called on well-formed '\#pragma omp target teams distribute simd' after |
10500 | /// parsing of the associated statement. |
10501 | StmtResult ActOnOpenMPTargetTeamsDistributeSimdDirective( |
10502 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10503 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); |
10504 | |
10505 | /// Checks correctness of linear modifiers. |
10506 | bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, |
10507 | SourceLocation LinLoc); |
10508 | /// Checks that the specified declaration matches requirements for the linear |
10509 | /// decls. |
10510 | bool CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, |
10511 | OpenMPLinearClauseKind LinKind, QualType Type, |
10512 | bool IsDeclareSimd = false); |
10513 | |
10514 | /// Called on well-formed '\#pragma omp declare simd' after parsing of |
10515 | /// the associated method/function. |
10516 | DeclGroupPtrTy ActOnOpenMPDeclareSimdDirective( |
10517 | DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, |
10518 | Expr *Simdlen, ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, |
10519 | ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, |
10520 | ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR); |
10521 | |
10522 | /// Checks '\#pragma omp declare variant' variant function and original |
10523 | /// functions after parsing of the associated method/function. |
10524 | /// \param DG Function declaration to which declare variant directive is |
10525 | /// applied to. |
10526 | /// \param VariantRef Expression that references the variant function, which |
10527 | /// must be used instead of the original one, specified in \p DG. |
10528 | /// \param TI The trait info object representing the match clause. |
10529 | /// \returns None, if the function/variant function are not compatible with |
10530 | /// the pragma, pair of original function/variant ref expression otherwise. |
10531 | Optional<std::pair<FunctionDecl *, Expr *>> |
10532 | checkOpenMPDeclareVariantFunction(DeclGroupPtrTy DG, Expr *VariantRef, |
10533 | OMPTraitInfo &TI, SourceRange SR); |
10534 | |
10535 | /// Called on well-formed '\#pragma omp declare variant' after parsing of |
10536 | /// the associated method/function. |
10537 | /// \param FD Function declaration to which declare variant directive is |
10538 | /// applied to. |
10539 | /// \param VariantRef Expression that references the variant function, which |
10540 | /// must be used instead of the original one, specified in \p DG. |
10541 | /// \param TI The context traits associated with the function variant. |
10542 | void ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, Expr *VariantRef, |
10543 | OMPTraitInfo &TI, SourceRange SR); |
10544 | |
10545 | OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, |
10546 | Expr *Expr, |
10547 | SourceLocation StartLoc, |
10548 | SourceLocation LParenLoc, |
10549 | SourceLocation EndLoc); |
10550 | /// Called on well-formed 'allocator' clause. |
10551 | OMPClause *ActOnOpenMPAllocatorClause(Expr *Allocator, |
10552 | SourceLocation StartLoc, |
10553 | SourceLocation LParenLoc, |
10554 | SourceLocation EndLoc); |
10555 | /// Called on well-formed 'if' clause. |
10556 | OMPClause *ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, |
10557 | Expr *Condition, SourceLocation StartLoc, |
10558 | SourceLocation LParenLoc, |
10559 | SourceLocation NameModifierLoc, |
10560 | SourceLocation ColonLoc, |
10561 | SourceLocation EndLoc); |
10562 | /// Called on well-formed 'final' clause. |
10563 | OMPClause *ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc, |
10564 | SourceLocation LParenLoc, |
10565 | SourceLocation EndLoc); |
10566 | /// Called on well-formed 'num_threads' clause. |
10567 | OMPClause *ActOnOpenMPNumThreadsClause(Expr *NumThreads, |
10568 | SourceLocation StartLoc, |
10569 | SourceLocation LParenLoc, |
10570 | SourceLocation EndLoc); |
10571 | /// Called on well-formed 'safelen' clause. |
10572 | OMPClause *ActOnOpenMPSafelenClause(Expr *Length, |
10573 | SourceLocation StartLoc, |
10574 | SourceLocation LParenLoc, |
10575 | SourceLocation EndLoc); |
10576 | /// Called on well-formed 'simdlen' clause. |
10577 | OMPClause *ActOnOpenMPSimdlenClause(Expr *Length, SourceLocation StartLoc, |
10578 | SourceLocation LParenLoc, |
10579 | SourceLocation EndLoc); |
10580 | /// Called on well-formed 'collapse' clause. |
10581 | OMPClause *ActOnOpenMPCollapseClause(Expr *NumForLoops, |
10582 | SourceLocation StartLoc, |
10583 | SourceLocation LParenLoc, |
10584 | SourceLocation EndLoc); |
10585 | /// Called on well-formed 'ordered' clause. |
10586 | OMPClause * |
10587 | ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc, |
10588 | SourceLocation LParenLoc = SourceLocation(), |
10589 | Expr *NumForLoops = nullptr); |
10590 | /// Called on well-formed 'grainsize' clause. |
10591 | OMPClause *ActOnOpenMPGrainsizeClause(Expr *Size, SourceLocation StartLoc, |
10592 | SourceLocation LParenLoc, |
10593 | SourceLocation EndLoc); |
10594 | /// Called on well-formed 'num_tasks' clause. |
10595 | OMPClause *ActOnOpenMPNumTasksClause(Expr *NumTasks, SourceLocation StartLoc, |
10596 | SourceLocation LParenLoc, |
10597 | SourceLocation EndLoc); |
10598 | /// Called on well-formed 'hint' clause. |
10599 | OMPClause *ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, |
10600 | SourceLocation LParenLoc, |
10601 | SourceLocation EndLoc); |
10602 | /// Called on well-formed 'detach' clause. |
10603 | OMPClause *ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, |
10604 | SourceLocation LParenLoc, |
10605 | SourceLocation EndLoc); |
10606 | |
10607 | OMPClause *ActOnOpenMPSimpleClause(OpenMPClauseKind Kind, |
10608 | unsigned Argument, |
10609 | SourceLocation ArgumentLoc, |
10610 | SourceLocation StartLoc, |
10611 | SourceLocation LParenLoc, |
10612 | SourceLocation EndLoc); |
10613 | /// Called on well-formed 'default' clause. |
10614 | OMPClause *ActOnOpenMPDefaultClause(llvm::omp::DefaultKind Kind, |
10615 | SourceLocation KindLoc, |
10616 | SourceLocation StartLoc, |
10617 | SourceLocation LParenLoc, |
10618 | SourceLocation EndLoc); |
10619 | /// Called on well-formed 'proc_bind' clause. |
10620 | OMPClause *ActOnOpenMPProcBindClause(llvm::omp::ProcBindKind Kind, |
10621 | SourceLocation KindLoc, |
10622 | SourceLocation StartLoc, |
10623 | SourceLocation LParenLoc, |
10624 | SourceLocation EndLoc); |
10625 | /// Called on well-formed 'order' clause. |
10626 | OMPClause *ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, |
10627 | SourceLocation KindLoc, |
10628 | SourceLocation StartLoc, |
10629 | SourceLocation LParenLoc, |
10630 | SourceLocation EndLoc); |
10631 | /// Called on well-formed 'update' clause. |
10632 | OMPClause *ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, |
10633 | SourceLocation KindLoc, |
10634 | SourceLocation StartLoc, |
10635 | SourceLocation LParenLoc, |
10636 | SourceLocation EndLoc); |
10637 | |
10638 | OMPClause *ActOnOpenMPSingleExprWithArgClause( |
10639 | OpenMPClauseKind Kind, ArrayRef<unsigned> Arguments, Expr *Expr, |
10640 | SourceLocation StartLoc, SourceLocation LParenLoc, |
10641 | ArrayRef<SourceLocation> ArgumentsLoc, SourceLocation DelimLoc, |
10642 | SourceLocation EndLoc); |
10643 | /// Called on well-formed 'schedule' clause. |
10644 | OMPClause *ActOnOpenMPScheduleClause( |
10645 | OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, |
10646 | OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, |
10647 | SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, |
10648 | SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc); |
10649 | |
10650 | OMPClause *ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, |
10651 | SourceLocation EndLoc); |
10652 | /// Called on well-formed 'nowait' clause. |
10653 | OMPClause *ActOnOpenMPNowaitClause(SourceLocation StartLoc, |
10654 | SourceLocation EndLoc); |
10655 | /// Called on well-formed 'untied' clause. |
10656 | OMPClause *ActOnOpenMPUntiedClause(SourceLocation StartLoc, |
10657 | SourceLocation EndLoc); |
10658 | /// Called on well-formed 'mergeable' clause. |
10659 | OMPClause *ActOnOpenMPMergeableClause(SourceLocation StartLoc, |
10660 | SourceLocation EndLoc); |
10661 | /// Called on well-formed 'read' clause. |
10662 | OMPClause *ActOnOpenMPReadClause(SourceLocation StartLoc, |
10663 | SourceLocation EndLoc); |
10664 | /// Called on well-formed 'write' clause. |
10665 | OMPClause *ActOnOpenMPWriteClause(SourceLocation StartLoc, |
10666 | SourceLocation EndLoc); |
10667 | /// Called on well-formed 'update' clause. |
10668 | OMPClause *ActOnOpenMPUpdateClause(SourceLocation StartLoc, |
10669 | SourceLocation EndLoc); |
10670 | /// Called on well-formed 'capture' clause. |
10671 | OMPClause *ActOnOpenMPCaptureClause(SourceLocation StartLoc, |
10672 | SourceLocation EndLoc); |
10673 | /// Called on well-formed 'seq_cst' clause. |
10674 | OMPClause *ActOnOpenMPSeqCstClause(SourceLocation StartLoc, |
10675 | SourceLocation EndLoc); |
10676 | /// Called on well-formed 'acq_rel' clause. |
10677 | OMPClause *ActOnOpenMPAcqRelClause(SourceLocation StartLoc, |
10678 | SourceLocation EndLoc); |
10679 | /// Called on well-formed 'acquire' clause. |
10680 | OMPClause *ActOnOpenMPAcquireClause(SourceLocation StartLoc, |
10681 | SourceLocation EndLoc); |
10682 | /// Called on well-formed 'release' clause. |
10683 | OMPClause *ActOnOpenMPReleaseClause(SourceLocation StartLoc, |
10684 | SourceLocation EndLoc); |
10685 | /// Called on well-formed 'relaxed' clause. |
10686 | OMPClause *ActOnOpenMPRelaxedClause(SourceLocation StartLoc, |
10687 | SourceLocation EndLoc); |
10688 | /// Called on well-formed 'destroy' clause. |
10689 | OMPClause *ActOnOpenMPDestroyClause(SourceLocation StartLoc, |
10690 | SourceLocation EndLoc); |
10691 | /// Called on well-formed 'threads' clause. |
10692 | OMPClause *ActOnOpenMPThreadsClause(SourceLocation StartLoc, |
10693 | SourceLocation EndLoc); |
10694 | /// Called on well-formed 'simd' clause. |
10695 | OMPClause *ActOnOpenMPSIMDClause(SourceLocation StartLoc, |
10696 | SourceLocation EndLoc); |
10697 | /// Called on well-formed 'nogroup' clause. |
10698 | OMPClause *ActOnOpenMPNogroupClause(SourceLocation StartLoc, |
10699 | SourceLocation EndLoc); |
10700 | /// Called on well-formed 'unified_address' clause. |
10701 | OMPClause *ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, |
10702 | SourceLocation EndLoc); |
10703 | |
10704 | /// Called on well-formed 'unified_address' clause. |
10705 | OMPClause *ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, |
10706 | SourceLocation EndLoc); |
10707 | |
10708 | /// Called on well-formed 'reverse_offload' clause. |
10709 | OMPClause *ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, |
10710 | SourceLocation EndLoc); |
10711 | |
10712 | /// Called on well-formed 'dynamic_allocators' clause. |
10713 | OMPClause *ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, |
10714 | SourceLocation EndLoc); |
10715 | |
10716 | /// Called on well-formed 'atomic_default_mem_order' clause. |
10717 | OMPClause *ActOnOpenMPAtomicDefaultMemOrderClause( |
10718 | OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindLoc, |
10719 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc); |
10720 | |
10721 | OMPClause *ActOnOpenMPVarListClause( |
10722 | OpenMPClauseKind Kind, ArrayRef<Expr *> Vars, Expr *DepModOrTailExpr, |
10723 | const OMPVarListLocTy &Locs, SourceLocation ColonLoc, |
10724 | CXXScopeSpec &ReductionOrMapperIdScopeSpec, |
10725 | DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, |
10726 | ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, |
10727 | ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, |
10728 | SourceLocation ExtraModifierLoc, |
10729 | ArrayRef<OpenMPMotionModifierKind> MotionModifiers, |
10730 | ArrayRef<SourceLocation> MotionModifiersLoc); |
10731 | /// Called on well-formed 'inclusive' clause. |
10732 | OMPClause *ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, |
10733 | SourceLocation StartLoc, |
10734 | SourceLocation LParenLoc, |
10735 | SourceLocation EndLoc); |
10736 | /// Called on well-formed 'exclusive' clause. |
10737 | OMPClause *ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList, |
10738 | SourceLocation StartLoc, |
10739 | SourceLocation LParenLoc, |
10740 | SourceLocation EndLoc); |
10741 | /// Called on well-formed 'allocate' clause. |
10742 | OMPClause * |
10743 | ActOnOpenMPAllocateClause(Expr *Allocator, ArrayRef<Expr *> VarList, |
10744 | SourceLocation StartLoc, SourceLocation ColonLoc, |
10745 | SourceLocation LParenLoc, SourceLocation EndLoc); |
10746 | /// Called on well-formed 'private' clause. |
10747 | OMPClause *ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, |
10748 | SourceLocation StartLoc, |
10749 | SourceLocation LParenLoc, |
10750 | SourceLocation EndLoc); |
10751 | /// Called on well-formed 'firstprivate' clause. |
10752 | OMPClause *ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, |
10753 | SourceLocation StartLoc, |
10754 | SourceLocation LParenLoc, |
10755 | SourceLocation EndLoc); |
10756 | /// Called on well-formed 'lastprivate' clause. |
10757 | OMPClause *ActOnOpenMPLastprivateClause( |
10758 | ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, |
10759 | SourceLocation LPKindLoc, SourceLocation ColonLoc, |
10760 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc); |
10761 | /// Called on well-formed 'shared' clause. |
10762 | OMPClause *ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, |
10763 | SourceLocation StartLoc, |
10764 | SourceLocation LParenLoc, |
10765 | SourceLocation EndLoc); |
10766 | /// Called on well-formed 'reduction' clause. |
10767 | OMPClause *ActOnOpenMPReductionClause( |
10768 | ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, |
10769 | SourceLocation StartLoc, SourceLocation LParenLoc, |
10770 | SourceLocation ModifierLoc, SourceLocation ColonLoc, |
10771 | SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, |
10772 | const DeclarationNameInfo &ReductionId, |
10773 | ArrayRef<Expr *> UnresolvedReductions = llvm::None); |
10774 | /// Called on well-formed 'task_reduction' clause. |
10775 | OMPClause *ActOnOpenMPTaskReductionClause( |
10776 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, |
10777 | SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, |
10778 | CXXScopeSpec &ReductionIdScopeSpec, |
10779 | const DeclarationNameInfo &ReductionId, |
10780 | ArrayRef<Expr *> UnresolvedReductions = llvm::None); |
10781 | /// Called on well-formed 'in_reduction' clause. |
10782 | OMPClause *ActOnOpenMPInReductionClause( |
10783 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, |
10784 | SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, |
10785 | CXXScopeSpec &ReductionIdScopeSpec, |
10786 | const DeclarationNameInfo &ReductionId, |
10787 | ArrayRef<Expr *> UnresolvedReductions = llvm::None); |
10788 | /// Called on well-formed 'linear' clause. |
10789 | OMPClause * |
10790 | ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step, |
10791 | SourceLocation StartLoc, SourceLocation LParenLoc, |
10792 | OpenMPLinearClauseKind LinKind, SourceLocation LinLoc, |
10793 | SourceLocation ColonLoc, SourceLocation EndLoc); |
10794 | /// Called on well-formed 'aligned' clause. |
10795 | OMPClause *ActOnOpenMPAlignedClause(ArrayRef<Expr *> VarList, |
10796 | Expr *Alignment, |
10797 | SourceLocation StartLoc, |
10798 | SourceLocation LParenLoc, |
10799 | SourceLocation ColonLoc, |
10800 | SourceLocation EndLoc); |
10801 | /// Called on well-formed 'copyin' clause. |
10802 | OMPClause *ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, |
10803 | SourceLocation StartLoc, |
10804 | SourceLocation LParenLoc, |
10805 | SourceLocation EndLoc); |
10806 | /// Called on well-formed 'copyprivate' clause. |
10807 | OMPClause *ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, |
10808 | SourceLocation StartLoc, |
10809 | SourceLocation LParenLoc, |
10810 | SourceLocation EndLoc); |
10811 | /// Called on well-formed 'flush' pseudo clause. |
10812 | OMPClause *ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, |
10813 | SourceLocation StartLoc, |
10814 | SourceLocation LParenLoc, |
10815 | SourceLocation EndLoc); |
10816 | /// Called on well-formed 'depobj' pseudo clause. |
10817 | OMPClause *ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, |
10818 | SourceLocation LParenLoc, |
10819 | SourceLocation EndLoc); |
10820 | /// Called on well-formed 'depend' clause. |
10821 | OMPClause * |
10822 | ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, |
10823 | SourceLocation DepLoc, SourceLocation ColonLoc, |
10824 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, |
10825 | SourceLocation LParenLoc, SourceLocation EndLoc); |
10826 | /// Called on well-formed 'device' clause. |
10827 | OMPClause *ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, |
10828 | Expr *Device, SourceLocation StartLoc, |
10829 | SourceLocation LParenLoc, |
10830 | SourceLocation ModifierLoc, |
10831 | SourceLocation EndLoc); |
10832 | /// Called on well-formed 'map' clause. |
10833 | OMPClause * |
10834 | ActOnOpenMPMapClause(ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, |
10835 | ArrayRef<SourceLocation> MapTypeModifiersLoc, |
10836 | CXXScopeSpec &MapperIdScopeSpec, |
10837 | DeclarationNameInfo &MapperId, |
10838 | OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, |
10839 | SourceLocation MapLoc, SourceLocation ColonLoc, |
10840 | ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs, |
10841 | ArrayRef<Expr *> UnresolvedMappers = llvm::None); |
10842 | /// Called on well-formed 'num_teams' clause. |
10843 | OMPClause *ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, |
10844 | SourceLocation LParenLoc, |
10845 | SourceLocation EndLoc); |
10846 | /// Called on well-formed 'thread_limit' clause. |
10847 | OMPClause *ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, |
10848 | SourceLocation StartLoc, |
10849 | SourceLocation LParenLoc, |
10850 | SourceLocation EndLoc); |
10851 | /// Called on well-formed 'priority' clause. |
10852 | OMPClause *ActOnOpenMPPriorityClause(Expr *Priority, SourceLocation StartLoc, |
10853 | SourceLocation LParenLoc, |
10854 | SourceLocation EndLoc); |
10855 | /// Called on well-formed 'dist_schedule' clause. |
10856 | OMPClause *ActOnOpenMPDistScheduleClause( |
10857 | OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, |
10858 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KindLoc, |
10859 | SourceLocation CommaLoc, SourceLocation EndLoc); |
10860 | /// Called on well-formed 'defaultmap' clause. |
10861 | OMPClause *ActOnOpenMPDefaultmapClause( |
10862 | OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, |
10863 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, |
10864 | SourceLocation KindLoc, SourceLocation EndLoc); |
10865 | /// Called on well-formed 'to' clause. |
10866 | OMPClause * |
10867 | ActOnOpenMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers, |
10868 | ArrayRef<SourceLocation> MotionModifiersLoc, |
10869 | CXXScopeSpec &MapperIdScopeSpec, |
10870 | DeclarationNameInfo &MapperId, SourceLocation ColonLoc, |
10871 | ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs, |
10872 | ArrayRef<Expr *> UnresolvedMappers = llvm::None); |
10873 | /// Called on well-formed 'from' clause. |
10874 | OMPClause * |
10875 | ActOnOpenMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers, |
10876 | ArrayRef<SourceLocation> MotionModifiersLoc, |
10877 | CXXScopeSpec &MapperIdScopeSpec, |
10878 | DeclarationNameInfo &MapperId, SourceLocation ColonLoc, |
10879 | ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs, |
10880 | ArrayRef<Expr *> UnresolvedMappers = llvm::None); |
10881 | /// Called on well-formed 'use_device_ptr' clause. |
10882 | OMPClause *ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, |
10883 | const OMPVarListLocTy &Locs); |
10884 | /// Called on well-formed 'use_device_addr' clause. |
10885 | OMPClause *ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList, |
10886 | const OMPVarListLocTy &Locs); |
10887 | /// Called on well-formed 'is_device_ptr' clause. |
10888 | OMPClause *ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, |
10889 | const OMPVarListLocTy &Locs); |
10890 | /// Called on well-formed 'nontemporal' clause. |
10891 | OMPClause *ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, |
10892 | SourceLocation StartLoc, |
10893 | SourceLocation LParenLoc, |
10894 | SourceLocation EndLoc); |
10895 | |
10896 | /// Data for list of allocators. |
10897 | struct UsesAllocatorsData { |
10898 | /// Allocator. |
10899 | Expr *Allocator = nullptr; |
10900 | /// Allocator traits. |
10901 | Expr *AllocatorTraits = nullptr; |
10902 | /// Locations of '(' and ')' symbols. |
10903 | SourceLocation LParenLoc, RParenLoc; |
10904 | }; |
10905 | /// Called on well-formed 'uses_allocators' clause. |
10906 | OMPClause *ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc, |
10907 | SourceLocation LParenLoc, |
10908 | SourceLocation EndLoc, |
10909 | ArrayRef<UsesAllocatorsData> Data); |
10910 | /// Called on well-formed 'affinity' clause. |
10911 | OMPClause *ActOnOpenMPAffinityClause(SourceLocation StartLoc, |
10912 | SourceLocation LParenLoc, |
10913 | SourceLocation ColonLoc, |
10914 | SourceLocation EndLoc, Expr *Modifier, |
10915 | ArrayRef<Expr *> Locators); |
10916 | |
10917 | /// The kind of conversion being performed. |
10918 | enum CheckedConversionKind { |
10919 | /// An implicit conversion. |
10920 | CCK_ImplicitConversion, |
10921 | /// A C-style cast. |
10922 | CCK_CStyleCast, |
10923 | /// A functional-style cast. |
10924 | CCK_FunctionalCast, |
10925 | /// A cast other than a C-style cast. |
10926 | CCK_OtherCast, |
10927 | /// A conversion for an operand of a builtin overloaded operator. |
10928 | CCK_ForBuiltinOverloadedOp |
10929 | }; |
10930 | |
10931 | static bool isCast(CheckedConversionKind CCK) { |
10932 | return CCK == CCK_CStyleCast || CCK == CCK_FunctionalCast || |
10933 | CCK == CCK_OtherCast; |
10934 | } |
10935 | |
10936 | /// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit |
10937 | /// cast. If there is already an implicit cast, merge into the existing one. |
10938 | /// If isLvalue, the result of the cast is an lvalue. |
10939 | ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, |
10940 | ExprValueKind VK = VK_RValue, |
10941 | const CXXCastPath *BasePath = nullptr, |
10942 | CheckedConversionKind CCK |
10943 | = CCK_ImplicitConversion); |
10944 | |
10945 | /// ScalarTypeToBooleanCastKind - Returns the cast kind corresponding |
10946 | /// to the conversion from scalar type ScalarTy to the Boolean type. |
10947 | static CastKind ScalarTypeToBooleanCastKind(QualType ScalarTy); |
10948 | |
10949 | /// IgnoredValueConversions - Given that an expression's result is |
10950 | /// syntactically ignored, perform any conversions that are |
10951 | /// required. |
10952 | ExprResult IgnoredValueConversions(Expr *E); |
10953 | |
10954 | // UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts |
10955 | // functions and arrays to their respective pointers (C99 6.3.2.1). |
10956 | ExprResult UsualUnaryConversions(Expr *E); |
10957 | |
10958 | /// CallExprUnaryConversions - a special case of an unary conversion |
10959 | /// performed on a function designator of a call expression. |
10960 | ExprResult CallExprUnaryConversions(Expr *E); |
10961 | |
10962 | // DefaultFunctionArrayConversion - converts functions and arrays |
10963 | // to their respective pointers (C99 6.3.2.1). |
10964 | ExprResult DefaultFunctionArrayConversion(Expr *E, bool Diagnose = true); |
10965 | |
10966 | // DefaultFunctionArrayLvalueConversion - converts functions and |
10967 | // arrays to their respective pointers and performs the |
10968 | // lvalue-to-rvalue conversion. |
10969 | ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, |
10970 | bool Diagnose = true); |
10971 | |
10972 | // DefaultLvalueConversion - performs lvalue-to-rvalue conversion on |
10973 | // the operand. This function is a no-op if the operand has a function type |
10974 | // or an array type. |
10975 | ExprResult DefaultLvalueConversion(Expr *E); |
10976 | |
10977 | // DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that |
10978 | // do not have a prototype. Integer promotions are performed on each |
10979 | // argument, and arguments that have type float are promoted to double. |
10980 | ExprResult DefaultArgumentPromotion(Expr *E); |
10981 | |
10982 | /// If \p E is a prvalue denoting an unmaterialized temporary, materialize |
10983 | /// it as an xvalue. In C++98, the result will still be a prvalue, because |
10984 | /// we don't have xvalues there. |
10985 | ExprResult TemporaryMaterializationConversion(Expr *E); |
10986 | |
10987 | // Used for emitting the right warning by DefaultVariadicArgumentPromotion |
10988 | enum VariadicCallType { |
10989 | VariadicFunction, |
10990 | VariadicBlock, |
10991 | VariadicMethod, |
10992 | VariadicConstructor, |
10993 | VariadicDoesNotApply |
10994 | }; |
10995 | |
10996 | VariadicCallType getVariadicCallType(FunctionDecl *FDecl, |
10997 | const FunctionProtoType *Proto, |
10998 | Expr *Fn); |
10999 | |
11000 | // Used for determining in which context a type is allowed to be passed to a |
11001 | // vararg function. |
11002 | enum VarArgKind { |
11003 | VAK_Valid, |
11004 | VAK_ValidInCXX11, |
11005 | VAK_Undefined, |
11006 | VAK_MSVCUndefined, |
11007 | VAK_Invalid |
11008 | }; |
11009 | |
11010 | // Determines which VarArgKind fits an expression. |
11011 | VarArgKind isValidVarArgType(const QualType &Ty); |
11012 | |
11013 | /// Check to see if the given expression is a valid argument to a variadic |
11014 | /// function, issuing a diagnostic if not. |
11015 | void checkVariadicArgument(const Expr *E, VariadicCallType CT); |
11016 | |
11017 | /// Check to see if a given expression could have '.c_str()' called on it. |
11018 | bool hasCStrMethod(const Expr *E); |
11019 | |
11020 | /// GatherArgumentsForCall - Collector argument expressions for various |
11021 | /// form of call prototypes. |
11022 | bool GatherArgumentsForCall(SourceLocation CallLoc, FunctionDecl *FDecl, |
11023 | const FunctionProtoType *Proto, |
11024 | unsigned FirstParam, ArrayRef<Expr *> Args, |
11025 | SmallVectorImpl<Expr *> &AllArgs, |
11026 | VariadicCallType CallType = VariadicDoesNotApply, |
11027 | bool AllowExplicit = false, |
11028 | bool IsListInitialization = false); |
11029 | |
11030 | // DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but |
11031 | // will create a runtime trap if the resulting type is not a POD type. |
11032 | ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, |
11033 | FunctionDecl *FDecl); |
11034 | |
11035 | /// Context in which we're performing a usual arithmetic conversion. |
11036 | enum ArithConvKind { |
11037 | /// An arithmetic operation. |
11038 | ACK_Arithmetic, |
11039 | /// A bitwise operation. |
11040 | ACK_BitwiseOp, |
11041 | /// A comparison. |
11042 | ACK_Comparison, |
11043 | /// A conditional (?:) operator. |
11044 | ACK_Conditional, |
11045 | /// A compound assignment expression. |
11046 | ACK_CompAssign, |
11047 | }; |
11048 | |
11049 | // UsualArithmeticConversions - performs the UsualUnaryConversions on it's |
11050 | // operands and then handles various conversions that are common to binary |
11051 | // operators (C99 6.3.1.8). If both operands aren't arithmetic, this |
11052 | // routine returns the first non-arithmetic type found. The client is |
11053 | // responsible for emitting appropriate error diagnostics. |
11054 | QualType UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS, |
11055 | SourceLocation Loc, ArithConvKind ACK); |
11056 | |
11057 | /// AssignConvertType - All of the 'assignment' semantic checks return this |
11058 | /// enum to indicate whether the assignment was allowed. These checks are |
11059 | /// done for simple assignments, as well as initialization, return from |
11060 | /// function, argument passing, etc. The query is phrased in terms of a |
11061 | /// source and destination type. |
11062 | enum AssignConvertType { |
11063 | /// Compatible - the types are compatible according to the standard. |
11064 | Compatible, |
11065 | |
11066 | /// PointerToInt - The assignment converts a pointer to an int, which we |
11067 | /// accept as an extension. |
11068 | PointerToInt, |
11069 | |
11070 | /// IntToPointer - The assignment converts an int to a pointer, which we |
11071 | /// accept as an extension. |
11072 | IntToPointer, |
11073 | |
11074 | /// FunctionVoidPointer - The assignment is between a function pointer and |
11075 | /// void*, which the standard doesn't allow, but we accept as an extension. |
11076 | FunctionVoidPointer, |
11077 | |
11078 | /// IncompatiblePointer - The assignment is between two pointers types that |
11079 | /// are not compatible, but we accept them as an extension. |
11080 | IncompatiblePointer, |
11081 | |
11082 | /// IncompatibleFunctionPointer - The assignment is between two function |
11083 | /// pointers types that are not compatible, but we accept them as an |
11084 | /// extension. |
11085 | IncompatibleFunctionPointer, |
11086 | |
11087 | /// IncompatiblePointerSign - The assignment is between two pointers types |
11088 | /// which point to integers which have a different sign, but are otherwise |
11089 | /// identical. This is a subset of the above, but broken out because it's by |
11090 | /// far the most common case of incompatible pointers. |
11091 | IncompatiblePointerSign, |
11092 | |
11093 | /// CompatiblePointerDiscardsQualifiers - The assignment discards |
11094 | /// c/v/r qualifiers, which we accept as an extension. |
11095 | CompatiblePointerDiscardsQualifiers, |
11096 | |
11097 | /// IncompatiblePointerDiscardsQualifiers - The assignment |
11098 | /// discards qualifiers that we don't permit to be discarded, |
11099 | /// like address spaces. |
11100 | IncompatiblePointerDiscardsQualifiers, |
11101 | |
11102 | /// IncompatibleNestedPointerAddressSpaceMismatch - The assignment |
11103 | /// changes address spaces in nested pointer types which is not allowed. |
11104 | /// For instance, converting __private int ** to __generic int ** is |
11105 | /// illegal even though __private could be converted to __generic. |
11106 | IncompatibleNestedPointerAddressSpaceMismatch, |
11107 | |
11108 | /// IncompatibleNestedPointerQualifiers - The assignment is between two |
11109 | /// nested pointer types, and the qualifiers other than the first two |
11110 | /// levels differ e.g. char ** -> const char **, but we accept them as an |
11111 | /// extension. |
11112 | IncompatibleNestedPointerQualifiers, |
11113 | |
11114 | /// IncompatibleVectors - The assignment is between two vector types that |
11115 | /// have the same size, which we accept as an extension. |
11116 | IncompatibleVectors, |
11117 | |
11118 | /// IntToBlockPointer - The assignment converts an int to a block |
11119 | /// pointer. We disallow this. |
11120 | IntToBlockPointer, |
11121 | |
11122 | /// IncompatibleBlockPointer - The assignment is between two block |
11123 | /// pointers types that are not compatible. |
11124 | IncompatibleBlockPointer, |
11125 | |
11126 | /// IncompatibleObjCQualifiedId - The assignment is between a qualified |
11127 | /// id type and something else (that is incompatible with it). For example, |
11128 | /// "id <XXX>" = "Foo *", where "Foo *" doesn't implement the XXX protocol. |
11129 | IncompatibleObjCQualifiedId, |
11130 | |
11131 | /// IncompatibleObjCWeakRef - Assigning a weak-unavailable object to an |
11132 | /// object with __weak qualifier. |
11133 | IncompatibleObjCWeakRef, |
11134 | |
11135 | /// Incompatible - We reject this conversion outright, it is invalid to |
11136 | /// represent it in the AST. |
11137 | Incompatible |
11138 | }; |
11139 | |
11140 | /// DiagnoseAssignmentResult - Emit a diagnostic, if required, for the |
11141 | /// assignment conversion type specified by ConvTy. This returns true if the |
11142 | /// conversion was invalid or false if the conversion was accepted. |
11143 | bool DiagnoseAssignmentResult(AssignConvertType ConvTy, |
11144 | SourceLocation Loc, |
11145 | QualType DstType, QualType SrcType, |
11146 | Expr *SrcExpr, AssignmentAction Action, |
11147 | bool *Complained = nullptr); |
11148 | |
11149 | /// IsValueInFlagEnum - Determine if a value is allowed as part of a flag |
11150 | /// enum. If AllowMask is true, then we also allow the complement of a valid |
11151 | /// value, to be used as a mask. |
11152 | bool IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val, |
11153 | bool AllowMask) const; |
11154 | |
11155 | /// DiagnoseAssignmentEnum - Warn if assignment to enum is a constant |
11156 | /// integer not in the range of enum values. |
11157 | void DiagnoseAssignmentEnum(QualType DstType, QualType SrcType, |
11158 | Expr *SrcExpr); |
11159 | |
11160 | /// CheckAssignmentConstraints - Perform type checking for assignment, |
11161 | /// argument passing, variable initialization, and function return values. |
11162 | /// C99 6.5.16. |
11163 | AssignConvertType CheckAssignmentConstraints(SourceLocation Loc, |
11164 | QualType LHSType, |
11165 | QualType RHSType); |
11166 | |
11167 | /// Check assignment constraints and optionally prepare for a conversion of |
11168 | /// the RHS to the LHS type. The conversion is prepared for if ConvertRHS |
11169 | /// is true. |
11170 | AssignConvertType CheckAssignmentConstraints(QualType LHSType, |
11171 | ExprResult &RHS, |
11172 | CastKind &Kind, |
11173 | bool ConvertRHS = true); |
11174 | |
11175 | /// Check assignment constraints for an assignment of RHS to LHSType. |
11176 | /// |
11177 | /// \param LHSType The destination type for the assignment. |
11178 | /// \param RHS The source expression for the assignment. |
11179 | /// \param Diagnose If \c true, diagnostics may be produced when checking |
11180 | /// for assignability. If a diagnostic is produced, \p RHS will be |
11181 | /// set to ExprError(). Note that this function may still return |
11182 | /// without producing a diagnostic, even for an invalid assignment. |
11183 | /// \param DiagnoseCFAudited If \c true, the target is a function parameter |
11184 | /// in an audited Core Foundation API and does not need to be checked |
11185 | /// for ARC retain issues. |
11186 | /// \param ConvertRHS If \c true, \p RHS will be updated to model the |
11187 | /// conversions necessary to perform the assignment. If \c false, |
11188 | /// \p Diagnose must also be \c false. |
11189 | AssignConvertType CheckSingleAssignmentConstraints( |
11190 | QualType LHSType, ExprResult &RHS, bool Diagnose = true, |
11191 | bool DiagnoseCFAudited = false, bool ConvertRHS = true); |
11192 | |
11193 | // If the lhs type is a transparent union, check whether we |
11194 | // can initialize the transparent union with the given expression. |
11195 | AssignConvertType CheckTransparentUnionArgumentConstraints(QualType ArgType, |
11196 | ExprResult &RHS); |
11197 | |
11198 | bool IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType); |
11199 | |
11200 | bool CheckExceptionSpecCompatibility(Expr *From, QualType ToType); |
11201 | |
11202 | ExprResult PerformImplicitConversion(Expr *From, QualType ToType, |
11203 | AssignmentAction Action, |
11204 | bool AllowExplicit = false); |
11205 | ExprResult PerformImplicitConversion(Expr *From, QualType ToType, |
11206 | AssignmentAction Action, |
11207 | bool AllowExplicit, |
11208 | ImplicitConversionSequence& ICS); |
11209 | ExprResult PerformImplicitConversion(Expr *From, QualType ToType, |
11210 | const ImplicitConversionSequence& ICS, |
11211 | AssignmentAction Action, |
11212 | CheckedConversionKind CCK |
11213 | = CCK_ImplicitConversion); |
11214 | ExprResult PerformImplicitConversion(Expr *From, QualType ToType, |
11215 | const StandardConversionSequence& SCS, |
11216 | AssignmentAction Action, |
11217 | CheckedConversionKind CCK); |
11218 | |
11219 | ExprResult PerformQualificationConversion( |
11220 | Expr *E, QualType Ty, ExprValueKind VK = VK_RValue, |
11221 | CheckedConversionKind CCK = CCK_ImplicitConversion); |
11222 | |
11223 | /// the following "Check" methods will return a valid/converted QualType |
11224 | /// or a null QualType (indicating an error diagnostic was issued). |
11225 | |
11226 | /// type checking binary operators (subroutines of CreateBuiltinBinOp). |
11227 | QualType InvalidOperands(SourceLocation Loc, ExprResult &LHS, |
11228 | ExprResult &RHS); |
11229 | QualType InvalidLogicalVectorOperands(SourceLocation Loc, ExprResult &LHS, |
11230 | ExprResult &RHS); |
11231 | QualType CheckPointerToMemberOperands( // C++ 5.5 |
11232 | ExprResult &LHS, ExprResult &RHS, ExprValueKind &VK, |
11233 | SourceLocation OpLoc, bool isIndirect); |
11234 | QualType CheckMultiplyDivideOperands( // C99 6.5.5 |
11235 | ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, bool IsCompAssign, |
11236 | bool IsDivide); |
11237 | QualType CheckRemainderOperands( // C99 6.5.5 |
11238 | ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, |
11239 | bool IsCompAssign = false); |
11240 | QualType CheckAdditionOperands( // C99 6.5.6 |
11241 | ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, |
11242 | BinaryOperatorKind Opc, QualType* CompLHSTy = nullptr); |
11243 | QualType CheckSubtractionOperands( // C99 6.5.6 |
11244 | ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, |
11245 | QualType* CompLHSTy = nullptr); |
11246 | QualType CheckShiftOperands( // C99 6.5.7 |
11247 | ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, |
11248 | BinaryOperatorKind Opc, bool IsCompAssign = false); |
11249 | void CheckPtrComparisonWithNullChar(ExprResult &E, ExprResult &NullE); |
11250 | QualType CheckCompareOperands( // C99 6.5.8/9 |
11251 | ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, |
11252 | BinaryOperatorKind Opc); |
11253 | QualType CheckBitwiseOperands( // C99 6.5.[10...12] |
11254 | ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, |
11255 | BinaryOperatorKind Opc); |
11256 | QualType CheckLogicalOperands( // C99 6.5.[13,14] |
11257 | ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, |
11258 | BinaryOperatorKind Opc); |
11259 | // CheckAssignmentOperands is used for both simple and compound assignment. |
11260 | // For simple assignment, pass both expressions and a null converted type. |
11261 | // For compound assignment, pass both expressions and the converted type. |
11262 | QualType CheckAssignmentOperands( // C99 6.5.16.[1,2] |
11263 | Expr *LHSExpr, ExprResult &RHS, SourceLocation Loc, QualType CompoundType); |
11264 | |
11265 | ExprResult checkPseudoObjectIncDec(Scope *S, SourceLocation OpLoc, |
11266 | UnaryOperatorKind Opcode, Expr *Op); |
11267 | ExprResult checkPseudoObjectAssignment(Scope *S, SourceLocation OpLoc, |
11268 | BinaryOperatorKind Opcode, |
11269 | Expr *LHS, Expr *RHS); |
11270 | ExprResult checkPseudoObjectRValue(Expr *E); |
11271 | Expr *recreateSyntacticForm(PseudoObjectExpr *E); |
11272 | |
11273 | QualType CheckConditionalOperands( // C99 6.5.15 |
11274 | ExprResult &Cond, ExprResult &LHS, ExprResult &RHS, |
11275 | ExprValueKind &VK, ExprObjectKind &OK, SourceLocation QuestionLoc); |
11276 | QualType CXXCheckConditionalOperands( // C++ 5.16 |
11277 | ExprResult &cond, ExprResult &lhs, ExprResult &rhs, |
11278 | ExprValueKind &VK, ExprObjectKind &OK, SourceLocation questionLoc); |
11279 | QualType CheckGNUVectorConditionalTypes(ExprResult &Cond, ExprResult &LHS, |
11280 | ExprResult &RHS, |
11281 | SourceLocation QuestionLoc); |
11282 | QualType FindCompositePointerType(SourceLocation Loc, Expr *&E1, Expr *&E2, |
11283 | bool ConvertArgs = true); |
11284 | QualType FindCompositePointerType(SourceLocation Loc, |
11285 | ExprResult &E1, ExprResult &E2, |
11286 | bool ConvertArgs = true) { |
11287 | Expr *E1Tmp = E1.get(), *E2Tmp = E2.get(); |
11288 | QualType Composite = |
11289 | FindCompositePointerType(Loc, E1Tmp, E2Tmp, ConvertArgs); |
11290 | E1 = E1Tmp; |
11291 | E2 = E2Tmp; |
11292 | return Composite; |
11293 | } |
11294 | |
11295 | QualType FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS, |
11296 | SourceLocation QuestionLoc); |
11297 | |
11298 | bool DiagnoseConditionalForNull(Expr *LHSExpr, Expr *RHSExpr, |
11299 | SourceLocation QuestionLoc); |
11300 | |
11301 | void DiagnoseAlwaysNonNullPointer(Expr *E, |
11302 | Expr::NullPointerConstantKind NullType, |
11303 | bool IsEqual, SourceRange Range); |
11304 | |
11305 | /// type checking for vector binary operators. |
11306 | QualType CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, |
11307 | SourceLocation Loc, bool IsCompAssign, |
11308 | bool AllowBothBool, bool AllowBoolConversion); |
11309 | QualType GetSignedVectorType(QualType V); |
11310 | QualType CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS, |
11311 | SourceLocation Loc, |
11312 | BinaryOperatorKind Opc); |
11313 | QualType CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS, |
11314 | SourceLocation Loc); |
11315 | |
11316 | /// Type checking for matrix binary operators. |
11317 | QualType CheckMatrixElementwiseOperands(ExprResult &LHS, ExprResult &RHS, |
11318 | SourceLocation Loc, |
11319 | bool IsCompAssign); |
11320 | QualType CheckMatrixMultiplyOperands(ExprResult &LHS, ExprResult &RHS, |
11321 | SourceLocation Loc, bool IsCompAssign); |
11322 | |
11323 | bool areLaxCompatibleVectorTypes(QualType srcType, QualType destType); |
11324 | bool isLaxVectorConversion(QualType srcType, QualType destType); |
11325 | |
11326 | /// type checking declaration initializers (C99 6.7.8) |
11327 | bool CheckForConstantInitializer(Expr *e, QualType t); |
11328 | |
11329 | // type checking C++ declaration initializers (C++ [dcl.init]). |
11330 | |
11331 | /// ReferenceCompareResult - Expresses the result of comparing two |
11332 | /// types (cv1 T1 and cv2 T2) to determine their compatibility for the |
11333 | /// purposes of initialization by reference (C++ [dcl.init.ref]p4). |
11334 | enum ReferenceCompareResult { |
11335 | /// Ref_Incompatible - The two types are incompatible, so direct |
11336 | /// reference binding is not possible. |
11337 | Ref_Incompatible = 0, |
11338 | /// Ref_Related - The two types are reference-related, which means |
11339 | /// that their unqualified forms (T1 and T2) are either the same |
11340 | /// or T1 is a base class of T2. |
11341 | Ref_Related, |
11342 | /// Ref_Compatible - The two types are reference-compatible. |
11343 | Ref_Compatible |
11344 | }; |
11345 | |
11346 | // Fake up a scoped enumeration that still contextually converts to bool. |
11347 | struct ReferenceConversionsScope { |
11348 | /// The conversions that would be performed on an lvalue of type T2 when |
11349 | /// binding a reference of type T1 to it, as determined when evaluating |
11350 | /// whether T1 is reference-compatible with T2. |
11351 | enum ReferenceConversions { |
11352 | Qualification = 0x1, |
11353 | NestedQualification = 0x2, |
11354 | Function = 0x4, |
11355 | DerivedToBase = 0x8, |
11356 | ObjC = 0x10, |
11357 | ObjCLifetime = 0x20, |
11358 | |
11359 | LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/ObjCLifetime)LLVM_BITMASK_LARGEST_ENUMERATOR = ObjCLifetime |
11360 | }; |
11361 | }; |
11362 | using ReferenceConversions = ReferenceConversionsScope::ReferenceConversions; |
11363 | |
11364 | ReferenceCompareResult |
11365 | CompareReferenceRelationship(SourceLocation Loc, QualType T1, QualType T2, |
11366 | ReferenceConversions *Conv = nullptr); |
11367 | |
11368 | ExprResult checkUnknownAnyCast(SourceRange TypeRange, QualType CastType, |
11369 | Expr *CastExpr, CastKind &CastKind, |
11370 | ExprValueKind &VK, CXXCastPath &Path); |
11371 | |
11372 | /// Force an expression with unknown-type to an expression of the |
11373 | /// given type. |
11374 | ExprResult forceUnknownAnyToType(Expr *E, QualType ToType); |
11375 | |
11376 | /// Type-check an expression that's being passed to an |
11377 | /// __unknown_anytype parameter. |
11378 | ExprResult checkUnknownAnyArg(SourceLocation callLoc, |
11379 | Expr *result, QualType ¶mType); |
11380 | |
11381 | // CheckVectorCast - check type constraints for vectors. |
11382 | // Since vectors are an extension, there are no C standard reference for this. |
11383 | // We allow casting between vectors and integer datatypes of the same size. |
11384 | // returns true if the cast is invalid |
11385 | bool CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty, |
11386 | CastKind &Kind); |
11387 | |
11388 | /// Prepare `SplattedExpr` for a vector splat operation, adding |
11389 | /// implicit casts if necessary. |
11390 | ExprResult prepareVectorSplat(QualType VectorTy, Expr *SplattedExpr); |
11391 | |
11392 | // CheckExtVectorCast - check type constraints for extended vectors. |
11393 | // Since vectors are an extension, there are no C standard reference for this. |
11394 | // We allow casting between vectors and integer datatypes of the same size, |
11395 | // or vectors and the element type of that vector. |
11396 | // returns the cast expr |
11397 | ExprResult CheckExtVectorCast(SourceRange R, QualType DestTy, Expr *CastExpr, |
11398 | CastKind &Kind); |
11399 | |
11400 | ExprResult BuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo, QualType Type, |
11401 | SourceLocation LParenLoc, |
11402 | Expr *CastExpr, |
11403 | SourceLocation RParenLoc); |
11404 | |
11405 | enum ARCConversionResult { ACR_okay, ACR_unbridged, ACR_error }; |
11406 | |
11407 | /// Checks for invalid conversions and casts between |
11408 | /// retainable pointers and other pointer kinds for ARC and Weak. |
11409 | ARCConversionResult CheckObjCConversion(SourceRange castRange, |
11410 | QualType castType, Expr *&op, |
11411 | CheckedConversionKind CCK, |
11412 | bool Diagnose = true, |
11413 | bool DiagnoseCFAudited = false, |
11414 | BinaryOperatorKind Opc = BO_PtrMemD |
11415 | ); |
11416 | |
11417 | Expr *stripARCUnbridgedCast(Expr *e); |
11418 | void diagnoseARCUnbridgedCast(Expr *e); |
11419 | |
11420 | bool CheckObjCARCUnavailableWeakConversion(QualType castType, |
11421 | QualType ExprType); |
11422 | |
11423 | /// checkRetainCycles - Check whether an Objective-C message send |
11424 | /// might create an obvious retain cycle. |
11425 | void checkRetainCycles(ObjCMessageExpr *msg); |
11426 | void checkRetainCycles(Expr *receiver, Expr *argument); |
11427 | void checkRetainCycles(VarDecl *Var, Expr *Init); |
11428 | |
11429 | /// checkUnsafeAssigns - Check whether +1 expr is being assigned |
11430 | /// to weak/__unsafe_unretained type. |
11431 | bool checkUnsafeAssigns(SourceLocation Loc, QualType LHS, Expr *RHS); |
11432 | |
11433 | /// checkUnsafeExprAssigns - Check whether +1 expr is being assigned |
11434 | /// to weak/__unsafe_unretained expression. |
11435 | void checkUnsafeExprAssigns(SourceLocation Loc, Expr *LHS, Expr *RHS); |
11436 | |
11437 | /// CheckMessageArgumentTypes - Check types in an Obj-C message send. |
11438 | /// \param Method - May be null. |
11439 | /// \param [out] ReturnType - The return type of the send. |
11440 | /// \return true iff there were any incompatible types. |
11441 | bool CheckMessageArgumentTypes(const Expr *Receiver, QualType ReceiverType, |
11442 | MultiExprArg Args, Selector Sel, |
11443 | ArrayRef<SourceLocation> SelectorLocs, |
11444 | ObjCMethodDecl *Method, bool isClassMessage, |
11445 | bool isSuperMessage, SourceLocation lbrac, |
11446 | SourceLocation rbrac, SourceRange RecRange, |
11447 | QualType &ReturnType, ExprValueKind &VK); |
11448 | |
11449 | /// Determine the result of a message send expression based on |
11450 | /// the type of the receiver, the method expected to receive the message, |
11451 | /// and the form of the message send. |
11452 | QualType getMessageSendResultType(const Expr *Receiver, QualType ReceiverType, |
11453 | ObjCMethodDecl *Method, bool isClassMessage, |
11454 | bool isSuperMessage); |
11455 | |
11456 | /// If the given expression involves a message send to a method |
11457 | /// with a related result type, emit a note describing what happened. |
11458 | void EmitRelatedResultTypeNote(const Expr *E); |
11459 | |
11460 | /// Given that we had incompatible pointer types in a return |
11461 | /// statement, check whether we're in a method with a related result |
11462 | /// type, and if so, emit a note describing what happened. |
11463 | void EmitRelatedResultTypeNoteForReturn(QualType destType); |
11464 | |
11465 | class ConditionResult { |
11466 | Decl *ConditionVar; |
11467 | FullExprArg Condition; |
11468 | bool Invalid; |
11469 | bool HasKnownValue; |
11470 | bool KnownValue; |
11471 | |
11472 | friend class Sema; |
11473 | ConditionResult(Sema &S, Decl *ConditionVar, FullExprArg Condition, |
11474 | bool IsConstexpr) |
11475 | : ConditionVar(ConditionVar), Condition(Condition), Invalid(false), |
11476 | HasKnownValue(IsConstexpr && Condition.get() && |
11477 | !Condition.get()->isValueDependent()), |
11478 | KnownValue(HasKnownValue && |
11479 | !!Condition.get()->EvaluateKnownConstInt(S.Context)) {} |
11480 | explicit ConditionResult(bool Invalid) |
11481 | : ConditionVar(nullptr), Condition(nullptr), Invalid(Invalid), |
11482 | HasKnownValue(false), KnownValue(false) {} |
11483 | |
11484 | public: |
11485 | ConditionResult() : ConditionResult(false) {} |
11486 | bool isInvalid() const { return Invalid; } |
11487 | std::pair<VarDecl *, Expr *> get() const { |
11488 | return std::make_pair(cast_or_null<VarDecl>(ConditionVar), |
11489 | Condition.get()); |
11490 | } |
11491 | llvm::Optional<bool> getKnownValue() const { |
11492 | if (!HasKnownValue) |
11493 | return None; |
11494 | return KnownValue; |
11495 | } |
11496 | }; |
11497 | static ConditionResult ConditionError() { return ConditionResult(true); } |
11498 | |
11499 | enum class ConditionKind { |
11500 | Boolean, ///< A boolean condition, from 'if', 'while', 'for', or 'do'. |
11501 | ConstexprIf, ///< A constant boolean condition from 'if constexpr'. |
11502 | Switch ///< An integral condition for a 'switch' statement. |
11503 | }; |
11504 | |
11505 | ConditionResult ActOnCondition(Scope *S, SourceLocation Loc, |
11506 | Expr *SubExpr, ConditionKind CK); |
11507 | |
11508 | ConditionResult ActOnConditionVariable(Decl *ConditionVar, |
11509 | SourceLocation StmtLoc, |
11510 | ConditionKind CK); |
11511 | |
11512 | DeclResult ActOnCXXConditionDeclaration(Scope *S, Declarator &D); |
11513 | |
11514 | ExprResult CheckConditionVariable(VarDecl *ConditionVar, |
11515 | SourceLocation StmtLoc, |
11516 | ConditionKind CK); |
11517 | ExprResult CheckSwitchCondition(SourceLocation SwitchLoc, Expr *Cond); |
11518 | |
11519 | /// CheckBooleanCondition - Diagnose problems involving the use of |
11520 | /// the given expression as a boolean condition (e.g. in an if |
11521 | /// statement). Also performs the standard function and array |
11522 | /// decays, possibly changing the input variable. |
11523 | /// |
11524 | /// \param Loc - A location associated with the condition, e.g. the |
11525 | /// 'if' keyword. |
11526 | /// \return true iff there were any errors |
11527 | ExprResult CheckBooleanCondition(SourceLocation Loc, Expr *E, |
11528 | bool IsConstexpr = false); |
11529 | |
11530 | /// ActOnExplicitBoolSpecifier - Build an ExplicitSpecifier from an expression |
11531 | /// found in an explicit(bool) specifier. |
11532 | ExplicitSpecifier ActOnExplicitBoolSpecifier(Expr *E); |
11533 | |
11534 | /// tryResolveExplicitSpecifier - Attempt to resolve the explict specifier. |
11535 | /// Returns true if the explicit specifier is now resolved. |
11536 | bool tryResolveExplicitSpecifier(ExplicitSpecifier &ExplicitSpec); |
11537 | |
11538 | /// DiagnoseAssignmentAsCondition - Given that an expression is |
11539 | /// being used as a boolean condition, warn if it's an assignment. |
11540 | void DiagnoseAssignmentAsCondition(Expr *E); |
11541 | |
11542 | /// Redundant parentheses over an equality comparison can indicate |
11543 | /// that the user intended an assignment used as condition. |
11544 | void DiagnoseEqualityWithExtraParens(ParenExpr *ParenE); |
11545 | |
11546 | /// CheckCXXBooleanCondition - Returns true if conversion to bool is invalid. |
11547 | ExprResult CheckCXXBooleanCondition(Expr *CondExpr, bool IsConstexpr = false); |
11548 | |
11549 | /// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have |
11550 | /// the specified width and sign. If an overflow occurs, detect it and emit |
11551 | /// the specified diagnostic. |
11552 | void ConvertIntegerToTypeWarnOnOverflow(llvm::APSInt &OldVal, |
11553 | unsigned NewWidth, bool NewSign, |
11554 | SourceLocation Loc, unsigned DiagID); |
11555 | |
11556 | /// Checks that the Objective-C declaration is declared in the global scope. |
11557 | /// Emits an error and marks the declaration as invalid if it's not declared |
11558 | /// in the global scope. |
11559 | bool CheckObjCDeclScope(Decl *D); |
11560 | |
11561 | /// Abstract base class used for diagnosing integer constant |
11562 | /// expression violations. |
11563 | class VerifyICEDiagnoser { |
11564 | public: |
11565 | bool Suppress; |
11566 | |
11567 | VerifyICEDiagnoser(bool Suppress = false) : Suppress(Suppress) { } |
11568 | |
11569 | virtual void diagnoseNotICE(Sema &S, SourceLocation Loc, SourceRange SR) =0; |
11570 | virtual void diagnoseFold(Sema &S, SourceLocation Loc, SourceRange SR); |
11571 | virtual ~VerifyICEDiagnoser() { } |
11572 | }; |
11573 | |
11574 | /// VerifyIntegerConstantExpression - Verifies that an expression is an ICE, |
11575 | /// and reports the appropriate diagnostics. Returns false on success. |
11576 | /// Can optionally return the value of the expression. |
11577 | ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, |
11578 | VerifyICEDiagnoser &Diagnoser, |
11579 | bool AllowFold = true); |
11580 | ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, |
11581 | unsigned DiagID, |
11582 | bool AllowFold = true); |
11583 | ExprResult VerifyIntegerConstantExpression(Expr *E, |
11584 | llvm::APSInt *Result = nullptr); |
11585 | |
11586 | /// VerifyBitField - verifies that a bit field expression is an ICE and has |
11587 | /// the correct width, and that the field type is valid. |
11588 | /// Returns false on success. |
11589 | /// Can optionally return whether the bit-field is of width 0 |
11590 | ExprResult VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName, |
11591 | QualType FieldTy, bool IsMsStruct, |
11592 | Expr *BitWidth, bool *ZeroWidth = nullptr); |
11593 | |
11594 | private: |
11595 | unsigned ForceCUDAHostDeviceDepth = 0; |
11596 | |
11597 | public: |
11598 | /// Increments our count of the number of times we've seen a pragma forcing |
11599 | /// functions to be __host__ __device__. So long as this count is greater |
11600 | /// than zero, all functions encountered will be __host__ __device__. |
11601 | void PushForceCUDAHostDevice(); |
11602 | |
11603 | /// Decrements our count of the number of times we've seen a pragma forcing |
11604 | /// functions to be __host__ __device__. Returns false if the count is 0 |
11605 | /// before incrementing, so you can emit an error. |
11606 | bool PopForceCUDAHostDevice(); |
11607 | |
11608 | /// Diagnostics that are emitted only if we discover that the given function |
11609 | /// must be codegen'ed. Because handling these correctly adds overhead to |
11610 | /// compilation, this is currently only enabled for CUDA compilations. |
11611 | llvm::DenseMap<CanonicalDeclPtr<FunctionDecl>, |
11612 | std::vector<PartialDiagnosticAt>> |
11613 | DeviceDeferredDiags; |
11614 | |
11615 | /// A pair of a canonical FunctionDecl and a SourceLocation. When used as the |
11616 | /// key in a hashtable, both the FD and location are hashed. |
11617 | struct FunctionDeclAndLoc { |
11618 | CanonicalDeclPtr<FunctionDecl> FD; |
11619 | SourceLocation Loc; |
11620 | }; |
11621 | |
11622 | /// FunctionDecls and SourceLocations for which CheckCUDACall has emitted a |
11623 | /// (maybe deferred) "bad call" diagnostic. We use this to avoid emitting the |
11624 | /// same deferred diag twice. |
11625 | llvm::DenseSet<FunctionDeclAndLoc> LocsWithCUDACallDiags; |
11626 | |
11627 | /// An inverse call graph, mapping known-emitted functions to one of their |
11628 | /// known-emitted callers (plus the location of the call). |
11629 | /// |
11630 | /// Functions that we can tell a priori must be emitted aren't added to this |
11631 | /// map. |
11632 | llvm::DenseMap</* Callee = */ CanonicalDeclPtr<FunctionDecl>, |
11633 | /* Caller = */ FunctionDeclAndLoc> |
11634 | DeviceKnownEmittedFns; |
11635 | |
11636 | /// Diagnostic builder for CUDA/OpenMP devices errors which may or may not be |
11637 | /// deferred. |
11638 | /// |
11639 | /// In CUDA, there exist constructs (e.g. variable-length arrays, try/catch) |
11640 | /// which are not allowed to appear inside __device__ functions and are |
11641 | /// allowed to appear in __host__ __device__ functions only if the host+device |
11642 | /// function is never codegen'ed. |
11643 | /// |
11644 | /// To handle this, we use the notion of "deferred diagnostics", where we |
11645 | /// attach a diagnostic to a FunctionDecl that's emitted iff it's codegen'ed. |
11646 | /// |
11647 | /// This class lets you emit either a regular diagnostic, a deferred |
11648 | /// diagnostic, or no diagnostic at all, according to an argument you pass to |
11649 | /// its constructor, thus simplifying the process of creating these "maybe |
11650 | /// deferred" diagnostics. |
11651 | class DeviceDiagBuilder { |
11652 | public: |
11653 | enum Kind { |
11654 | /// Emit no diagnostics. |
11655 | K_Nop, |
11656 | /// Emit the diagnostic immediately (i.e., behave like Sema::Diag()). |
11657 | K_Immediate, |
11658 | /// Emit the diagnostic immediately, and, if it's a warning or error, also |
11659 | /// emit a call stack showing how this function can be reached by an a |
11660 | /// priori known-emitted function. |
11661 | K_ImmediateWithCallStack, |
11662 | /// Create a deferred diagnostic, which is emitted only if the function |
11663 | /// it's attached to is codegen'ed. Also emit a call stack as with |
11664 | /// K_ImmediateWithCallStack. |
11665 | K_Deferred |
11666 | }; |
11667 | |
11668 | DeviceDiagBuilder(Kind K, SourceLocation Loc, unsigned DiagID, |
11669 | FunctionDecl *Fn, Sema &S); |
11670 | DeviceDiagBuilder(DeviceDiagBuilder &&D); |
11671 | DeviceDiagBuilder(const DeviceDiagBuilder &) = default; |
11672 | ~DeviceDiagBuilder(); |
11673 | |
11674 | /// Convertible to bool: True if we immediately emitted an error, false if |
11675 | /// we didn't emit an error or we created a deferred error. |
11676 | /// |
11677 | /// Example usage: |
11678 | /// |
11679 | /// if (DeviceDiagBuilder(...) << foo << bar) |
11680 | /// return ExprError(); |
11681 | /// |
11682 | /// But see CUDADiagIfDeviceCode() and CUDADiagIfHostCode() -- you probably |
11683 | /// want to use these instead of creating a DeviceDiagBuilder yourself. |
11684 | operator bool() const { return ImmediateDiag.hasValue(); } |
11685 | |
11686 | template <typename T> |
11687 | friend const DeviceDiagBuilder &operator<<(const DeviceDiagBuilder &Diag, |
11688 | const T &Value) { |
11689 | if (Diag.ImmediateDiag.hasValue()) |
11690 | *Diag.ImmediateDiag << Value; |
11691 | else if (Diag.PartialDiagId.hasValue()) |
11692 | Diag.S.DeviceDeferredDiags[Diag.Fn][*Diag.PartialDiagId].second |
11693 | << Value; |
11694 | return Diag; |
11695 | } |
11696 | |
11697 | private: |
11698 | Sema &S; |
11699 | SourceLocation Loc; |
11700 | unsigned DiagID; |
11701 | FunctionDecl *Fn; |
11702 | bool ShowCallStack; |
11703 | |
11704 | // Invariant: At most one of these Optionals has a value. |
11705 | // FIXME: Switch these to a Variant once that exists. |
11706 | llvm::Optional<SemaDiagnosticBuilder> ImmediateDiag; |
11707 | llvm::Optional<unsigned> PartialDiagId; |
11708 | }; |
11709 | |
11710 | /// Creates a DeviceDiagBuilder that emits the diagnostic if the current context |
11711 | /// is "used as device code". |
11712 | /// |
11713 | /// - If CurContext is a __host__ function, does not emit any diagnostics. |
11714 | /// - If CurContext is a __device__ or __global__ function, emits the |
11715 | /// diagnostics immediately. |
11716 | /// - If CurContext is a __host__ __device__ function and we are compiling for |
11717 | /// the device, creates a diagnostic which is emitted if and when we realize |
11718 | /// that the function will be codegen'ed. |
11719 | /// |
11720 | /// Example usage: |
11721 | /// |
11722 | /// // Variable-length arrays are not allowed in CUDA device code. |
11723 | /// if (CUDADiagIfDeviceCode(Loc, diag::err_cuda_vla) << CurrentCUDATarget()) |
11724 | /// return ExprError(); |
11725 | /// // Otherwise, continue parsing as normal. |
11726 | DeviceDiagBuilder CUDADiagIfDeviceCode(SourceLocation Loc, unsigned DiagID); |
11727 | |
11728 | /// Creates a DeviceDiagBuilder that emits the diagnostic if the current context |
11729 | /// is "used as host code". |
11730 | /// |
11731 | /// Same as CUDADiagIfDeviceCode, with "host" and "device" switched. |
11732 | DeviceDiagBuilder CUDADiagIfHostCode(SourceLocation Loc, unsigned DiagID); |
11733 | |
11734 | /// Creates a DeviceDiagBuilder that emits the diagnostic if the current |
11735 | /// context is "used as device code". |
11736 | /// |
11737 | /// - If CurContext is a `declare target` function or it is known that the |
11738 | /// function is emitted for the device, emits the diagnostics immediately. |
11739 | /// - If CurContext is a non-`declare target` function and we are compiling |
11740 | /// for the device, creates a diagnostic which is emitted if and when we |
11741 | /// realize that the function will be codegen'ed. |
11742 | /// |
11743 | /// Example usage: |
11744 | /// |
11745 | /// // Variable-length arrays are not allowed in NVPTX device code. |
11746 | /// if (diagIfOpenMPDeviceCode(Loc, diag::err_vla_unsupported)) |
11747 | /// return ExprError(); |
11748 | /// // Otherwise, continue parsing as normal. |
11749 | DeviceDiagBuilder diagIfOpenMPDeviceCode(SourceLocation Loc, unsigned DiagID); |
11750 | |
11751 | /// Creates a DeviceDiagBuilder that emits the diagnostic if the current |
11752 | /// context is "used as host code". |
11753 | /// |
11754 | /// - If CurContext is a `declare target` function or it is known that the |
11755 | /// function is emitted for the host, emits the diagnostics immediately. |
11756 | /// - If CurContext is a non-host function, just ignore it. |
11757 | /// |
11758 | /// Example usage: |
11759 | /// |
11760 | /// // Variable-length arrays are not allowed in NVPTX device code. |
11761 | /// if (diagIfOpenMPHostode(Loc, diag::err_vla_unsupported)) |
11762 | /// return ExprError(); |
11763 | /// // Otherwise, continue parsing as normal. |
11764 | DeviceDiagBuilder diagIfOpenMPHostCode(SourceLocation Loc, unsigned DiagID); |
11765 | |
11766 | DeviceDiagBuilder targetDiag(SourceLocation Loc, unsigned DiagID); |
11767 | |
11768 | /// Check if the expression is allowed to be used in expressions for the |
11769 | /// offloading devices. |
11770 | void checkDeviceDecl(const ValueDecl *D, SourceLocation Loc); |
11771 | |
11772 | enum CUDAFunctionTarget { |
11773 | CFT_Device, |
11774 | CFT_Global, |
11775 | CFT_Host, |
11776 | CFT_HostDevice, |
11777 | CFT_InvalidTarget |
11778 | }; |
11779 | |
11780 | /// Determines whether the given function is a CUDA device/host/kernel/etc. |
11781 | /// function. |
11782 | /// |
11783 | /// Use this rather than examining the function's attributes yourself -- you |
11784 | /// will get it wrong. Returns CFT_Host if D is null. |
11785 | CUDAFunctionTarget IdentifyCUDATarget(const FunctionDecl *D, |
11786 | bool IgnoreImplicitHDAttr = false); |
11787 | CUDAFunctionTarget IdentifyCUDATarget(const ParsedAttributesView &Attrs); |
11788 | |
11789 | /// Gets the CUDA target for the current context. |
11790 | CUDAFunctionTarget CurrentCUDATarget() { |
11791 | return IdentifyCUDATarget(dyn_cast<FunctionDecl>(CurContext)); |
11792 | } |
11793 | |
11794 | static bool isCUDAImplicitHostDeviceFunction(const FunctionDecl *D); |
11795 | |
11796 | // CUDA function call preference. Must be ordered numerically from |
11797 | // worst to best. |
11798 | enum CUDAFunctionPreference { |
11799 | CFP_Never, // Invalid caller/callee combination. |
11800 | CFP_WrongSide, // Calls from host-device to host or device |
11801 | // function that do not match current compilation |
11802 | // mode. |
11803 | CFP_HostDevice, // Any calls to host/device functions. |
11804 | CFP_SameSide, // Calls from host-device to host or device |
11805 | // function matching current compilation mode. |
11806 | CFP_Native, // host-to-host or device-to-device calls. |
11807 | }; |
11808 | |
11809 | /// Identifies relative preference of a given Caller/Callee |
11810 | /// combination, based on their host/device attributes. |
11811 | /// \param Caller function which needs address of \p Callee. |
11812 | /// nullptr in case of global context. |
11813 | /// \param Callee target function |
11814 | /// |
11815 | /// \returns preference value for particular Caller/Callee combination. |
11816 | CUDAFunctionPreference IdentifyCUDAPreference(const FunctionDecl *Caller, |
11817 | const FunctionDecl *Callee); |
11818 | |
11819 | /// Determines whether Caller may invoke Callee, based on their CUDA |
11820 | /// host/device attributes. Returns false if the call is not allowed. |
11821 | /// |
11822 | /// Note: Will return true for CFP_WrongSide calls. These may appear in |
11823 | /// semantically correct CUDA programs, but only if they're never codegen'ed. |
11824 | bool IsAllowedCUDACall(const FunctionDecl *Caller, |
11825 | const FunctionDecl *Callee) { |
11826 | return IdentifyCUDAPreference(Caller, Callee) != CFP_Never; |
11827 | } |
11828 | |
11829 | /// May add implicit CUDAHostAttr and CUDADeviceAttr attributes to FD, |
11830 | /// depending on FD and the current compilation settings. |
11831 | void maybeAddCUDAHostDeviceAttrs(FunctionDecl *FD, |
11832 | const LookupResult &Previous); |
11833 | |
11834 | /// May add implicit CUDAConstantAttr attribute to VD, depending on VD |
11835 | /// and current compilation settings. |
11836 | void MaybeAddCUDAConstantAttr(VarDecl *VD); |
11837 | |
11838 | public: |
11839 | /// Check whether we're allowed to call Callee from the current context. |
11840 | /// |
11841 | /// - If the call is never allowed in a semantically-correct program |
11842 | /// (CFP_Never), emits an error and returns false. |
11843 | /// |
11844 | /// - If the call is allowed in semantically-correct programs, but only if |
11845 | /// it's never codegen'ed (CFP_WrongSide), creates a deferred diagnostic to |
11846 | /// be emitted if and when the caller is codegen'ed, and returns true. |
11847 | /// |
11848 | /// Will only create deferred diagnostics for a given SourceLocation once, |
11849 | /// so you can safely call this multiple times without generating duplicate |
11850 | /// deferred errors. |
11851 | /// |
11852 | /// - Otherwise, returns true without emitting any diagnostics. |
11853 | bool CheckCUDACall(SourceLocation Loc, FunctionDecl *Callee); |
11854 | |
11855 | void CUDACheckLambdaCapture(CXXMethodDecl *D, const sema::Capture &Capture); |
11856 | |
11857 | /// Set __device__ or __host__ __device__ attributes on the given lambda |
11858 | /// operator() method. |
11859 | /// |
11860 | /// CUDA lambdas by default is host device function unless it has explicit |
11861 | /// host or device attribute. |
11862 | void CUDASetLambdaAttrs(CXXMethodDecl *Method); |
11863 | |
11864 | /// Finds a function in \p Matches with highest calling priority |
11865 | /// from \p Caller context and erases all functions with lower |
11866 | /// calling priority. |
11867 | void EraseUnwantedCUDAMatches( |
11868 | const FunctionDecl *Caller, |
11869 | SmallVectorImpl<std::pair<DeclAccessPair, FunctionDecl *>> &Matches); |
11870 | |
11871 | /// Given a implicit special member, infer its CUDA target from the |
11872 | /// calls it needs to make to underlying base/field special members. |
11873 | /// \param ClassDecl the class for which the member is being created. |
11874 | /// \param CSM the kind of special member. |
11875 | /// \param MemberDecl the special member itself. |
11876 | /// \param ConstRHS true if this is a copy operation with a const object on |
11877 | /// its RHS. |
11878 | /// \param Diagnose true if this call should emit diagnostics. |
11879 | /// \return true if there was an error inferring. |
11880 | /// The result of this call is implicit CUDA target attribute(s) attached to |
11881 | /// the member declaration. |
11882 | bool inferCUDATargetForImplicitSpecialMember(CXXRecordDecl *ClassDecl, |
11883 | CXXSpecialMember CSM, |
11884 | CXXMethodDecl *MemberDecl, |
11885 | bool ConstRHS, |
11886 | bool Diagnose); |
11887 | |
11888 | /// \return true if \p CD can be considered empty according to CUDA |
11889 | /// (E.2.3.1 in CUDA 7.5 Programming guide). |
11890 | bool isEmptyCudaConstructor(SourceLocation Loc, CXXConstructorDecl *CD); |
11891 | bool isEmptyCudaDestructor(SourceLocation Loc, CXXDestructorDecl *CD); |
11892 | |
11893 | // \brief Checks that initializers of \p Var satisfy CUDA restrictions. In |
11894 | // case of error emits appropriate diagnostic and invalidates \p Var. |
11895 | // |
11896 | // \details CUDA allows only empty constructors as initializers for global |
11897 | // variables (see E.2.3.1, CUDA 7.5). The same restriction also applies to all |
11898 | // __shared__ variables whether they are local or not (they all are implicitly |
11899 | // static in CUDA). One exception is that CUDA allows constant initializers |
11900 | // for __constant__ and __device__ variables. |
11901 | void checkAllowedCUDAInitializer(VarDecl *VD); |
11902 | |
11903 | /// Check whether NewFD is a valid overload for CUDA. Emits |
11904 | /// diagnostics and invalidates NewFD if not. |
11905 | void checkCUDATargetOverload(FunctionDecl *NewFD, |
11906 | const LookupResult &Previous); |
11907 | /// Copies target attributes from the template TD to the function FD. |
11908 | void inheritCUDATargetAttrs(FunctionDecl *FD, const FunctionTemplateDecl &TD); |
11909 | |
11910 | /// Returns the name of the launch configuration function. This is the name |
11911 | /// of the function that will be called to configure kernel call, with the |
11912 | /// parameters specified via <<<>>>. |
11913 | std::string getCudaConfigureFuncName() const; |
11914 | |
11915 | /// \name Code completion |
11916 | //@{ |
11917 | /// Describes the context in which code completion occurs. |
11918 | enum ParserCompletionContext { |
11919 | /// Code completion occurs at top-level or namespace context. |
11920 | PCC_Namespace, |
11921 | /// Code completion occurs within a class, struct, or union. |
11922 | PCC_Class, |
11923 | /// Code completion occurs within an Objective-C interface, protocol, |
11924 | /// or category. |
11925 | PCC_ObjCInterface, |
11926 | /// Code completion occurs within an Objective-C implementation or |
11927 | /// category implementation |
11928 | PCC_ObjCImplementation, |
11929 | /// Code completion occurs within the list of instance variables |
11930 | /// in an Objective-C interface, protocol, category, or implementation. |
11931 | PCC_ObjCInstanceVariableList, |
11932 | /// Code completion occurs following one or more template |
11933 | /// headers. |
11934 | PCC_Template, |
11935 | /// Code completion occurs following one or more template |
11936 | /// headers within a class. |
11937 | PCC_MemberTemplate, |
11938 | /// Code completion occurs within an expression. |
11939 | PCC_Expression, |
11940 | /// Code completion occurs within a statement, which may |
11941 | /// also be an expression or a declaration. |
11942 | PCC_Statement, |
11943 | /// Code completion occurs at the beginning of the |
11944 | /// initialization statement (or expression) in a for loop. |
11945 | PCC_ForInit, |
11946 | /// Code completion occurs within the condition of an if, |
11947 | /// while, switch, or for statement. |
11948 | PCC_Condition, |
11949 | /// Code completion occurs within the body of a function on a |
11950 | /// recovery path, where we do not have a specific handle on our position |
11951 | /// in the grammar. |
11952 | PCC_RecoveryInFunction, |
11953 | /// Code completion occurs where only a type is permitted. |
11954 | PCC_Type, |
11955 | /// Code completion occurs in a parenthesized expression, which |
11956 | /// might also be a type cast. |
11957 | PCC_ParenthesizedExpression, |
11958 | /// Code completion occurs within a sequence of declaration |
11959 | /// specifiers within a function, method, or block. |
11960 | PCC_LocalDeclarationSpecifiers |
11961 | }; |
11962 | |
11963 | void CodeCompleteModuleImport(SourceLocation ImportLoc, ModuleIdPath Path); |
11964 | void CodeCompleteOrdinaryName(Scope *S, |
11965 | ParserCompletionContext CompletionContext); |
11966 | void CodeCompleteDeclSpec(Scope *S, DeclSpec &DS, |
11967 | bool AllowNonIdentifiers, |
11968 | bool AllowNestedNameSpecifiers); |
11969 | |
11970 | struct CodeCompleteExpressionData; |
11971 | void CodeCompleteExpression(Scope *S, |
11972 | const CodeCompleteExpressionData &Data); |
11973 | void CodeCompleteExpression(Scope *S, QualType PreferredType, |
11974 | bool IsParenthesized = false); |
11975 | void CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, Expr *OtherOpBase, |
11976 | SourceLocation OpLoc, bool IsArrow, |
11977 | bool IsBaseExprStatement, |
11978 | QualType PreferredType); |
11979 | void CodeCompletePostfixExpression(Scope *S, ExprResult LHS, |
11980 | QualType PreferredType); |
11981 | void CodeCompleteTag(Scope *S, unsigned TagSpec); |
11982 | void CodeCompleteTypeQualifiers(DeclSpec &DS); |
11983 | void CodeCompleteFunctionQualifiers(DeclSpec &DS, Declarator &D, |
11984 | const VirtSpecifiers *VS = nullptr); |
11985 | void CodeCompleteBracketDeclarator(Scope *S); |
11986 | void CodeCompleteCase(Scope *S); |
11987 | /// Reports signatures for a call to CodeCompleteConsumer and returns the |
11988 | /// preferred type for the current argument. Returned type can be null. |
11989 | QualType ProduceCallSignatureHelp(Scope *S, Expr *Fn, ArrayRef<Expr *> Args, |
11990 | SourceLocation OpenParLoc); |
11991 | QualType ProduceConstructorSignatureHelp(Scope *S, QualType Type, |
11992 | SourceLocation Loc, |
11993 | ArrayRef<Expr *> Args, |
11994 | SourceLocation OpenParLoc); |
11995 | QualType ProduceCtorInitMemberSignatureHelp(Scope *S, Decl *ConstructorDecl, |
11996 | CXXScopeSpec SS, |
11997 | ParsedType TemplateTypeTy, |
11998 | ArrayRef<Expr *> ArgExprs, |
11999 | IdentifierInfo *II, |
12000 | SourceLocation OpenParLoc); |
12001 | void CodeCompleteInitializer(Scope *S, Decl *D); |
12002 | /// Trigger code completion for a record of \p BaseType. \p InitExprs are |
12003 | /// expressions in the initializer list seen so far and \p D is the current |
12004 | /// Designation being parsed. |
12005 | void CodeCompleteDesignator(const QualType BaseType, |
12006 | llvm::ArrayRef<Expr *> InitExprs, |
12007 | const Designation &D); |
12008 | void CodeCompleteAfterIf(Scope *S, bool IsBracedThen); |
12009 | |
12010 | void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, bool EnteringContext, |
12011 | bool IsUsingDeclaration, QualType BaseType, |
12012 | QualType PreferredType); |
12013 | void CodeCompleteUsing(Scope *S); |
12014 | void CodeCompleteUsingDirective(Scope *S); |
12015 | void CodeCompleteNamespaceDecl(Scope *S); |
12016 | void CodeCompleteNamespaceAliasDecl(Scope *S); |
12017 | void CodeCompleteOperatorName(Scope *S); |
12018 | void CodeCompleteConstructorInitializer( |
12019 | Decl *Constructor, |
12020 | ArrayRef<CXXCtorInitializer *> Initializers); |
12021 | |
12022 | void CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro, |
12023 | bool AfterAmpersand); |
12024 | void CodeCompleteAfterFunctionEquals(Declarator &D); |
12025 | |
12026 | void CodeCompleteObjCAtDirective(Scope *S); |
12027 | void CodeCompleteObjCAtVisibility(Scope *S); |
12028 | void CodeCompleteObjCAtStatement(Scope *S); |
12029 | void CodeCompleteObjCAtExpression(Scope *S); |
12030 | void CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS); |
12031 | void CodeCompleteObjCPropertyGetter(Scope *S); |
12032 | void CodeCompleteObjCPropertySetter(Scope *S); |
12033 | void CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS, |
12034 | bool IsParameter); |
12035 | void CodeCompleteObjCMessageReceiver(Scope *S); |
12036 | void CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc, |
12037 | ArrayRef<IdentifierInfo *> SelIdents, |
12038 | bool AtArgumentExpression); |
12039 | void CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver, |
12040 | ArrayRef<IdentifierInfo *> SelIdents, |
12041 | bool AtArgumentExpression, |
12042 | bool IsSuper = false); |
12043 | void CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver, |
12044 | ArrayRef<IdentifierInfo *> SelIdents, |
12045 | bool AtArgumentExpression, |
12046 | ObjCInterfaceDecl *Super = nullptr); |
12047 | void CodeCompleteObjCForCollection(Scope *S, |
12048 | DeclGroupPtrTy IterationVar); |
12049 | void CodeCompleteObjCSelector(Scope *S, |
12050 | ArrayRef<IdentifierInfo *> SelIdents); |
12051 | void CodeCompleteObjCProtocolReferences( |
12052 | ArrayRef<IdentifierLocPair> Protocols); |
12053 | void CodeCompleteObjCProtocolDecl(Scope *S); |
12054 | void CodeCompleteObjCInterfaceDecl(Scope *S); |
12055 | void CodeCompleteObjCSuperclass(Scope *S, |
12056 | IdentifierInfo *ClassName, |
12057 | SourceLocation ClassNameLoc); |
12058 | void CodeCompleteObjCImplementationDecl(Scope *S); |
12059 | void CodeCompleteObjCInterfaceCategory(Scope *S, |
12060 | IdentifierInfo *ClassName, |
12061 | SourceLocation ClassNameLoc); |
12062 | void CodeCompleteObjCImplementationCategory(Scope *S, |
12063 | IdentifierInfo *ClassName, |
12064 | SourceLocation ClassNameLoc); |
12065 | void CodeCompleteObjCPropertyDefinition(Scope *S); |
12066 | void CodeCompleteObjCPropertySynthesizeIvar(Scope *S, |
12067 | IdentifierInfo *PropertyName); |
12068 | void CodeCompleteObjCMethodDecl(Scope *S, Optional<bool> IsInstanceMethod, |
12069 | ParsedType ReturnType); |
12070 | void CodeCompleteObjCMethodDeclSelector(Scope *S, |
12071 | bool IsInstanceMethod, |
12072 | bool AtParameterName, |
12073 | ParsedType ReturnType, |
12074 | ArrayRef<IdentifierInfo *> SelIdents); |
12075 | void CodeCompleteObjCClassPropertyRefExpr(Scope *S, IdentifierInfo &ClassName, |
12076 | SourceLocation ClassNameLoc, |
12077 | bool IsBaseExprStatement); |
12078 | void CodeCompletePreprocessorDirective(bool InConditional); |
12079 | void CodeCompleteInPreprocessorConditionalExclusion(Scope *S); |
12080 | void CodeCompletePreprocessorMacroName(bool IsDefinition); |
12081 | void CodeCompletePreprocessorExpression(); |
12082 | void CodeCompletePreprocessorMacroArgument(Scope *S, |
12083 | IdentifierInfo *Macro, |
12084 | MacroInfo *MacroInfo, |
12085 | unsigned Argument); |
12086 | void CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled); |
12087 | void CodeCompleteNaturalLanguage(); |
12088 | void CodeCompleteAvailabilityPlatformName(); |
12089 | void GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator, |
12090 | CodeCompletionTUInfo &CCTUInfo, |
12091 | SmallVectorImpl<CodeCompletionResult> &Results); |
12092 | //@} |
12093 | |
12094 | //===--------------------------------------------------------------------===// |
12095 | // Extra semantic analysis beyond the C type system |
12096 | |
12097 | public: |
12098 | SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL, |
12099 | unsigned ByteNo) const; |
12100 | |
12101 | private: |
12102 | void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr, |
12103 | const ArraySubscriptExpr *ASE=nullptr, |
12104 | bool AllowOnePastEnd=true, bool IndexNegated=false); |
12105 | void CheckArrayAccess(const Expr *E); |
12106 | // Used to grab the relevant information from a FormatAttr and a |
12107 | // FunctionDeclaration. |
12108 | struct FormatStringInfo { |
12109 | unsigned FormatIdx; |
12110 | unsigned FirstDataArg; |
12111 | bool HasVAListArg; |
12112 | }; |
12113 | |
12114 | static bool getFormatStringInfo(const FormatAttr *Format, bool IsCXXMember, |
12115 | FormatStringInfo *FSI); |
12116 | bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, |
12117 | const FunctionProtoType *Proto); |
12118 | bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc, |
12119 | ArrayRef<const Expr *> Args); |
12120 | bool CheckPointerCall(NamedDecl *NDecl, CallExpr *TheCall, |
12121 | const FunctionProtoType *Proto); |
12122 | bool CheckOtherCall(CallExpr *TheCall, const FunctionProtoType *Proto); |
12123 | void CheckConstructorCall(FunctionDecl *FDecl, |
12124 | ArrayRef<const Expr *> Args, |
12125 | const FunctionProtoType *Proto, |
12126 | SourceLocation Loc); |
12127 | |
12128 | void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, |
12129 | const Expr *ThisArg, ArrayRef<const Expr *> Args, |
12130 | bool IsMemberFunction, SourceLocation Loc, SourceRange Range, |
12131 | VariadicCallType CallType); |
12132 | |
12133 | bool CheckObjCString(Expr *Arg); |
12134 | ExprResult CheckOSLogFormatStringArg(Expr *Arg); |
12135 | |
12136 | ExprResult CheckBuiltinFunctionCall(FunctionDecl *FDecl, |
12137 | unsigned BuiltinID, CallExpr *TheCall); |
12138 | |
12139 | bool CheckTSBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, |
12140 | CallExpr *TheCall); |
12141 | |
12142 | void checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, CallExpr *TheCall); |
12143 | |
12144 | bool CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall, |
12145 | unsigned MaxWidth); |
12146 | bool CheckNeonBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, |
12147 | CallExpr *TheCall); |
12148 | bool CheckMVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); |
12149 | bool CheckSVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); |
12150 | bool CheckCDEBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, |
12151 | CallExpr *TheCall); |
12152 | bool CheckARMCoprocessorImmediate(const TargetInfo &TI, const Expr *CoprocArg, |
12153 | bool WantCDE); |
12154 | bool CheckARMBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, |
12155 | CallExpr *TheCall); |
12156 | |
12157 | bool CheckAArch64BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, |
12158 | CallExpr *TheCall); |
12159 | bool CheckBPFBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); |
12160 | bool CheckHexagonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); |
12161 | bool CheckHexagonBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall); |
12162 | bool CheckMipsBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, |
12163 | CallExpr *TheCall); |
12164 | bool CheckMipsBuiltinCpu(const TargetInfo &TI, unsigned BuiltinID, |
12165 | CallExpr *TheCall); |
12166 | bool CheckMipsBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall); |
12167 | bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); |
12168 | bool CheckX86BuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall); |
12169 | bool CheckX86BuiltinGatherScatterScale(unsigned BuiltinID, CallExpr *TheCall); |
12170 | bool CheckX86BuiltinTileArguments(unsigned BuiltinID, CallExpr *TheCall); |
12171 | bool CheckX86BuiltinTileArgumentsRange(CallExpr *TheCall, |
12172 | ArrayRef<int> ArgNums); |
12173 | bool CheckX86BuiltinTileArgumentsRange(CallExpr *TheCall, int ArgNum); |
12174 | bool CheckX86BuiltinTileDuplicate(CallExpr *TheCall, ArrayRef<int> ArgNums); |
12175 | bool CheckX86BuiltinTileRangeAndDuplicate(CallExpr *TheCall, |
12176 | ArrayRef<int> ArgNums); |
12177 | bool CheckX86BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, |
12178 | CallExpr *TheCall); |
12179 | bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, |
12180 | CallExpr *TheCall); |
12181 | bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); |
12182 | |
12183 | bool SemaBuiltinVAStart(unsigned BuiltinID, CallExpr *TheCall); |
12184 | bool SemaBuiltinVAStartARMMicrosoft(CallExpr *Call); |
12185 | bool SemaBuiltinUnorderedCompare(CallExpr *TheCall); |
12186 | bool SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs); |
12187 | bool SemaBuiltinComplex(CallExpr *TheCall); |
12188 | bool SemaBuiltinVSX(CallExpr *TheCall); |
12189 | bool SemaBuiltinOSLogFormat(CallExpr *TheCall); |
12190 | |
12191 | public: |
12192 | // Used by C++ template instantiation. |
12193 | ExprResult SemaBuiltinShuffleVector(CallExpr *TheCall); |
12194 | ExprResult SemaConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo, |
12195 | SourceLocation BuiltinLoc, |
12196 | SourceLocation RParenLoc); |
12197 | |
12198 | private: |
12199 | bool SemaBuiltinPrefetch(CallExpr *TheCall); |
12200 | bool SemaBuiltinAllocaWithAlign(CallExpr *TheCall); |
12201 | bool SemaBuiltinAssume(CallExpr *TheCall); |
12202 | bool SemaBuiltinAssumeAligned(CallExpr *TheCall); |
12203 | bool SemaBuiltinLongjmp(CallExpr *TheCall); |
12204 | bool SemaBuiltinSetjmp(CallExpr *TheCall); |
12205 | ExprResult SemaBuiltinAtomicOverloaded(ExprResult TheCallResult); |
12206 | ExprResult SemaBuiltinNontemporalOverloaded(ExprResult TheCallResult); |
12207 | ExprResult SemaAtomicOpsOverloaded(ExprResult TheCallResult, |
12208 | AtomicExpr::AtomicOp Op); |
12209 | ExprResult SemaBuiltinOperatorNewDeleteOverloaded(ExprResult TheCallResult, |
12210 | bool IsDelete); |
12211 | bool SemaBuiltinConstantArg(CallExpr *TheCall, int ArgNum, |
12212 | llvm::APSInt &Result); |
12213 | bool SemaBuiltinConstantArgRange(CallExpr *TheCall, int ArgNum, int Low, |
12214 | int High, bool RangeIsError = true); |
12215 | bool SemaBuiltinConstantArgMultiple(CallExpr *TheCall, int ArgNum, |
12216 | unsigned Multiple); |
12217 | bool SemaBuiltinConstantArgPower2(CallExpr *TheCall, int ArgNum); |
12218 | bool SemaBuiltinConstantArgShiftedByte(CallExpr *TheCall, int ArgNum, |
12219 | unsigned ArgBits); |
12220 | bool SemaBuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, int ArgNum, |
12221 | unsigned ArgBits); |
12222 | bool SemaBuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall, |
12223 | int ArgNum, unsigned ExpectedFieldNum, |
12224 | bool AllowName); |
12225 | bool SemaBuiltinARMMemoryTaggingCall(unsigned BuiltinID, CallExpr *TheCall); |
12226 | |
12227 | // Matrix builtin handling. |
12228 | ExprResult SemaBuiltinMatrixTranspose(CallExpr *TheCall, |
12229 | ExprResult CallResult); |
12230 | ExprResult SemaBuiltinMatrixColumnMajorLoad(CallExpr *TheCall, |
12231 | ExprResult CallResult); |
12232 | ExprResult SemaBuiltinMatrixColumnMajorStore(CallExpr *TheCall, |
12233 | ExprResult CallResult); |
12234 | |
12235 | public: |
12236 | enum FormatStringType { |
12237 | FST_Scanf, |
12238 | FST_Printf, |
12239 | FST_NSString, |
12240 | FST_Strftime, |
12241 | FST_Strfmon, |
12242 | FST_Kprintf, |
12243 | FST_FreeBSDKPrintf, |
12244 | FST_OSTrace, |
12245 | FST_OSLog, |
12246 | FST_Unknown |
12247 | }; |
12248 | static FormatStringType GetFormatStringType(const FormatAttr *Format); |
12249 | |
12250 | bool FormatStringHasSArg(const StringLiteral *FExpr); |
12251 | |
12252 | static bool GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx); |
12253 | |
12254 | private: |
12255 | bool CheckFormatArguments(const FormatAttr *Format, |
12256 | ArrayRef<const Expr *> Args, |
12257 | bool IsCXXMember, |
12258 | VariadicCallType CallType, |
12259 | SourceLocation Loc, SourceRange Range, |
12260 | llvm::SmallBitVector &CheckedVarArgs); |
12261 | bool CheckFormatArguments(ArrayRef<const Expr *> Args, |
12262 | bool HasVAListArg, unsigned format_idx, |
12263 | unsigned firstDataArg, FormatStringType Type, |
12264 | VariadicCallType CallType, |
12265 | SourceLocation Loc, SourceRange range, |
12266 | llvm::SmallBitVector &CheckedVarArgs); |
12267 | |
12268 | void CheckAbsoluteValueFunction(const CallExpr *Call, |
12269 | const FunctionDecl *FDecl); |
12270 | |
12271 | void CheckMaxUnsignedZero(const CallExpr *Call, const FunctionDecl *FDecl); |
12272 | |
12273 | void CheckMemaccessArguments(const CallExpr *Call, |
12274 | unsigned BId, |
12275 | IdentifierInfo *FnName); |
12276 | |
12277 | void CheckStrlcpycatArguments(const CallExpr *Call, |
12278 | IdentifierInfo *FnName); |
12279 | |
12280 | void CheckStrncatArguments(const CallExpr *Call, |
12281 | IdentifierInfo *FnName); |
12282 | |
12283 | void CheckReturnValExpr(Expr *RetValExp, QualType lhsType, |
12284 | SourceLocation ReturnLoc, |
12285 | bool isObjCMethod = false, |
12286 | const AttrVec *Attrs = nullptr, |
12287 | const FunctionDecl *FD = nullptr); |
12288 | |
12289 | public: |
12290 | void CheckFloatComparison(SourceLocation Loc, Expr *LHS, Expr *RHS); |
12291 | |
12292 | private: |
12293 | void CheckImplicitConversions(Expr *E, SourceLocation CC = SourceLocation()); |
12294 | void CheckBoolLikeConversion(Expr *E, SourceLocation CC); |
12295 | void CheckForIntOverflow(Expr *E); |
12296 | void CheckUnsequencedOperations(const Expr *E); |
12297 | |
12298 | /// Perform semantic checks on a completed expression. This will either |
12299 | /// be a full-expression or a default argument expression. |
12300 | void CheckCompletedExpr(Expr *E, SourceLocation CheckLoc = SourceLocation(), |
12301 | bool IsConstexpr = false); |
12302 | |
12303 | void CheckBitFieldInitialization(SourceLocation InitLoc, FieldDecl *Field, |
12304 | Expr *Init); |
12305 | |
12306 | /// Check if there is a field shadowing. |
12307 | void CheckShadowInheritedFields(const SourceLocation &Loc, |
12308 | DeclarationName FieldName, |
12309 | const CXXRecordDecl *RD, |
12310 | bool DeclIsField = true); |
12311 | |
12312 | /// Check if the given expression contains 'break' or 'continue' |
12313 | /// statement that produces control flow different from GCC. |
12314 | void CheckBreakContinueBinding(Expr *E); |
12315 | |
12316 | /// Check whether receiver is mutable ObjC container which |
12317 | /// attempts to add itself into the container |
12318 | void CheckObjCCircularContainer(ObjCMessageExpr *Message); |
12319 | |
12320 | void AnalyzeDeleteExprMismatch(const CXXDeleteExpr *DE); |
12321 | void AnalyzeDeleteExprMismatch(FieldDecl *Field, SourceLocation DeleteLoc, |
12322 | bool DeleteWasArrayForm); |
12323 | public: |
12324 | /// Register a magic integral constant to be used as a type tag. |
12325 | void RegisterTypeTagForDatatype(const IdentifierInfo *ArgumentKind, |
12326 | uint64_t MagicValue, QualType Type, |
12327 | bool LayoutCompatible, bool MustBeNull); |
12328 | |
12329 | struct TypeTagData { |
12330 | TypeTagData() {} |
12331 | |
12332 | TypeTagData(QualType Type, bool LayoutCompatible, bool MustBeNull) : |
12333 | Type(Type), LayoutCompatible(LayoutCompatible), |
12334 | MustBeNull(MustBeNull) |
12335 | {} |
12336 | |
12337 | QualType Type; |
12338 | |
12339 | /// If true, \c Type should be compared with other expression's types for |
12340 | /// layout-compatibility. |
12341 | unsigned LayoutCompatible : 1; |
12342 | unsigned MustBeNull : 1; |
12343 | }; |
12344 | |
12345 | /// A pair of ArgumentKind identifier and magic value. This uniquely |
12346 | /// identifies the magic value. |
12347 | typedef std::pair<const IdentifierInfo *, uint64_t> TypeTagMagicValue; |
12348 | |
12349 | private: |
12350 | /// A map from magic value to type information. |
12351 | std::unique_ptr<llvm::DenseMap<TypeTagMagicValue, TypeTagData>> |
12352 | TypeTagForDatatypeMagicValues; |
12353 | |
12354 | /// Peform checks on a call of a function with argument_with_type_tag |
12355 | /// or pointer_with_type_tag attributes. |
12356 | void CheckArgumentWithTypeTag(const ArgumentWithTypeTagAttr *Attr, |
12357 | const ArrayRef<const Expr *> ExprArgs, |
12358 | SourceLocation CallSiteLoc); |
12359 | |
12360 | /// Check if we are taking the address of a packed field |
12361 | /// as this may be a problem if the pointer value is dereferenced. |
12362 | void CheckAddressOfPackedMember(Expr *rhs); |
12363 | |
12364 | /// The parser's current scope. |
12365 | /// |
12366 | /// The parser maintains this state here. |
12367 | Scope *CurScope; |
12368 | |
12369 | mutable IdentifierInfo *Ident_super; |
12370 | mutable IdentifierInfo *Ident___float128; |
12371 | |
12372 | /// Nullability type specifiers. |
12373 | IdentifierInfo *Ident__Nonnull = nullptr; |
12374 | IdentifierInfo *Ident__Nullable = nullptr; |
12375 | IdentifierInfo *Ident__Null_unspecified = nullptr; |
12376 | |
12377 | IdentifierInfo *Ident_NSError = nullptr; |
12378 | |
12379 | /// The handler for the FileChanged preprocessor events. |
12380 | /// |
12381 | /// Used for diagnostics that implement custom semantic analysis for #include |
12382 | /// directives, like -Wpragma-pack. |
12383 | sema::SemaPPCallbacks *SemaPPCallbackHandler; |
12384 | |
12385 | protected: |
12386 | friend class Parser; |
12387 | friend class InitializationSequence; |
12388 | friend class ASTReader; |
12389 | friend class ASTDeclReader; |
12390 | friend class ASTWriter; |
12391 | |
12392 | public: |
12393 | /// Retrieve the keyword associated |
12394 | IdentifierInfo *getNullabilityKeyword(NullabilityKind nullability); |
12395 | |
12396 | /// The struct behind the CFErrorRef pointer. |
12397 | RecordDecl *CFError = nullptr; |
12398 | |
12399 | /// Retrieve the identifier "NSError". |
12400 | IdentifierInfo *getNSErrorIdent(); |
12401 | |
12402 | /// Retrieve the parser's current scope. |
12403 | /// |
12404 | /// This routine must only be used when it is certain that semantic analysis |
12405 | /// and the parser are in precisely the same context, which is not the case |
12406 | /// when, e.g., we are performing any kind of template instantiation. |
12407 | /// Therefore, the only safe places to use this scope are in the parser |
12408 | /// itself and in routines directly invoked from the parser and *never* from |
12409 | /// template substitution or instantiation. |
12410 | Scope *getCurScope() const { return CurScope; } |
12411 | |
12412 | void incrementMSManglingNumber() const { |
12413 | return CurScope->incrementMSManglingNumber(); |
12414 | } |
12415 | |
12416 | IdentifierInfo *getSuperIdentifier() const; |
12417 | IdentifierInfo *getFloat128Identifier() const; |
12418 | |
12419 | Decl *getObjCDeclContext() const; |
12420 | |
12421 | DeclContext *getCurLexicalContext() const { |
12422 | return OriginalLexicalContext ? OriginalLexicalContext : CurContext; |
12423 | } |
12424 | |
12425 | const DeclContext *getCurObjCLexicalContext() const { |
12426 | const DeclContext *DC = getCurLexicalContext(); |
12427 | // A category implicitly has the attribute of the interface. |
12428 | if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(DC)) |
12429 | DC = CatD->getClassInterface(); |
12430 | return DC; |
12431 | } |
12432 | |
12433 | /// Determine the number of levels of enclosing template parameters. This is |
12434 | /// only usable while parsing. Note that this does not include dependent |
12435 | /// contexts in which no template parameters have yet been declared, such as |
12436 | /// in a terse function template or generic lambda before the first 'auto' is |
12437 | /// encountered. |
12438 | unsigned getTemplateDepth(Scope *S) const; |
12439 | |
12440 | /// To be used for checking whether the arguments being passed to |
12441 | /// function exceeds the number of parameters expected for it. |
12442 | static bool TooManyArguments(size_t NumParams, size_t NumArgs, |
12443 | bool PartialOverloading = false) { |
12444 | // We check whether we're just after a comma in code-completion. |
12445 | if (NumArgs > 0 && PartialOverloading) |
12446 | return NumArgs + 1 > NumParams; // If so, we view as an extra argument. |
12447 | return NumArgs > NumParams; |
12448 | } |
12449 | |
12450 | // Emitting members of dllexported classes is delayed until the class |
12451 | // (including field initializers) is fully parsed. |
12452 | SmallVector<CXXRecordDecl*, 4> DelayedDllExportClasses; |
12453 | SmallVector<CXXMethodDecl*, 4> DelayedDllExportMemberFunctions; |
12454 | |
12455 | private: |
12456 | int ParsingClassDepth = 0; |
12457 | |
12458 | class SavePendingParsedClassStateRAII { |
12459 | public: |
12460 | SavePendingParsedClassStateRAII(Sema &S) : S(S) { swapSavedState(); } |
12461 | |
12462 | ~SavePendingParsedClassStateRAII() { |
12463 | 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~++20200806111125+5446ec85070/clang/include/clang/Sema/Sema.h" , 12464, __PRETTY_FUNCTION__)) |
12464 | "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~++20200806111125+5446ec85070/clang/include/clang/Sema/Sema.h" , 12464, __PRETTY_FUNCTION__)); |
12465 | 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~++20200806111125+5446ec85070/clang/include/clang/Sema/Sema.h" , 12466, __PRETTY_FUNCTION__)) |
12466 | "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~++20200806111125+5446ec85070/clang/include/clang/Sema/Sema.h" , 12466, __PRETTY_FUNCTION__)); |
12467 | swapSavedState(); |
12468 | } |
12469 | |
12470 | private: |
12471 | Sema &S; |
12472 | decltype(DelayedOverridingExceptionSpecChecks) |
12473 | SavedOverridingExceptionSpecChecks; |
12474 | decltype(DelayedEquivalentExceptionSpecChecks) |
12475 | SavedEquivalentExceptionSpecChecks; |
12476 | |
12477 | void swapSavedState() { |
12478 | SavedOverridingExceptionSpecChecks.swap( |
12479 | S.DelayedOverridingExceptionSpecChecks); |
12480 | SavedEquivalentExceptionSpecChecks.swap( |
12481 | S.DelayedEquivalentExceptionSpecChecks); |
12482 | } |
12483 | }; |
12484 | |
12485 | /// Helper class that collects misaligned member designations and |
12486 | /// their location info for delayed diagnostics. |
12487 | struct MisalignedMember { |
12488 | Expr *E; |
12489 | RecordDecl *RD; |
12490 | ValueDecl *MD; |
12491 | CharUnits Alignment; |
12492 | |
12493 | MisalignedMember() : E(), RD(), MD(), Alignment() {} |
12494 | MisalignedMember(Expr *E, RecordDecl *RD, ValueDecl *MD, |
12495 | CharUnits Alignment) |
12496 | : E(E), RD(RD), MD(MD), Alignment(Alignment) {} |
12497 | explicit MisalignedMember(Expr *E) |
12498 | : MisalignedMember(E, nullptr, nullptr, CharUnits()) {} |
12499 | |
12500 | bool operator==(const MisalignedMember &m) { return this->E == m.E; } |
12501 | }; |
12502 | /// Small set of gathered accesses to potentially misaligned members |
12503 | /// due to the packed attribute. |
12504 | SmallVector<MisalignedMember, 4> MisalignedMembers; |
12505 | |
12506 | /// Adds an expression to the set of gathered misaligned members. |
12507 | void AddPotentialMisalignedMembers(Expr *E, RecordDecl *RD, ValueDecl *MD, |
12508 | CharUnits Alignment); |
12509 | |
12510 | public: |
12511 | /// Diagnoses the current set of gathered accesses. This typically |
12512 | /// happens at full expression level. The set is cleared after emitting the |
12513 | /// diagnostics. |
12514 | void DiagnoseMisalignedMembers(); |
12515 | |
12516 | /// This function checks if the expression is in the sef of potentially |
12517 | /// misaligned members and it is converted to some pointer type T with lower |
12518 | /// or equal alignment requirements. If so it removes it. This is used when |
12519 | /// we do not want to diagnose such misaligned access (e.g. in conversions to |
12520 | /// void*). |
12521 | void DiscardMisalignedMemberAddress(const Type *T, Expr *E); |
12522 | |
12523 | /// This function calls Action when it determines that E designates a |
12524 | /// misaligned member due to the packed attribute. This is used to emit |
12525 | /// local diagnostics like in reference binding. |
12526 | void RefersToMemberWithReducedAlignment( |
12527 | Expr *E, |
12528 | llvm::function_ref<void(Expr *, RecordDecl *, FieldDecl *, CharUnits)> |
12529 | Action); |
12530 | |
12531 | /// Describes the reason a calling convention specification was ignored, used |
12532 | /// for diagnostics. |
12533 | enum class CallingConventionIgnoredReason { |
12534 | ForThisTarget = 0, |
12535 | VariadicFunction, |
12536 | ConstructorDestructor, |
12537 | BuiltinFunction |
12538 | }; |
12539 | /// Creates a DeviceDiagBuilder that emits the diagnostic if the current |
12540 | /// context is "used as device code". |
12541 | /// |
12542 | /// - If CurLexicalContext is a kernel function or it is known that the |
12543 | /// function will be emitted for the device, emits the diagnostics |
12544 | /// immediately. |
12545 | /// - If CurLexicalContext is a function and we are compiling |
12546 | /// for the device, but we don't know that this function will be codegen'ed |
12547 | /// for devive yet, creates a diagnostic which is emitted if and when we |
12548 | /// realize that the function will be codegen'ed. |
12549 | /// |
12550 | /// Example usage: |
12551 | /// |
12552 | /// Diagnose __float128 type usage only from SYCL device code if the current |
12553 | /// target doesn't support it |
12554 | /// if (!S.Context.getTargetInfo().hasFloat128Type() && |
12555 | /// S.getLangOpts().SYCLIsDevice) |
12556 | /// SYCLDiagIfDeviceCode(Loc, diag::err_type_unsupported) << "__float128"; |
12557 | DeviceDiagBuilder SYCLDiagIfDeviceCode(SourceLocation Loc, unsigned DiagID); |
12558 | |
12559 | /// Check whether we're allowed to call Callee from the current context. |
12560 | /// |
12561 | /// - If the call is never allowed in a semantically-correct program |
12562 | /// emits an error and returns false. |
12563 | /// |
12564 | /// - If the call is allowed in semantically-correct programs, but only if |
12565 | /// it's never codegen'ed, creates a deferred diagnostic to be emitted if |
12566 | /// and when the caller is codegen'ed, and returns true. |
12567 | /// |
12568 | /// - Otherwise, returns true without emitting any diagnostics. |
12569 | /// |
12570 | /// Adds Callee to DeviceCallGraph if we don't know if its caller will be |
12571 | /// codegen'ed yet. |
12572 | bool checkSYCLDeviceFunction(SourceLocation Loc, FunctionDecl *Callee); |
12573 | }; |
12574 | |
12575 | /// RAII object that enters a new expression evaluation context. |
12576 | class EnterExpressionEvaluationContext { |
12577 | Sema &Actions; |
12578 | bool Entered = true; |
12579 | |
12580 | public: |
12581 | EnterExpressionEvaluationContext( |
12582 | Sema &Actions, Sema::ExpressionEvaluationContext NewContext, |
12583 | Decl *LambdaContextDecl = nullptr, |
12584 | Sema::ExpressionEvaluationContextRecord::ExpressionKind ExprContext = |
12585 | Sema::ExpressionEvaluationContextRecord::EK_Other, |
12586 | bool ShouldEnter = true) |
12587 | : Actions(Actions), Entered(ShouldEnter) { |
12588 | if (Entered) |
12589 | Actions.PushExpressionEvaluationContext(NewContext, LambdaContextDecl, |
12590 | ExprContext); |
12591 | } |
12592 | EnterExpressionEvaluationContext( |
12593 | Sema &Actions, Sema::ExpressionEvaluationContext NewContext, |
12594 | Sema::ReuseLambdaContextDecl_t, |
12595 | Sema::ExpressionEvaluationContextRecord::ExpressionKind ExprContext = |
12596 | Sema::ExpressionEvaluationContextRecord::EK_Other) |
12597 | : Actions(Actions) { |
12598 | Actions.PushExpressionEvaluationContext( |
12599 | NewContext, Sema::ReuseLambdaContextDecl, ExprContext); |
12600 | } |
12601 | |
12602 | enum InitListTag { InitList }; |
12603 | EnterExpressionEvaluationContext(Sema &Actions, InitListTag, |
12604 | bool ShouldEnter = true) |
12605 | : Actions(Actions), Entered(false) { |
12606 | // In C++11 onwards, narrowing checks are performed on the contents of |
12607 | // braced-init-lists, even when they occur within unevaluated operands. |
12608 | // Therefore we still need to instantiate constexpr functions used in such |
12609 | // a context. |
12610 | if (ShouldEnter && Actions.isUnevaluatedContext() && |
12611 | Actions.getLangOpts().CPlusPlus11) { |
12612 | Actions.PushExpressionEvaluationContext( |
12613 | Sema::ExpressionEvaluationContext::UnevaluatedList); |
12614 | Entered = true; |
12615 | } |
12616 | } |
12617 | |
12618 | ~EnterExpressionEvaluationContext() { |
12619 | if (Entered) |
12620 | Actions.PopExpressionEvaluationContext(); |
12621 | } |
12622 | }; |
12623 | |
12624 | DeductionFailureInfo |
12625 | MakeDeductionFailureInfo(ASTContext &Context, Sema::TemplateDeductionResult TDK, |
12626 | sema::TemplateDeductionInfo &Info); |
12627 | |
12628 | /// Contains a late templated function. |
12629 | /// Will be parsed at the end of the translation unit, used by Sema & Parser. |
12630 | struct LateParsedTemplate { |
12631 | CachedTokens Toks; |
12632 | /// The template function declaration to be late parsed. |
12633 | Decl *D; |
12634 | }; |
12635 | } // end namespace clang |
12636 | |
12637 | namespace llvm { |
12638 | // Hash a FunctionDeclAndLoc by looking at both its FunctionDecl and its |
12639 | // SourceLocation. |
12640 | template <> struct DenseMapInfo<clang::Sema::FunctionDeclAndLoc> { |
12641 | using FunctionDeclAndLoc = clang::Sema::FunctionDeclAndLoc; |
12642 | using FDBaseInfo = DenseMapInfo<clang::CanonicalDeclPtr<clang::FunctionDecl>>; |
12643 | |
12644 | static FunctionDeclAndLoc getEmptyKey() { |
12645 | return {FDBaseInfo::getEmptyKey(), clang::SourceLocation()}; |
12646 | } |
12647 | |
12648 | static FunctionDeclAndLoc getTombstoneKey() { |
12649 | return {FDBaseInfo::getTombstoneKey(), clang::SourceLocation()}; |
12650 | } |
12651 | |
12652 | static unsigned getHashValue(const FunctionDeclAndLoc &FDL) { |
12653 | return hash_combine(FDBaseInfo::getHashValue(FDL.FD), |
12654 | FDL.Loc.getRawEncoding()); |
12655 | } |
12656 | |
12657 | static bool isEqual(const FunctionDeclAndLoc &LHS, |
12658 | const FunctionDeclAndLoc &RHS) { |
12659 | return LHS.FD == RHS.FD && LHS.Loc == RHS.Loc; |
12660 | } |
12661 | }; |
12662 | } // namespace llvm |
12663 | |
12664 | #endif |