xref: /minix3/external/bsd/llvm/dist/clang/include/clang/Sema/TemplateDeduction.h (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1 //===- TemplateDeduction.h - C++ template argument deduction ----*- C++ -*-===/
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //===----------------------------------------------------------------------===/
8 //
9 //  This file provides types used with Sema's template argument deduction
10 // routines.
11 //
12 //===----------------------------------------------------------------------===/
13 #ifndef LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
14 #define LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
15 
16 #include "clang/AST/DeclTemplate.h"
17 #include "clang/Basic/PartialDiagnostic.h"
18 #include "llvm/ADT/SmallVector.h"
19 
20 namespace clang {
21 
22 struct DeducedPack;
23 class TemplateArgumentList;
24 class Sema;
25 
26 namespace sema {
27 
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.
33   ///
34   TemplateArgumentList *Deduced;
35 
36   /// \brief The source location at which template argument
37   /// deduction is occurring.
38   SourceLocation Loc;
39 
40   /// \brief Have we suppressed an error during deduction?
41   bool HasSFINAEDiagnostic;
42 
43   /// \brief Warnings (and follow-on notes) that were suppressed due to
44   /// SFINAE while performing template argument deduction.
45   SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics;
46 
47   TemplateDeductionInfo(const TemplateDeductionInfo &) LLVM_DELETED_FUNCTION;
48   void operator=(const TemplateDeductionInfo &) LLVM_DELETED_FUNCTION;
49 
50 public:
TemplateDeductionInfo(SourceLocation Loc)51   TemplateDeductionInfo(SourceLocation Loc)
52     : Deduced(nullptr), Loc(Loc), HasSFINAEDiagnostic(false),
53       Expression(nullptr) {}
54 
55   /// \brief Returns the location at which template argument is
56   /// occurring.
getLocation()57   SourceLocation getLocation() const {
58     return Loc;
59   }
60 
61   /// \brief Take ownership of the deduced template argument list.
take()62   TemplateArgumentList *take() {
63     TemplateArgumentList *Result = Deduced;
64     Deduced = nullptr;
65     return Result;
66   }
67 
68   /// \brief Take ownership of the SFINAE diagnostic.
takeSFINAEDiagnostic(PartialDiagnosticAt & PD)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;
75   }
76 
77   /// \brief Provide a new template argument list that contains the
78   /// results of template argument deduction.
reset(TemplateArgumentList * NewDeduced)79   void reset(TemplateArgumentList *NewDeduced) {
80     Deduced = NewDeduced;
81   }
82 
83   /// \brief Is a SFINAE diagnostic available?
hasSFINAEDiagnostic()84   bool hasSFINAEDiagnostic() const {
85     return HasSFINAEDiagnostic;
86   }
87 
88   /// \brief Set the diagnostic which caused the SFINAE failure.
addSFINAEDiagnostic(SourceLocation Loc,PartialDiagnostic PD)89   void addSFINAEDiagnostic(SourceLocation Loc, PartialDiagnostic PD) {
90     // Only collect the first diagnostic.
91     if (HasSFINAEDiagnostic)
92       return;
93     SuppressedDiagnostics.clear();
94     SuppressedDiagnostics.push_back(
95         std::make_pair(Loc, PartialDiagnostic::NullDiagnostic()));
96     SuppressedDiagnostics.back().second.swap(PD);
97     HasSFINAEDiagnostic = true;
98   }
99 
100   /// \brief Add a new diagnostic to the set of diagnostics
addSuppressedDiagnostic(SourceLocation Loc,PartialDiagnostic PD)101   void addSuppressedDiagnostic(SourceLocation Loc,
102                                PartialDiagnostic PD) {
103     if (HasSFINAEDiagnostic)
104       return;
105     SuppressedDiagnostics.push_back(
106         std::make_pair(Loc, PartialDiagnostic::NullDiagnostic()));
107     SuppressedDiagnostics.back().second.swap(PD);
108   }
109 
110   /// \brief Iterator over the set of suppressed diagnostics.
111   typedef SmallVectorImpl<PartialDiagnosticAt>::const_iterator
112     diag_iterator;
113 
114   /// \brief Returns an iterator at the beginning of the sequence of suppressed
115   /// diagnostics.
diag_begin()116   diag_iterator diag_begin() const { return SuppressedDiagnostics.begin(); }
117 
118   /// \brief Returns an iterator at the end of the sequence of suppressed
119   /// diagnostics.
diag_end()120   diag_iterator diag_end() const { return SuppressedDiagnostics.end(); }
121 
122   /// \brief The template parameter to which a template argument
123   /// deduction failure refers.
124   ///
125   /// Depending on the result of template argument deduction, this
126   /// template parameter may have different meanings:
127   ///
128   ///   TDK_Incomplete: this is the first template parameter whose
129   ///   corresponding template argument was not deduced.
130   ///
131   ///   TDK_Inconsistent: this is the template parameter for which
132   ///   two different template argument values were deduced.
133   TemplateParameter Param;
134 
135   /// \brief The first template argument to which the template
136   /// argument deduction failure refers.
137   ///
138   /// Depending on the result of the template argument deduction,
139   /// this template argument may have different meanings:
140   ///
141   ///   TDK_Inconsistent: this argument is the first value deduced
142   ///   for the corresponding template parameter.
143   ///
144   ///   TDK_SubstitutionFailure: this argument is the template
145   ///   argument we were instantiating when we encountered an error.
146   ///
147   ///   TDK_NonDeducedMismatch: this is the component of the 'parameter'
148   ///   of the deduction, directly provided in the source code.
149   TemplateArgument FirstArg;
150 
151   /// \brief The second template argument to which the template
152   /// argument deduction failure refers.
153   ///
154   ///   TDK_NonDeducedMismatch: this is the mismatching component of the
155   ///   'argument' of the deduction, from which we are deducing arguments.
156   ///
157   /// FIXME: Finish documenting this.
158   TemplateArgument SecondArg;
159 
160   /// \brief The expression which caused a deduction failure.
161   ///
162   ///   TDK_FailedOverloadResolution: this argument is the reference to
163   ///   an overloaded function which could not be resolved to a specific
164   ///   function.
165   Expr *Expression;
166 
167   /// \brief Information on packs that we're currently expanding.
168   ///
169   /// FIXME: This should be kept internal to SemaTemplateDeduction.
170   SmallVector<DeducedPack *, 8> PendingDeducedPacks;
171 };
172 
173 } // end namespace sema
174 
175 /// A structure used to record information about a failed
176 /// template argument deduction, for diagnosis.
177 struct DeductionFailureInfo {
178   /// A Sema::TemplateDeductionResult.
179   unsigned Result : 8;
180 
181   /// \brief Indicates whether a diagnostic is stored in Diagnostic.
182   unsigned HasDiagnostic : 1;
183 
184   /// \brief Opaque pointer containing additional data about
185   /// this deduction failure.
186   void *Data;
187 
188   /// \brief A diagnostic indicating why deduction failed.
189   union {
190     void *Align;
191     char Diagnostic[sizeof(PartialDiagnosticAt)];
192   };
193 
194   /// \brief Retrieve the diagnostic which caused this deduction failure,
195   /// if any.
196   PartialDiagnosticAt *getSFINAEDiagnostic();
197 
198   /// \brief Retrieve the template parameter this deduction failure
199   /// refers to, if any.
200   TemplateParameter getTemplateParameter();
201 
202   /// \brief Retrieve the template argument list associated with this
203   /// deduction failure, if any.
204   TemplateArgumentList *getTemplateArgumentList();
205 
206   /// \brief Return the first template argument this deduction failure
207   /// refers to, if any.
208   const TemplateArgument *getFirstArg();
209 
210   /// \brief Return the second template argument this deduction failure
211   /// refers to, if any.
212   const TemplateArgument *getSecondArg();
213 
214   /// \brief Return the expression this deduction failure refers to,
215   /// if any.
216   Expr *getExpr();
217 
218   /// \brief Free any memory associated with this deduction failure.
219   void Destroy();
220 };
221 
222 /// TemplateSpecCandidate - This is a generalization of OverloadCandidate
223 /// which keeps track of template argument deduction failure info, when
224 /// handling explicit specializations (and instantiations) of templates
225 /// beyond function overloading.
226 /// For now, assume that the candidates are non-matching specializations.
227 /// TODO: In the future, we may need to unify/generalize this with
228 /// OverloadCandidate.
229 struct TemplateSpecCandidate {
230   /// Specialization - The actual specialization that this candidate
231   /// represents. When NULL, this may be a built-in candidate.
232   Decl *Specialization;
233 
234   /// Template argument deduction info
235   DeductionFailureInfo DeductionFailure;
236 
setTemplateSpecCandidate237   void set(Decl *Spec, DeductionFailureInfo Info) {
238     Specialization = Spec;
239     DeductionFailure = Info;
240   }
241 
242   /// Diagnose a template argument deduction failure.
243   void NoteDeductionFailure(Sema &S);
244 };
245 
246 /// TemplateSpecCandidateSet - A set of generalized overload candidates,
247 /// used in template specializations.
248 /// TODO: In the future, we may need to unify/generalize this with
249 /// OverloadCandidateSet.
250 class TemplateSpecCandidateSet {
251   SmallVector<TemplateSpecCandidate, 16> Candidates;
252   SourceLocation Loc;
253 
254   TemplateSpecCandidateSet(
255       const TemplateSpecCandidateSet &) LLVM_DELETED_FUNCTION;
256   void operator=(const TemplateSpecCandidateSet &) LLVM_DELETED_FUNCTION;
257 
258   void destroyCandidates();
259 
260 public:
TemplateSpecCandidateSet(SourceLocation Loc)261   TemplateSpecCandidateSet(SourceLocation Loc) : Loc(Loc) {}
~TemplateSpecCandidateSet()262   ~TemplateSpecCandidateSet() { destroyCandidates(); }
263 
getLocation()264   SourceLocation getLocation() const { return Loc; }
265 
266   /// \brief Clear out all of the candidates.
267   /// TODO: This may be unnecessary.
268   void clear();
269 
270   typedef SmallVector<TemplateSpecCandidate, 16>::iterator iterator;
begin()271   iterator begin() { return Candidates.begin(); }
end()272   iterator end() { return Candidates.end(); }
273 
size()274   size_t size() const { return Candidates.size(); }
empty()275   bool empty() const { return Candidates.empty(); }
276 
277   /// \brief Add a new candidate with NumConversions conversion sequence slots
278   /// to the overload set.
addCandidate()279   TemplateSpecCandidate &addCandidate() {
280     Candidates.push_back(TemplateSpecCandidate());
281     return Candidates.back();
282   }
283 
284   void NoteCandidates(Sema &S, SourceLocation Loc);
285 
NoteCandidates(Sema & S,SourceLocation Loc)286   void NoteCandidates(Sema &S, SourceLocation Loc) const {
287     const_cast<TemplateSpecCandidateSet *>(this)->NoteCandidates(S, Loc);
288   }
289 };
290 
291 } // end namespace clang
292 
293 #endif
294