/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/Sema/TemplateDeduction.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- TemplateDeduction.h - C++ template argument deduction ----*- 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 provides types used with Sema's template argument deduction |
10 | | // routines. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #ifndef LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H |
15 | | #define LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H |
16 | | |
17 | | #include "clang/Sema/Ownership.h" |
18 | | #include "clang/Sema/SemaConcept.h" |
19 | | #include "clang/AST/ASTConcept.h" |
20 | | #include "clang/AST/DeclAccessPair.h" |
21 | | #include "clang/AST/DeclTemplate.h" |
22 | | #include "clang/AST/TemplateBase.h" |
23 | | #include "clang/Basic/PartialDiagnostic.h" |
24 | | #include "clang/Basic/SourceLocation.h" |
25 | | #include "llvm/ADT/Optional.h" |
26 | | #include "llvm/ADT/SmallVector.h" |
27 | | #include <cassert> |
28 | | #include <cstddef> |
29 | | #include <utility> |
30 | | |
31 | | namespace clang { |
32 | | |
33 | | class Decl; |
34 | | struct DeducedPack; |
35 | | class Sema; |
36 | | |
37 | | namespace sema { |
38 | | |
39 | | /// Provides information about an attempted template argument |
40 | | /// deduction, whose success or failure was described by a |
41 | | /// TemplateDeductionResult value. |
42 | | class TemplateDeductionInfo { |
43 | | /// The deduced template argument list. |
44 | | TemplateArgumentList *Deduced = nullptr; |
45 | | |
46 | | /// The source location at which template argument |
47 | | /// deduction is occurring. |
48 | | SourceLocation Loc; |
49 | | |
50 | | /// Have we suppressed an error during deduction? |
51 | | bool HasSFINAEDiagnostic = false; |
52 | | |
53 | | /// The template parameter depth for which we're performing deduction. |
54 | | unsigned DeducedDepth; |
55 | | |
56 | | /// The number of parameters with explicitly-specified template arguments, |
57 | | /// up to and including the partially-specified pack (if any). |
58 | | unsigned ExplicitArgs = 0; |
59 | | |
60 | | /// Warnings (and follow-on notes) that were suppressed due to |
61 | | /// SFINAE while performing template argument deduction. |
62 | | SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics; |
63 | | |
64 | | public: |
65 | | TemplateDeductionInfo(SourceLocation Loc, unsigned DeducedDepth = 0) |
66 | 2.05M | : Loc(Loc), DeducedDepth(DeducedDepth) {} |
67 | | TemplateDeductionInfo(const TemplateDeductionInfo &) = delete; |
68 | | TemplateDeductionInfo &operator=(const TemplateDeductionInfo &) = delete; |
69 | | |
70 | | enum ForBaseTag { ForBase }; |
71 | | /// Create temporary template deduction info for speculatively deducing |
72 | | /// against a base class of an argument's type. |
73 | | TemplateDeductionInfo(ForBaseTag, const TemplateDeductionInfo &Info) |
74 | | : Deduced(Info.Deduced), Loc(Info.Loc), DeducedDepth(Info.DeducedDepth), |
75 | 13.3k | ExplicitArgs(Info.ExplicitArgs) {} |
76 | | |
77 | | /// Returns the location at which template argument is |
78 | | /// occurring. |
79 | 4.31M | SourceLocation getLocation() const { |
80 | 4.31M | return Loc; |
81 | 4.31M | } |
82 | | |
83 | | /// The depth of template parameters for which deduction is being |
84 | | /// performed. |
85 | 3.34M | unsigned getDeducedDepth() const { |
86 | 3.34M | return DeducedDepth; |
87 | 3.34M | } |
88 | | |
89 | | /// Get the number of explicitly-specified arguments. |
90 | 60.6k | unsigned getNumExplicitArgs() const { |
91 | 60.6k | return ExplicitArgs; |
92 | 60.6k | } |
93 | | |
94 | | /// Take ownership of the deduced template argument list. |
95 | 265k | TemplateArgumentList *take() { |
96 | 265k | TemplateArgumentList *Result = Deduced; |
97 | 265k | Deduced = nullptr; |
98 | 265k | return Result; |
99 | 265k | } |
100 | | |
101 | | /// Take ownership of the SFINAE diagnostic. |
102 | 86.7k | void takeSFINAEDiagnostic(PartialDiagnosticAt &PD) { |
103 | 86.7k | assert(HasSFINAEDiagnostic); |
104 | 86.7k | PD.first = SuppressedDiagnostics.front().first; |
105 | 86.7k | PD.second.swap(SuppressedDiagnostics.front().second); |
106 | 86.7k | clearSFINAEDiagnostic(); |
107 | 86.7k | } |
108 | | |
109 | | /// Discard any SFINAE diagnostics. |
110 | 86.7k | void clearSFINAEDiagnostic() { |
111 | 86.7k | SuppressedDiagnostics.clear(); |
112 | 86.7k | HasSFINAEDiagnostic = false; |
113 | 86.7k | } |
114 | | |
115 | | /// Peek at the SFINAE diagnostic. |
116 | 73 | const PartialDiagnosticAt &peekSFINAEDiagnostic() const { |
117 | 73 | assert(HasSFINAEDiagnostic); |
118 | 73 | return SuppressedDiagnostics.front(); |
119 | 73 | } |
120 | | |
121 | | /// Provide an initial template argument list that contains the |
122 | | /// explicitly-specified arguments. |
123 | 229k | void setExplicitArgs(TemplateArgumentList *NewDeduced) { |
124 | 229k | Deduced = NewDeduced; |
125 | 229k | ExplicitArgs = Deduced->size(); |
126 | 229k | } |
127 | | |
128 | | /// Provide a new template argument list that contains the |
129 | | /// results of template argument deduction. |
130 | 676k | void reset(TemplateArgumentList *NewDeduced) { |
131 | 676k | Deduced = NewDeduced; |
132 | 676k | } |
133 | | |
134 | | /// Is a SFINAE diagnostic available? |
135 | 177k | bool hasSFINAEDiagnostic() const { |
136 | 177k | return HasSFINAEDiagnostic; |
137 | 177k | } |
138 | | |
139 | | /// Set the diagnostic which caused the SFINAE failure. |
140 | 88.4k | void addSFINAEDiagnostic(SourceLocation Loc, PartialDiagnostic PD) { |
141 | | // Only collect the first diagnostic. |
142 | 88.4k | if (HasSFINAEDiagnostic) |
143 | 0 | return; |
144 | 88.4k | SuppressedDiagnostics.clear(); |
145 | 88.4k | SuppressedDiagnostics.emplace_back(Loc, std::move(PD)); |
146 | 88.4k | HasSFINAEDiagnostic = true; |
147 | 88.4k | } |
148 | | |
149 | | /// Add a new diagnostic to the set of diagnostics |
150 | | void addSuppressedDiagnostic(SourceLocation Loc, |
151 | 29.8k | PartialDiagnostic PD) { |
152 | 29.8k | if (HasSFINAEDiagnostic) |
153 | 6.69k | return; |
154 | 23.1k | SuppressedDiagnostics.emplace_back(Loc, std::move(PD)); |
155 | 23.1k | } |
156 | | |
157 | | /// Iterator over the set of suppressed diagnostics. |
158 | | using diag_iterator = SmallVectorImpl<PartialDiagnosticAt>::const_iterator; |
159 | | |
160 | | /// Returns an iterator at the beginning of the sequence of suppressed |
161 | | /// diagnostics. |
162 | 384k | diag_iterator diag_begin() const { return SuppressedDiagnostics.begin(); } |
163 | | |
164 | | /// Returns an iterator at the end of the sequence of suppressed |
165 | | /// diagnostics. |
166 | 384k | diag_iterator diag_end() const { return SuppressedDiagnostics.end(); } |
167 | | |
168 | | /// The template parameter to which a template argument |
169 | | /// deduction failure refers. |
170 | | /// |
171 | | /// Depending on the result of template argument deduction, this |
172 | | /// template parameter may have different meanings: |
173 | | /// |
174 | | /// TDK_Incomplete: this is the first template parameter whose |
175 | | /// corresponding template argument was not deduced. |
176 | | /// |
177 | | /// TDK_IncompletePack: this is the expanded parameter pack for |
178 | | /// which we deduced too few arguments. |
179 | | /// |
180 | | /// TDK_Inconsistent: this is the template parameter for which |
181 | | /// two different template argument values were deduced. |
182 | | TemplateParameter Param; |
183 | | |
184 | | /// The first template argument to which the template |
185 | | /// argument deduction failure refers. |
186 | | /// |
187 | | /// Depending on the result of the template argument deduction, |
188 | | /// this template argument may have different meanings: |
189 | | /// |
190 | | /// TDK_IncompletePack: this is the number of arguments we deduced |
191 | | /// for the pack. |
192 | | /// |
193 | | /// TDK_Inconsistent: this argument is the first value deduced |
194 | | /// for the corresponding template parameter. |
195 | | /// |
196 | | /// TDK_SubstitutionFailure: this argument is the template |
197 | | /// argument we were instantiating when we encountered an error. |
198 | | /// |
199 | | /// TDK_DeducedMismatch: this is the parameter type, after substituting |
200 | | /// deduced arguments. |
201 | | /// |
202 | | /// TDK_NonDeducedMismatch: this is the component of the 'parameter' |
203 | | /// of the deduction, directly provided in the source code. |
204 | | TemplateArgument FirstArg; |
205 | | |
206 | | /// The second template argument to which the template |
207 | | /// argument deduction failure refers. |
208 | | /// |
209 | | /// TDK_Inconsistent: this argument is the second value deduced |
210 | | /// for the corresponding template parameter. |
211 | | /// |
212 | | /// TDK_DeducedMismatch: this is the (adjusted) call argument type. |
213 | | /// |
214 | | /// TDK_NonDeducedMismatch: this is the mismatching component of the |
215 | | /// 'argument' of the deduction, from which we are deducing arguments. |
216 | | /// |
217 | | /// FIXME: Finish documenting this. |
218 | | TemplateArgument SecondArg; |
219 | | |
220 | | /// The index of the function argument that caused a deduction |
221 | | /// failure. |
222 | | /// |
223 | | /// TDK_DeducedMismatch: this is the index of the argument that had a |
224 | | /// different argument type from its substituted parameter type. |
225 | | unsigned CallArgIndex = 0; |
226 | | |
227 | | /// Information on packs that we're currently expanding. |
228 | | /// |
229 | | /// FIXME: This should be kept internal to SemaTemplateDeduction. |
230 | | SmallVector<DeducedPack *, 8> PendingDeducedPacks; |
231 | | |
232 | | /// \brief The constraint satisfaction details resulting from the associated |
233 | | /// constraints satisfaction tests. |
234 | | ConstraintSatisfaction AssociatedConstraintsSatisfaction; |
235 | | }; |
236 | | |
237 | | } // namespace sema |
238 | | |
239 | | /// A structure used to record information about a failed |
240 | | /// template argument deduction, for diagnosis. |
241 | | struct DeductionFailureInfo { |
242 | | /// A Sema::TemplateDeductionResult. |
243 | | unsigned Result : 8; |
244 | | |
245 | | /// Indicates whether a diagnostic is stored in Diagnostic. |
246 | | unsigned HasDiagnostic : 1; |
247 | | |
248 | | /// Opaque pointer containing additional data about |
249 | | /// this deduction failure. |
250 | | void *Data; |
251 | | |
252 | | /// A diagnostic indicating why deduction failed. |
253 | | alignas(PartialDiagnosticAt) char Diagnostic[sizeof(PartialDiagnosticAt)]; |
254 | | |
255 | | /// Retrieve the diagnostic which caused this deduction failure, |
256 | | /// if any. |
257 | | PartialDiagnosticAt *getSFINAEDiagnostic(); |
258 | | |
259 | | /// Retrieve the template parameter this deduction failure |
260 | | /// refers to, if any. |
261 | | TemplateParameter getTemplateParameter(); |
262 | | |
263 | | /// Retrieve the template argument list associated with this |
264 | | /// deduction failure, if any. |
265 | | TemplateArgumentList *getTemplateArgumentList(); |
266 | | |
267 | | /// Return the first template argument this deduction failure |
268 | | /// refers to, if any. |
269 | | const TemplateArgument *getFirstArg(); |
270 | | |
271 | | /// Return the second template argument this deduction failure |
272 | | /// refers to, if any. |
273 | | const TemplateArgument *getSecondArg(); |
274 | | |
275 | | /// Return the index of the call argument that this deduction |
276 | | /// failure refers to, if any. |
277 | | llvm::Optional<unsigned> getCallArgIndex(); |
278 | | |
279 | | /// Free any memory associated with this deduction failure. |
280 | | void Destroy(); |
281 | | }; |
282 | | |
283 | | /// TemplateSpecCandidate - This is a generalization of OverloadCandidate |
284 | | /// which keeps track of template argument deduction failure info, when |
285 | | /// handling explicit specializations (and instantiations) of templates |
286 | | /// beyond function overloading. |
287 | | /// For now, assume that the candidates are non-matching specializations. |
288 | | /// TODO: In the future, we may need to unify/generalize this with |
289 | | /// OverloadCandidate. |
290 | | struct TemplateSpecCandidate { |
291 | | /// The declaration that was looked up, together with its access. |
292 | | /// Might be a UsingShadowDecl, but usually a FunctionTemplateDecl. |
293 | | DeclAccessPair FoundDecl; |
294 | | |
295 | | /// Specialization - The actual specialization that this candidate |
296 | | /// represents. When NULL, this may be a built-in candidate. |
297 | | Decl *Specialization; |
298 | | |
299 | | /// Template argument deduction info |
300 | | DeductionFailureInfo DeductionFailure; |
301 | | |
302 | 458k | void set(DeclAccessPair Found, Decl *Spec, DeductionFailureInfo Info) { |
303 | 458k | FoundDecl = Found; |
304 | 458k | Specialization = Spec; |
305 | 458k | DeductionFailure = Info; |
306 | 458k | } |
307 | | |
308 | | /// Diagnose a template argument deduction failure. |
309 | | void NoteDeductionFailure(Sema &S, bool ForTakingAddress); |
310 | | }; |
311 | | |
312 | | /// TemplateSpecCandidateSet - A set of generalized overload candidates, |
313 | | /// used in template specializations. |
314 | | /// TODO: In the future, we may need to unify/generalize this with |
315 | | /// OverloadCandidateSet. |
316 | | class TemplateSpecCandidateSet { |
317 | | SmallVector<TemplateSpecCandidate, 16> Candidates; |
318 | | SourceLocation Loc; |
319 | | |
320 | | // Stores whether we're taking the address of these candidates. This helps us |
321 | | // produce better error messages when dealing with the pass_object_size |
322 | | // attribute on parameters. |
323 | | bool ForTakingAddress; |
324 | | |
325 | | void destroyCandidates(); |
326 | | |
327 | | public: |
328 | | TemplateSpecCandidateSet(SourceLocation Loc, bool ForTakingAddress = false) |
329 | 805k | : Loc(Loc), ForTakingAddress(ForTakingAddress) {} |
330 | | TemplateSpecCandidateSet(const TemplateSpecCandidateSet &) = delete; |
331 | | TemplateSpecCandidateSet & |
332 | | operator=(const TemplateSpecCandidateSet &) = delete; |
333 | 805k | ~TemplateSpecCandidateSet() { destroyCandidates(); } |
334 | | |
335 | 658k | SourceLocation getLocation() const { return Loc; } |
336 | | |
337 | | /// Clear out all of the candidates. |
338 | | /// TODO: This may be unnecessary. |
339 | | void clear(); |
340 | | |
341 | | using iterator = SmallVector<TemplateSpecCandidate, 16>::iterator; |
342 | | |
343 | 805k | iterator begin() { return Candidates.begin(); } |
344 | 805k | iterator end() { return Candidates.end(); } |
345 | | |
346 | 135 | size_t size() const { return Candidates.size(); } |
347 | 55 | bool empty() const { return Candidates.empty(); } |
348 | | |
349 | | /// Add a new candidate with NumConversions conversion sequence slots |
350 | | /// to the overload set. |
351 | 458k | TemplateSpecCandidate &addCandidate() { |
352 | 458k | Candidates.emplace_back(); |
353 | 458k | return Candidates.back(); |
354 | 458k | } |
355 | | |
356 | | void NoteCandidates(Sema &S, SourceLocation Loc); |
357 | | |
358 | 14 | void NoteCandidates(Sema &S, SourceLocation Loc) const { |
359 | 14 | const_cast<TemplateSpecCandidateSet *>(this)->NoteCandidates(S, Loc); |
360 | 14 | } |
361 | | }; |
362 | | |
363 | | } // namespace clang |
364 | | |
365 | | #endif // LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H |