1 //===- TemplateDeduction.h - C++ template argument deduction ----*- C++ -*-===/
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //===----------------------------------------------------------------------===/
9 // This file provides types used with Sema's template argument deduction
12 //===----------------------------------------------------------------------===/
13 #ifndef LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
14 #define LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
16 #include "clang/AST/DeclTemplate.h"
17 #include "clang/Basic/PartialDiagnostic.h"
18 #include "llvm/ADT/SmallVector.h"
23 class TemplateArgumentList;
28 /// \brief Provides information about an attempted template argument
29 /// deduction, whose success or failure was described by a
30 /// TemplateDeductionResult value.
31 class TemplateDeductionInfo {
32 /// \brief The deduced template argument list.
34 TemplateArgumentList *Deduced;
36 /// \brief The source location at which template argument
37 /// deduction is occurring.
40 /// \brief Have we suppressed an error during deduction?
41 bool HasSFINAEDiagnostic;
43 /// \brief The template parameter depth for which we're performing deduction.
44 unsigned DeducedDepth;
46 /// \brief Warnings (and follow-on notes) that were suppressed due to
47 /// SFINAE while performing template argument deduction.
48 SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics;
50 TemplateDeductionInfo(const TemplateDeductionInfo &) = delete;
51 void operator=(const TemplateDeductionInfo &) = delete;
54 TemplateDeductionInfo(SourceLocation Loc, unsigned DeducedDepth = 0)
55 : Deduced(nullptr), Loc(Loc), HasSFINAEDiagnostic(false),
56 DeducedDepth(DeducedDepth), CallArgIndex(0) {}
58 /// \brief Returns the location at which template argument is
60 SourceLocation getLocation() const {
64 /// \brief The depth of template parameters for which deduction is being
66 unsigned getDeducedDepth() const {
70 /// \brief Take ownership of the deduced template argument list.
71 TemplateArgumentList *take() {
72 TemplateArgumentList *Result = Deduced;
77 /// \brief Take ownership of the SFINAE diagnostic.
78 void takeSFINAEDiagnostic(PartialDiagnosticAt &PD) {
79 assert(HasSFINAEDiagnostic);
80 PD.first = SuppressedDiagnostics.front().first;
81 PD.second.swap(SuppressedDiagnostics.front().second);
82 clearSFINAEDiagnostic();
85 /// \brief Discard any SFINAE diagnostics.
86 void clearSFINAEDiagnostic() {
87 SuppressedDiagnostics.clear();
88 HasSFINAEDiagnostic = false;
91 /// Peek at the SFINAE diagnostic.
92 const PartialDiagnosticAt &peekSFINAEDiagnostic() const {
93 assert(HasSFINAEDiagnostic);
94 return SuppressedDiagnostics.front();
97 /// \brief Provide a new template argument list that contains the
98 /// results of template argument deduction.
99 void reset(TemplateArgumentList *NewDeduced) {
100 Deduced = NewDeduced;
103 /// \brief Is a SFINAE diagnostic available?
104 bool hasSFINAEDiagnostic() const {
105 return HasSFINAEDiagnostic;
108 /// \brief Set the diagnostic which caused the SFINAE failure.
109 void addSFINAEDiagnostic(SourceLocation Loc, PartialDiagnostic PD) {
110 // Only collect the first diagnostic.
111 if (HasSFINAEDiagnostic)
113 SuppressedDiagnostics.clear();
114 SuppressedDiagnostics.emplace_back(Loc, std::move(PD));
115 HasSFINAEDiagnostic = true;
118 /// \brief Add a new diagnostic to the set of diagnostics
119 void addSuppressedDiagnostic(SourceLocation Loc,
120 PartialDiagnostic PD) {
121 if (HasSFINAEDiagnostic)
123 SuppressedDiagnostics.emplace_back(Loc, std::move(PD));
126 /// \brief Iterator over the set of suppressed diagnostics.
127 typedef SmallVectorImpl<PartialDiagnosticAt>::const_iterator
130 /// \brief Returns an iterator at the beginning of the sequence of suppressed
132 diag_iterator diag_begin() const { return SuppressedDiagnostics.begin(); }
134 /// \brief Returns an iterator at the end of the sequence of suppressed
136 diag_iterator diag_end() const { return SuppressedDiagnostics.end(); }
138 /// \brief The template parameter to which a template argument
139 /// deduction failure refers.
141 /// Depending on the result of template argument deduction, this
142 /// template parameter may have different meanings:
144 /// TDK_Incomplete: this is the first template parameter whose
145 /// corresponding template argument was not deduced.
147 /// TDK_Inconsistent: this is the template parameter for which
148 /// two different template argument values were deduced.
149 TemplateParameter Param;
151 /// \brief The first template argument to which the template
152 /// argument deduction failure refers.
154 /// Depending on the result of the template argument deduction,
155 /// this template argument may have different meanings:
157 /// TDK_Inconsistent: this argument is the first value deduced
158 /// for the corresponding template parameter.
160 /// TDK_SubstitutionFailure: this argument is the template
161 /// argument we were instantiating when we encountered an error.
163 /// TDK_DeducedMismatch: this is the parameter type, after substituting
164 /// deduced arguments.
166 /// TDK_NonDeducedMismatch: this is the component of the 'parameter'
167 /// of the deduction, directly provided in the source code.
168 TemplateArgument FirstArg;
170 /// \brief The second template argument to which the template
171 /// argument deduction failure refers.
173 /// TDK_Inconsistent: this argument is the second value deduced
174 /// for the corresponding template parameter.
176 /// TDK_DeducedMismatch: this is the (adjusted) call argument type.
178 /// TDK_NonDeducedMismatch: this is the mismatching component of the
179 /// 'argument' of the deduction, from which we are deducing arguments.
181 /// FIXME: Finish documenting this.
182 TemplateArgument SecondArg;
184 /// \brief The index of the function argument that caused a deduction
187 /// TDK_DeducedMismatch: this is the index of the argument that had a
188 /// different argument type from its substituted parameter type.
189 unsigned CallArgIndex;
191 /// \brief Information on packs that we're currently expanding.
193 /// FIXME: This should be kept internal to SemaTemplateDeduction.
194 SmallVector<DeducedPack *, 8> PendingDeducedPacks;
197 } // end namespace sema
199 /// A structure used to record information about a failed
200 /// template argument deduction, for diagnosis.
201 struct DeductionFailureInfo {
202 /// A Sema::TemplateDeductionResult.
205 /// \brief Indicates whether a diagnostic is stored in Diagnostic.
206 unsigned HasDiagnostic : 1;
208 /// \brief Opaque pointer containing additional data about
209 /// this deduction failure.
212 /// \brief A diagnostic indicating why deduction failed.
213 alignas(PartialDiagnosticAt) char Diagnostic[sizeof(PartialDiagnosticAt)];
215 /// \brief Retrieve the diagnostic which caused this deduction failure,
217 PartialDiagnosticAt *getSFINAEDiagnostic();
219 /// \brief Retrieve the template parameter this deduction failure
220 /// refers to, if any.
221 TemplateParameter getTemplateParameter();
223 /// \brief Retrieve the template argument list associated with this
224 /// deduction failure, if any.
225 TemplateArgumentList *getTemplateArgumentList();
227 /// \brief Return the first template argument this deduction failure
228 /// refers to, if any.
229 const TemplateArgument *getFirstArg();
231 /// \brief Return the second template argument this deduction failure
232 /// refers to, if any.
233 const TemplateArgument *getSecondArg();
235 /// \brief Return the index of the call argument that this deduction
236 /// failure refers to, if any.
237 llvm::Optional<unsigned> getCallArgIndex();
239 /// \brief Free any memory associated with this deduction failure.
243 /// TemplateSpecCandidate - This is a generalization of OverloadCandidate
244 /// which keeps track of template argument deduction failure info, when
245 /// handling explicit specializations (and instantiations) of templates
246 /// beyond function overloading.
247 /// For now, assume that the candidates are non-matching specializations.
248 /// TODO: In the future, we may need to unify/generalize this with
249 /// OverloadCandidate.
250 struct TemplateSpecCandidate {
251 /// \brief The declaration that was looked up, together with its access.
252 /// Might be a UsingShadowDecl, but usually a FunctionTemplateDecl.
253 DeclAccessPair FoundDecl;
255 /// Specialization - The actual specialization that this candidate
256 /// represents. When NULL, this may be a built-in candidate.
257 Decl *Specialization;
259 /// Template argument deduction info
260 DeductionFailureInfo DeductionFailure;
262 void set(DeclAccessPair Found, Decl *Spec, DeductionFailureInfo Info) {
264 Specialization = Spec;
265 DeductionFailure = Info;
268 /// Diagnose a template argument deduction failure.
269 void NoteDeductionFailure(Sema &S, bool ForTakingAddress);
272 /// TemplateSpecCandidateSet - A set of generalized overload candidates,
273 /// used in template specializations.
274 /// TODO: In the future, we may need to unify/generalize this with
275 /// OverloadCandidateSet.
276 class TemplateSpecCandidateSet {
277 SmallVector<TemplateSpecCandidate, 16> Candidates;
279 // Stores whether we're taking the address of these candidates. This helps us
280 // produce better error messages when dealing with the pass_object_size
281 // attribute on parameters.
282 bool ForTakingAddress;
284 TemplateSpecCandidateSet(
285 const TemplateSpecCandidateSet &) = delete;
286 void operator=(const TemplateSpecCandidateSet &) = delete;
288 void destroyCandidates();
291 TemplateSpecCandidateSet(SourceLocation Loc, bool ForTakingAddress = false)
292 : Loc(Loc), ForTakingAddress(ForTakingAddress) {}
293 ~TemplateSpecCandidateSet() { destroyCandidates(); }
295 SourceLocation getLocation() const { return Loc; }
297 /// \brief Clear out all of the candidates.
298 /// TODO: This may be unnecessary.
301 typedef SmallVector<TemplateSpecCandidate, 16>::iterator iterator;
302 iterator begin() { return Candidates.begin(); }
303 iterator end() { return Candidates.end(); }
305 size_t size() const { return Candidates.size(); }
306 bool empty() const { return Candidates.empty(); }
308 /// \brief Add a new candidate with NumConversions conversion sequence slots
309 /// to the overload set.
310 TemplateSpecCandidate &addCandidate() {
311 Candidates.emplace_back();
312 return Candidates.back();
315 void NoteCandidates(Sema &S, SourceLocation Loc);
317 void NoteCandidates(Sema &S, SourceLocation Loc) const {
318 const_cast<TemplateSpecCandidateSet *>(this)->NoteCandidates(S, Loc);
322 } // end namespace clang