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_TEMPLATE_DEDUCTION_H
14 #define LLVM_CLANG_SEMA_TEMPLATE_DEDUCTION_H
16 #include "clang/AST/DeclTemplate.h"
17 #include "clang/Basic/PartialDiagnostic.h"
18 #include "llvm/ADT/SmallVector.h"
22 class TemplateArgumentList;
27 /// \brief Provides information about an attempted template argument
28 /// deduction, whose success or failure was described by a
29 /// TemplateDeductionResult value.
30 class TemplateDeductionInfo {
31 /// \brief The deduced template argument list.
33 TemplateArgumentList *Deduced;
35 /// \brief The source location at which template argument
36 /// deduction is occurring.
39 /// \brief Have we suppressed an error during deduction?
40 bool HasSFINAEDiagnostic;
42 /// \brief Warnings (and follow-on notes) that were suppressed due to
43 /// SFINAE while performing template argument deduction.
44 SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics;
46 TemplateDeductionInfo(const TemplateDeductionInfo &) LLVM_DELETED_FUNCTION;
47 void operator=(const TemplateDeductionInfo &) LLVM_DELETED_FUNCTION;
50 TemplateDeductionInfo(SourceLocation Loc)
51 : Deduced(0), Loc(Loc), HasSFINAEDiagnostic(false), Expression(0) { }
53 /// \brief Returns the location at which template argument is
55 SourceLocation getLocation() const {
59 /// \brief Take ownership of the deduced template argument list.
60 TemplateArgumentList *take() {
61 TemplateArgumentList *Result = Deduced;
66 /// \brief Take ownership of the SFINAE diagnostic.
67 void takeSFINAEDiagnostic(PartialDiagnosticAt &PD) {
68 assert(HasSFINAEDiagnostic);
69 PD.first = SuppressedDiagnostics.front().first;
70 PD.second.swap(SuppressedDiagnostics.front().second);
71 SuppressedDiagnostics.clear();
72 HasSFINAEDiagnostic = false;
75 /// \brief Provide a new template argument list that contains the
76 /// results of template argument deduction.
77 void reset(TemplateArgumentList *NewDeduced) {
81 /// \brief Is a SFINAE diagnostic available?
82 bool hasSFINAEDiagnostic() const {
83 return HasSFINAEDiagnostic;
86 /// \brief Set the diagnostic which caused the SFINAE failure.
87 void addSFINAEDiagnostic(SourceLocation Loc, PartialDiagnostic PD) {
88 // Only collect the first diagnostic.
89 if (HasSFINAEDiagnostic)
91 SuppressedDiagnostics.clear();
92 SuppressedDiagnostics.push_back(
93 std::make_pair(Loc, PartialDiagnostic::NullDiagnostic()));
94 SuppressedDiagnostics.back().second.swap(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.push_back(
104 std::make_pair(Loc, PartialDiagnostic::NullDiagnostic()));
105 SuppressedDiagnostics.back().second.swap(PD);
108 /// \brief Iterator over the set of suppressed diagnostics.
109 typedef SmallVectorImpl<PartialDiagnosticAt>::const_iterator
112 /// \brief Returns an iterator at the beginning of the sequence of suppressed
114 diag_iterator diag_begin() const { return SuppressedDiagnostics.begin(); }
116 /// \brief Returns an iterator at the end of the sequence of suppressed
118 diag_iterator diag_end() const { return SuppressedDiagnostics.end(); }
120 /// \brief The template parameter to which a template argument
121 /// deduction failure refers.
123 /// Depending on the result of template argument deduction, this
124 /// template parameter may have different meanings:
126 /// TDK_Incomplete: this is the first template parameter whose
127 /// corresponding template argument was not deduced.
129 /// TDK_Inconsistent: this is the template parameter for which
130 /// two different template argument values were deduced.
131 TemplateParameter Param;
133 /// \brief The first template argument to which the template
134 /// argument deduction failure refers.
136 /// Depending on the result of the template argument deduction,
137 /// this template argument may have different meanings:
139 /// TDK_Inconsistent: this argument is the first value deduced
140 /// for the corresponding template parameter.
142 /// TDK_SubstitutionFailure: this argument is the template
143 /// argument we were instantiating when we encountered an error.
145 /// TDK_NonDeducedMismatch: this is the component of the 'parameter'
146 /// of the deduction, directly provided in the source code.
147 TemplateArgument FirstArg;
149 /// \brief The second template argument to which the template
150 /// argument deduction failure refers.
152 /// TDK_NonDeducedMismatch: this is the mismatching component of the
153 /// 'argument' of the deduction, from which we are deducing arguments.
155 /// FIXME: Finish documenting this.
156 TemplateArgument SecondArg;
158 /// \brief The expression which caused a deduction failure.
160 /// TDK_FailedOverloadResolution: this argument is the reference to
161 /// an overloaded function which could not be resolved to a specific
166 } // end namespace sema
168 /// A structure used to record information about a failed
169 /// template argument deduction, for diagnosis.
170 struct DeductionFailureInfo {
171 /// A Sema::TemplateDeductionResult.
174 /// \brief Indicates whether a diagnostic is stored in Diagnostic.
175 unsigned HasDiagnostic : 1;
177 /// \brief Opaque pointer containing additional data about
178 /// this deduction failure.
181 /// \brief A diagnostic indicating why deduction failed.
184 char Diagnostic[sizeof(PartialDiagnosticAt)];
187 /// \brief Retrieve the diagnostic which caused this deduction failure,
189 PartialDiagnosticAt *getSFINAEDiagnostic();
191 /// \brief Retrieve the template parameter this deduction failure
192 /// refers to, if any.
193 TemplateParameter getTemplateParameter();
195 /// \brief Retrieve the template argument list associated with this
196 /// deduction failure, if any.
197 TemplateArgumentList *getTemplateArgumentList();
199 /// \brief Return the first template argument this deduction failure
200 /// refers to, if any.
201 const TemplateArgument *getFirstArg();
203 /// \brief Return the second template argument this deduction failure
204 /// refers to, if any.
205 const TemplateArgument *getSecondArg();
207 /// \brief Return the expression this deduction failure refers to,
211 /// \brief Free any memory associated with this deduction failure.
215 /// TemplateSpecCandidate - This is a generalization of OverloadCandidate
216 /// which keeps track of template argument deduction failure info, when
217 /// handling explicit specializations (and instantiations) of templates
218 /// beyond function overloading.
219 /// For now, assume that the candidates are non-matching specializations.
220 /// TODO: In the future, we may need to unify/generalize this with
221 /// OverloadCandidate.
222 struct TemplateSpecCandidate {
223 /// Specialization - The actual specialization that this candidate
224 /// represents. When NULL, this may be a built-in candidate.
225 Decl *Specialization;
227 /// Template argument deduction info
228 DeductionFailureInfo DeductionFailure;
230 void set(Decl *Spec, DeductionFailureInfo Info) {
231 Specialization = Spec;
232 DeductionFailure = Info;
235 /// Diagnose a template argument deduction failure.
236 void NoteDeductionFailure(Sema &S);
239 /// TemplateSpecCandidateSet - A set of generalized overload candidates,
240 /// used in template specializations.
241 /// TODO: In the future, we may need to unify/generalize this with
242 /// OverloadCandidateSet.
243 class TemplateSpecCandidateSet {
244 SmallVector<TemplateSpecCandidate, 16> Candidates;
247 TemplateSpecCandidateSet(
248 const TemplateSpecCandidateSet &) LLVM_DELETED_FUNCTION;
249 void operator=(const TemplateSpecCandidateSet &) LLVM_DELETED_FUNCTION;
251 void destroyCandidates();
254 TemplateSpecCandidateSet(SourceLocation Loc) : Loc(Loc) {}
255 ~TemplateSpecCandidateSet() { destroyCandidates(); }
257 SourceLocation getLocation() const { return Loc; }
259 /// \brief Clear out all of the candidates.
260 /// TODO: This may be unnecessary.
263 typedef SmallVector<TemplateSpecCandidate, 16>::iterator iterator;
264 iterator begin() { return Candidates.begin(); }
265 iterator end() { return Candidates.end(); }
267 size_t size() const { return Candidates.size(); }
268 bool empty() const { return Candidates.empty(); }
270 /// \brief Add a new candidate with NumConversions conversion sequence slots
271 /// to the overload set.
272 TemplateSpecCandidate &addCandidate() {
273 Candidates.push_back(TemplateSpecCandidate());
274 return Candidates.back();
277 void NoteCandidates(Sema &S, SourceLocation Loc);
279 void NoteCandidates(Sema &S, SourceLocation Loc) const {
280 const_cast<TemplateSpecCandidateSet *>(this)->NoteCandidates(S, Loc);
284 } // end namespace clang