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 Warnings (and follow-on notes) that were suppressed due to
44 /// SFINAE while performing template argument deduction.
45 SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics;
47 TemplateDeductionInfo(const TemplateDeductionInfo &) = delete;
48 void operator=(const TemplateDeductionInfo &) = delete;
51 TemplateDeductionInfo(SourceLocation Loc)
52 : Deduced(nullptr), Loc(Loc), HasSFINAEDiagnostic(false),
53 Expression(nullptr) {}
55 /// \brief Returns the location at which template argument is
57 SourceLocation getLocation() const {
61 /// \brief Take ownership of the deduced template argument list.
62 TemplateArgumentList *take() {
63 TemplateArgumentList *Result = Deduced;
68 /// \brief Take ownership of the SFINAE diagnostic.
69 void takeSFINAEDiagnostic(PartialDiagnosticAt &PD) {
70 assert(HasSFINAEDiagnostic);
71 PD.first = SuppressedDiagnostics.front().first;
72 PD.second.swap(SuppressedDiagnostics.front().second);
73 SuppressedDiagnostics.clear();
74 HasSFINAEDiagnostic = false;
77 /// \brief Provide a new template argument list that contains the
78 /// results of template argument deduction.
79 void reset(TemplateArgumentList *NewDeduced) {
83 /// \brief Is a SFINAE diagnostic available?
84 bool hasSFINAEDiagnostic() const {
85 return HasSFINAEDiagnostic;
88 /// \brief Set the diagnostic which caused the SFINAE failure.
89 void addSFINAEDiagnostic(SourceLocation Loc, PartialDiagnostic PD) {
90 // Only collect the first diagnostic.
91 if (HasSFINAEDiagnostic)
93 SuppressedDiagnostics.clear();
94 SuppressedDiagnostics.emplace_back(Loc, std::move(PD));
95 HasSFINAEDiagnostic = true;
98 /// \brief Add a new diagnostic to the set of diagnostics
99 void addSuppressedDiagnostic(SourceLocation Loc,
100 PartialDiagnostic PD) {
101 if (HasSFINAEDiagnostic)
103 SuppressedDiagnostics.emplace_back(Loc, std::move(PD));
106 /// \brief Iterator over the set of suppressed diagnostics.
107 typedef SmallVectorImpl<PartialDiagnosticAt>::const_iterator
110 /// \brief Returns an iterator at the beginning of the sequence of suppressed
112 diag_iterator diag_begin() const { return SuppressedDiagnostics.begin(); }
114 /// \brief Returns an iterator at the end of the sequence of suppressed
116 diag_iterator diag_end() const { return SuppressedDiagnostics.end(); }
118 /// \brief The template parameter to which a template argument
119 /// deduction failure refers.
121 /// Depending on the result of template argument deduction, this
122 /// template parameter may have different meanings:
124 /// TDK_Incomplete: this is the first template parameter whose
125 /// corresponding template argument was not deduced.
127 /// TDK_Inconsistent: this is the template parameter for which
128 /// two different template argument values were deduced.
129 TemplateParameter Param;
131 /// \brief The first template argument to which the template
132 /// argument deduction failure refers.
134 /// Depending on the result of the template argument deduction,
135 /// this template argument may have different meanings:
137 /// TDK_Inconsistent: this argument is the first value deduced
138 /// for the corresponding template parameter.
140 /// TDK_SubstitutionFailure: this argument is the template
141 /// argument we were instantiating when we encountered an error.
143 /// TDK_NonDeducedMismatch: this is the component of the 'parameter'
144 /// of the deduction, directly provided in the source code.
145 TemplateArgument FirstArg;
147 /// \brief The second template argument to which the template
148 /// argument deduction failure refers.
150 /// TDK_NonDeducedMismatch: this is the mismatching component of the
151 /// 'argument' of the deduction, from which we are deducing arguments.
153 /// FIXME: Finish documenting this.
154 TemplateArgument SecondArg;
156 /// \brief The expression which caused a deduction failure.
158 /// TDK_FailedOverloadResolution: this argument is the reference to
159 /// an overloaded function which could not be resolved to a specific
163 /// \brief Information on packs that we're currently expanding.
165 /// FIXME: This should be kept internal to SemaTemplateDeduction.
166 SmallVector<DeducedPack *, 8> PendingDeducedPacks;
169 } // end namespace sema
171 /// A structure used to record information about a failed
172 /// template argument deduction, for diagnosis.
173 struct DeductionFailureInfo {
174 /// A Sema::TemplateDeductionResult.
177 /// \brief Indicates whether a diagnostic is stored in Diagnostic.
178 unsigned HasDiagnostic : 1;
180 /// \brief Opaque pointer containing additional data about
181 /// this deduction failure.
184 /// \brief A diagnostic indicating why deduction failed.
187 char Diagnostic[sizeof(PartialDiagnosticAt)];
190 /// \brief Retrieve the diagnostic which caused this deduction failure,
192 PartialDiagnosticAt *getSFINAEDiagnostic();
194 /// \brief Retrieve the template parameter this deduction failure
195 /// refers to, if any.
196 TemplateParameter getTemplateParameter();
198 /// \brief Retrieve the template argument list associated with this
199 /// deduction failure, if any.
200 TemplateArgumentList *getTemplateArgumentList();
202 /// \brief Return the first template argument this deduction failure
203 /// refers to, if any.
204 const TemplateArgument *getFirstArg();
206 /// \brief Return the second template argument this deduction failure
207 /// refers to, if any.
208 const TemplateArgument *getSecondArg();
210 /// \brief Return the expression this deduction failure refers to,
214 /// \brief Free any memory associated with this deduction failure.
218 /// TemplateSpecCandidate - This is a generalization of OverloadCandidate
219 /// which keeps track of template argument deduction failure info, when
220 /// handling explicit specializations (and instantiations) of templates
221 /// beyond function overloading.
222 /// For now, assume that the candidates are non-matching specializations.
223 /// TODO: In the future, we may need to unify/generalize this with
224 /// OverloadCandidate.
225 struct TemplateSpecCandidate {
226 /// Specialization - The actual specialization that this candidate
227 /// represents. When NULL, this may be a built-in candidate.
228 Decl *Specialization;
230 /// Template argument deduction info
231 DeductionFailureInfo DeductionFailure;
233 void set(Decl *Spec, DeductionFailureInfo Info) {
234 Specialization = Spec;
235 DeductionFailure = Info;
238 /// Diagnose a template argument deduction failure.
239 void NoteDeductionFailure(Sema &S);
242 /// TemplateSpecCandidateSet - A set of generalized overload candidates,
243 /// used in template specializations.
244 /// TODO: In the future, we may need to unify/generalize this with
245 /// OverloadCandidateSet.
246 class TemplateSpecCandidateSet {
247 SmallVector<TemplateSpecCandidate, 16> Candidates;
250 TemplateSpecCandidateSet(
251 const TemplateSpecCandidateSet &) = delete;
252 void operator=(const TemplateSpecCandidateSet &) = delete;
254 void destroyCandidates();
257 TemplateSpecCandidateSet(SourceLocation Loc) : Loc(Loc) {}
258 ~TemplateSpecCandidateSet() { destroyCandidates(); }
260 SourceLocation getLocation() const { return Loc; }
262 /// \brief Clear out all of the candidates.
263 /// TODO: This may be unnecessary.
266 typedef SmallVector<TemplateSpecCandidate, 16>::iterator iterator;
267 iterator begin() { return Candidates.begin(); }
268 iterator end() { return Candidates.end(); }
270 size_t size() const { return Candidates.size(); }
271 bool empty() const { return Candidates.empty(); }
273 /// \brief Add a new candidate with NumConversions conversion sequence slots
274 /// to the overload set.
275 TemplateSpecCandidate &addCandidate() {
276 Candidates.emplace_back();
277 return Candidates.back();
280 void NoteCandidates(Sema &S, SourceLocation Loc);
282 void NoteCandidates(Sema &S, SourceLocation Loc) const {
283 const_cast<TemplateSpecCandidateSet *>(this)->NoteCandidates(S, Loc);
287 } // end namespace clang