/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/SmallVector.h" |
26 | | #include <cassert> |
27 | | #include <cstddef> |
28 | | #include <optional> |
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 *DeducedSugared = nullptr, *DeducedCanonical = 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 | 3.58M | : 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 | | : DeducedSugared(Info.DeducedSugared), Loc(Info.Loc), |
75 | 33.2k | DeducedDepth(Info.DeducedDepth), ExplicitArgs(Info.ExplicitArgs) {} |
76 | | |
77 | | /// Returns the location at which template argument is |
78 | | /// occurring. |
79 | 6.96M | SourceLocation getLocation() const { |
80 | 6.96M | return Loc; |
81 | 6.96M | } |
82 | | |
83 | | /// The depth of template parameters for which deduction is being |
84 | | /// performed. |
85 | 4.70M | unsigned getDeducedDepth() const { |
86 | 4.70M | return DeducedDepth; |
87 | 4.70M | } |
88 | | |
89 | | /// Get the number of explicitly-specified arguments. |
90 | 77.2k | unsigned getNumExplicitArgs() const { |
91 | 77.2k | return ExplicitArgs; |
92 | 77.2k | } |
93 | | |
94 | | /// Take ownership of the deduced template argument lists. |
95 | 191k | TemplateArgumentList *takeSugared() { |
96 | 191k | TemplateArgumentList *Result = DeducedSugared; |
97 | 191k | DeducedSugared = nullptr; |
98 | 191k | return Result; |
99 | 191k | } |
100 | 123k | TemplateArgumentList *takeCanonical() { |
101 | 123k | TemplateArgumentList *Result = DeducedCanonical; |
102 | 123k | DeducedCanonical = nullptr; |
103 | 123k | return Result; |
104 | 123k | } |
105 | | |
106 | | /// Take ownership of the SFINAE diagnostic. |
107 | 276k | void takeSFINAEDiagnostic(PartialDiagnosticAt &PD) { |
108 | 276k | assert(HasSFINAEDiagnostic); |
109 | 276k | PD.first = SuppressedDiagnostics.front().first; |
110 | 276k | PD.second.swap(SuppressedDiagnostics.front().second); |
111 | 276k | clearSFINAEDiagnostic(); |
112 | 276k | } |
113 | | |
114 | | /// Discard any SFINAE diagnostics. |
115 | 463k | void clearSFINAEDiagnostic() { |
116 | 463k | SuppressedDiagnostics.clear(); |
117 | 463k | HasSFINAEDiagnostic = false; |
118 | 463k | } |
119 | | |
120 | | /// Peek at the SFINAE diagnostic. |
121 | 90.6k | const PartialDiagnosticAt &peekSFINAEDiagnostic() const { |
122 | 90.6k | assert(HasSFINAEDiagnostic); |
123 | 90.6k | return SuppressedDiagnostics.front(); |
124 | 90.6k | } |
125 | | |
126 | | /// Provide an initial template argument list that contains the |
127 | | /// explicitly-specified arguments. |
128 | | void setExplicitArgs(TemplateArgumentList *NewDeducedSugared, |
129 | 460k | TemplateArgumentList *NewDeducedCanonical) { |
130 | 460k | assert(NewDeducedSugared->size() == NewDeducedCanonical->size()); |
131 | 460k | DeducedSugared = NewDeducedSugared; |
132 | 460k | DeducedCanonical = NewDeducedCanonical; |
133 | 460k | ExplicitArgs = DeducedSugared->size(); |
134 | 460k | } |
135 | | |
136 | | /// Provide a new template argument list that contains the |
137 | | /// results of template argument deduction. |
138 | | void reset(TemplateArgumentList *NewDeducedSugared, |
139 | 1.10M | TemplateArgumentList *NewDeducedCanonical) { |
140 | 1.10M | DeducedSugared = NewDeducedSugared; |
141 | 1.10M | DeducedCanonical = NewDeducedCanonical; |
142 | 1.10M | } |
143 | | |
144 | | /// Is a SFINAE diagnostic available? |
145 | 469k | bool hasSFINAEDiagnostic() const { |
146 | 469k | return HasSFINAEDiagnostic; |
147 | 469k | } |
148 | | |
149 | | /// Set the diagnostic which caused the SFINAE failure. |
150 | 279k | void addSFINAEDiagnostic(SourceLocation Loc, PartialDiagnostic PD) { |
151 | | // Only collect the first diagnostic. |
152 | 279k | if (HasSFINAEDiagnostic) |
153 | 0 | return; |
154 | 279k | SuppressedDiagnostics.clear(); |
155 | 279k | SuppressedDiagnostics.emplace_back(Loc, std::move(PD)); |
156 | 279k | HasSFINAEDiagnostic = true; |
157 | 279k | } |
158 | | |
159 | | /// Add a new diagnostic to the set of diagnostics |
160 | | void addSuppressedDiagnostic(SourceLocation Loc, |
161 | 97.8k | PartialDiagnostic PD) { |
162 | 97.8k | if (HasSFINAEDiagnostic) |
163 | 13.4k | return; |
164 | 84.3k | SuppressedDiagnostics.emplace_back(Loc, std::move(PD)); |
165 | 84.3k | } |
166 | | |
167 | | /// Iterator over the set of suppressed diagnostics. |
168 | | using diag_iterator = SmallVectorImpl<PartialDiagnosticAt>::const_iterator; |
169 | | |
170 | | /// Returns an iterator at the beginning of the sequence of suppressed |
171 | | /// diagnostics. |
172 | 801k | diag_iterator diag_begin() const { return SuppressedDiagnostics.begin(); } |
173 | | |
174 | | /// Returns an iterator at the end of the sequence of suppressed |
175 | | /// diagnostics. |
176 | 801k | diag_iterator diag_end() const { return SuppressedDiagnostics.end(); } |
177 | | |
178 | | /// The template parameter to which a template argument |
179 | | /// deduction failure refers. |
180 | | /// |
181 | | /// Depending on the result of template argument deduction, this |
182 | | /// template parameter may have different meanings: |
183 | | /// |
184 | | /// TDK_Incomplete: this is the first template parameter whose |
185 | | /// corresponding template argument was not deduced. |
186 | | /// |
187 | | /// TDK_IncompletePack: this is the expanded parameter pack for |
188 | | /// which we deduced too few arguments. |
189 | | /// |
190 | | /// TDK_Inconsistent: this is the template parameter for which |
191 | | /// two different template argument values were deduced. |
192 | | TemplateParameter Param; |
193 | | |
194 | | /// The first template argument to which the template |
195 | | /// argument deduction failure refers. |
196 | | /// |
197 | | /// Depending on the result of the template argument deduction, |
198 | | /// this template argument may have different meanings: |
199 | | /// |
200 | | /// TDK_IncompletePack: this is the number of arguments we deduced |
201 | | /// for the pack. |
202 | | /// |
203 | | /// TDK_Inconsistent: this argument is the first value deduced |
204 | | /// for the corresponding template parameter. |
205 | | /// |
206 | | /// TDK_SubstitutionFailure: this argument is the template |
207 | | /// argument we were instantiating when we encountered an error. |
208 | | /// |
209 | | /// TDK_DeducedMismatch: this is the parameter type, after substituting |
210 | | /// deduced arguments. |
211 | | /// |
212 | | /// TDK_NonDeducedMismatch: this is the component of the 'parameter' |
213 | | /// of the deduction, directly provided in the source code. |
214 | | TemplateArgument FirstArg; |
215 | | |
216 | | /// The second template argument to which the template |
217 | | /// argument deduction failure refers. |
218 | | /// |
219 | | /// TDK_Inconsistent: this argument is the second value deduced |
220 | | /// for the corresponding template parameter. |
221 | | /// |
222 | | /// TDK_DeducedMismatch: this is the (adjusted) call argument type. |
223 | | /// |
224 | | /// TDK_NonDeducedMismatch: this is the mismatching component of the |
225 | | /// 'argument' of the deduction, from which we are deducing arguments. |
226 | | /// |
227 | | /// FIXME: Finish documenting this. |
228 | | TemplateArgument SecondArg; |
229 | | |
230 | | /// The index of the function argument that caused a deduction |
231 | | /// failure. |
232 | | /// |
233 | | /// TDK_DeducedMismatch: this is the index of the argument that had a |
234 | | /// different argument type from its substituted parameter type. |
235 | | unsigned CallArgIndex = 0; |
236 | | |
237 | | /// Information on packs that we're currently expanding. |
238 | | /// |
239 | | /// FIXME: This should be kept internal to SemaTemplateDeduction. |
240 | | SmallVector<DeducedPack *, 8> PendingDeducedPacks; |
241 | | |
242 | | /// \brief The constraint satisfaction details resulting from the associated |
243 | | /// constraints satisfaction tests. |
244 | | ConstraintSatisfaction AssociatedConstraintsSatisfaction; |
245 | | }; |
246 | | |
247 | | } // namespace sema |
248 | | |
249 | | /// A structure used to record information about a failed |
250 | | /// template argument deduction, for diagnosis. |
251 | | struct DeductionFailureInfo { |
252 | | /// A Sema::TemplateDeductionResult. |
253 | | unsigned Result : 8; |
254 | | |
255 | | /// Indicates whether a diagnostic is stored in Diagnostic. |
256 | | unsigned HasDiagnostic : 1; |
257 | | |
258 | | /// Opaque pointer containing additional data about |
259 | | /// this deduction failure. |
260 | | void *Data; |
261 | | |
262 | | /// A diagnostic indicating why deduction failed. |
263 | | alignas(PartialDiagnosticAt) char Diagnostic[sizeof(PartialDiagnosticAt)]; |
264 | | |
265 | | /// Retrieve the diagnostic which caused this deduction failure, |
266 | | /// if any. |
267 | | PartialDiagnosticAt *getSFINAEDiagnostic(); |
268 | | |
269 | | /// Retrieve the template parameter this deduction failure |
270 | | /// refers to, if any. |
271 | | TemplateParameter getTemplateParameter(); |
272 | | |
273 | | /// Retrieve the template argument list associated with this |
274 | | /// deduction failure, if any. |
275 | | TemplateArgumentList *getTemplateArgumentList(); |
276 | | |
277 | | /// Return the first template argument this deduction failure |
278 | | /// refers to, if any. |
279 | | const TemplateArgument *getFirstArg(); |
280 | | |
281 | | /// Return the second template argument this deduction failure |
282 | | /// refers to, if any. |
283 | | const TemplateArgument *getSecondArg(); |
284 | | |
285 | | /// Return the index of the call argument that this deduction |
286 | | /// failure refers to, if any. |
287 | | std::optional<unsigned> getCallArgIndex(); |
288 | | |
289 | | /// Free any memory associated with this deduction failure. |
290 | | void Destroy(); |
291 | | }; |
292 | | |
293 | | /// TemplateSpecCandidate - This is a generalization of OverloadCandidate |
294 | | /// which keeps track of template argument deduction failure info, when |
295 | | /// handling explicit specializations (and instantiations) of templates |
296 | | /// beyond function overloading. |
297 | | /// For now, assume that the candidates are non-matching specializations. |
298 | | /// TODO: In the future, we may need to unify/generalize this with |
299 | | /// OverloadCandidate. |
300 | | struct TemplateSpecCandidate { |
301 | | /// The declaration that was looked up, together with its access. |
302 | | /// Might be a UsingShadowDecl, but usually a FunctionTemplateDecl. |
303 | | DeclAccessPair FoundDecl; |
304 | | |
305 | | /// Specialization - The actual specialization that this candidate |
306 | | /// represents. When NULL, this may be a built-in candidate. |
307 | | Decl *Specialization; |
308 | | |
309 | | /// Template argument deduction info |
310 | | DeductionFailureInfo DeductionFailure; |
311 | | |
312 | 374k | void set(DeclAccessPair Found, Decl *Spec, DeductionFailureInfo Info) { |
313 | 374k | FoundDecl = Found; |
314 | 374k | Specialization = Spec; |
315 | 374k | DeductionFailure = Info; |
316 | 374k | } |
317 | | |
318 | | /// Diagnose a template argument deduction failure. |
319 | | void NoteDeductionFailure(Sema &S, bool ForTakingAddress); |
320 | | }; |
321 | | |
322 | | /// TemplateSpecCandidateSet - A set of generalized overload candidates, |
323 | | /// used in template specializations. |
324 | | /// TODO: In the future, we may need to unify/generalize this with |
325 | | /// OverloadCandidateSet. |
326 | | class TemplateSpecCandidateSet { |
327 | | SmallVector<TemplateSpecCandidate, 16> Candidates; |
328 | | SourceLocation Loc; |
329 | | |
330 | | // Stores whether we're taking the address of these candidates. This helps us |
331 | | // produce better error messages when dealing with the pass_object_size |
332 | | // attribute on parameters. |
333 | | bool ForTakingAddress; |
334 | | |
335 | | void destroyCandidates(); |
336 | | |
337 | | public: |
338 | | TemplateSpecCandidateSet(SourceLocation Loc, bool ForTakingAddress = false) |
339 | 680k | : Loc(Loc), ForTakingAddress(ForTakingAddress) {} |
340 | | TemplateSpecCandidateSet(const TemplateSpecCandidateSet &) = delete; |
341 | | TemplateSpecCandidateSet & |
342 | | operator=(const TemplateSpecCandidateSet &) = delete; |
343 | 680k | ~TemplateSpecCandidateSet() { destroyCandidates(); } |
344 | | |
345 | 518k | SourceLocation getLocation() const { return Loc; } |
346 | | |
347 | | /// Clear out all of the candidates. |
348 | | /// TODO: This may be unnecessary. |
349 | | void clear(); |
350 | | |
351 | | using iterator = SmallVector<TemplateSpecCandidate, 16>::iterator; |
352 | | |
353 | 680k | iterator begin() { return Candidates.begin(); } |
354 | 680k | iterator end() { return Candidates.end(); } |
355 | | |
356 | 189 | size_t size() const { return Candidates.size(); } |
357 | 66 | bool empty() const { return Candidates.empty(); } |
358 | | |
359 | | /// Add a new candidate with NumConversions conversion sequence slots |
360 | | /// to the overload set. |
361 | 374k | TemplateSpecCandidate &addCandidate() { |
362 | 374k | Candidates.emplace_back(); |
363 | 374k | return Candidates.back(); |
364 | 374k | } |
365 | | |
366 | | void NoteCandidates(Sema &S, SourceLocation Loc); |
367 | | |
368 | 23 | void NoteCandidates(Sema &S, SourceLocation Loc) const { |
369 | 23 | const_cast<TemplateSpecCandidateSet *>(this)->NoteCandidates(S, Loc); |
370 | 23 | } |
371 | | }; |
372 | | |
373 | | } // namespace clang |
374 | | |
375 | | #endif // LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H |