]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/Sema/TemplateDeduction.h
MFV: r329021
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / include / clang / Sema / TemplateDeduction.h
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 The template parameter depth for which we're performing deduction.
44   unsigned DeducedDepth;
45
46   /// \brief Warnings (and follow-on notes) that were suppressed due to
47   /// SFINAE while performing template argument deduction.
48   SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics;
49
50   TemplateDeductionInfo(const TemplateDeductionInfo &) = delete;
51   void operator=(const TemplateDeductionInfo &) = delete;
52
53 public:
54   TemplateDeductionInfo(SourceLocation Loc, unsigned DeducedDepth = 0)
55     : Deduced(nullptr), Loc(Loc), HasSFINAEDiagnostic(false),
56       DeducedDepth(DeducedDepth), CallArgIndex(0) {}
57
58   /// \brief Returns the location at which template argument is
59   /// occurring.
60   SourceLocation getLocation() const {
61     return Loc;
62   }
63
64   /// \brief The depth of template parameters for which deduction is being
65   /// performed.
66   unsigned getDeducedDepth() const {
67     return DeducedDepth;
68   }
69
70   /// \brief Take ownership of the deduced template argument list.
71   TemplateArgumentList *take() {
72     TemplateArgumentList *Result = Deduced;
73     Deduced = nullptr;
74     return Result;
75   }
76
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();
83   }
84
85   /// \brief Discard any SFINAE diagnostics.
86   void clearSFINAEDiagnostic() {
87     SuppressedDiagnostics.clear();
88     HasSFINAEDiagnostic = false;
89   }
90
91   /// Peek at the SFINAE diagnostic.
92   const PartialDiagnosticAt &peekSFINAEDiagnostic() const {
93     assert(HasSFINAEDiagnostic);
94     return SuppressedDiagnostics.front();
95   }
96
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;
101   }
102
103   /// \brief Is a SFINAE diagnostic available?
104   bool hasSFINAEDiagnostic() const {
105     return HasSFINAEDiagnostic;
106   }
107
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)
112       return;
113     SuppressedDiagnostics.clear();
114     SuppressedDiagnostics.emplace_back(Loc, std::move(PD));
115     HasSFINAEDiagnostic = true;
116   }
117
118   /// \brief Add a new diagnostic to the set of diagnostics
119   void addSuppressedDiagnostic(SourceLocation Loc,
120                                PartialDiagnostic PD) {
121     if (HasSFINAEDiagnostic)
122       return;
123     SuppressedDiagnostics.emplace_back(Loc, std::move(PD));
124   }
125
126   /// \brief Iterator over the set of suppressed diagnostics.
127   typedef SmallVectorImpl<PartialDiagnosticAt>::const_iterator
128     diag_iterator;
129
130   /// \brief Returns an iterator at the beginning of the sequence of suppressed
131   /// diagnostics.
132   diag_iterator diag_begin() const { return SuppressedDiagnostics.begin(); }
133
134   /// \brief Returns an iterator at the end of the sequence of suppressed
135   /// diagnostics.
136   diag_iterator diag_end() const { return SuppressedDiagnostics.end(); }
137
138   /// \brief The template parameter to which a template argument
139   /// deduction failure refers.
140   ///
141   /// Depending on the result of template argument deduction, this
142   /// template parameter may have different meanings:
143   ///
144   ///   TDK_Incomplete: this is the first template parameter whose
145   ///   corresponding template argument was not deduced.
146   ///
147   ///   TDK_Inconsistent: this is the template parameter for which
148   ///   two different template argument values were deduced.
149   TemplateParameter Param;
150
151   /// \brief The first template argument to which the template
152   /// argument deduction failure refers.
153   ///
154   /// Depending on the result of the template argument deduction,
155   /// this template argument may have different meanings:
156   ///
157   ///   TDK_Inconsistent: this argument is the first value deduced
158   ///   for the corresponding template parameter.
159   ///
160   ///   TDK_SubstitutionFailure: this argument is the template
161   ///   argument we were instantiating when we encountered an error.
162   ///
163   ///   TDK_DeducedMismatch: this is the parameter type, after substituting
164   ///   deduced arguments.
165   ///
166   ///   TDK_NonDeducedMismatch: this is the component of the 'parameter'
167   ///   of the deduction, directly provided in the source code.
168   TemplateArgument FirstArg;
169
170   /// \brief The second template argument to which the template
171   /// argument deduction failure refers.
172   ///
173   ///   TDK_Inconsistent: this argument is the second value deduced
174   ///   for the corresponding template parameter.
175   ///
176   ///   TDK_DeducedMismatch: this is the (adjusted) call argument type.
177   ///
178   ///   TDK_NonDeducedMismatch: this is the mismatching component of the
179   ///   'argument' of the deduction, from which we are deducing arguments.
180   ///
181   /// FIXME: Finish documenting this.
182   TemplateArgument SecondArg;
183
184   /// \brief The index of the function argument that caused a deduction
185   /// failure.
186   ///
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;
190
191   /// \brief Information on packs that we're currently expanding.
192   ///
193   /// FIXME: This should be kept internal to SemaTemplateDeduction.
194   SmallVector<DeducedPack *, 8> PendingDeducedPacks;
195 };
196
197 } // end namespace sema
198
199 /// A structure used to record information about a failed
200 /// template argument deduction, for diagnosis.
201 struct DeductionFailureInfo {
202   /// A Sema::TemplateDeductionResult.
203   unsigned Result : 8;
204
205   /// \brief Indicates whether a diagnostic is stored in Diagnostic.
206   unsigned HasDiagnostic : 1;
207
208   /// \brief Opaque pointer containing additional data about
209   /// this deduction failure.
210   void *Data;
211
212   /// \brief A diagnostic indicating why deduction failed.
213   alignas(PartialDiagnosticAt) char Diagnostic[sizeof(PartialDiagnosticAt)];
214
215   /// \brief Retrieve the diagnostic which caused this deduction failure,
216   /// if any.
217   PartialDiagnosticAt *getSFINAEDiagnostic();
218
219   /// \brief Retrieve the template parameter this deduction failure
220   /// refers to, if any.
221   TemplateParameter getTemplateParameter();
222
223   /// \brief Retrieve the template argument list associated with this
224   /// deduction failure, if any.
225   TemplateArgumentList *getTemplateArgumentList();
226
227   /// \brief Return the first template argument this deduction failure
228   /// refers to, if any.
229   const TemplateArgument *getFirstArg();
230
231   /// \brief Return the second template argument this deduction failure
232   /// refers to, if any.
233   const TemplateArgument *getSecondArg();
234
235   /// \brief Return the index of the call argument that this deduction
236   /// failure refers to, if any.
237   llvm::Optional<unsigned> getCallArgIndex();
238
239   /// \brief Free any memory associated with this deduction failure.
240   void Destroy();
241 };
242
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;
254
255   /// Specialization - The actual specialization that this candidate
256   /// represents. When NULL, this may be a built-in candidate.
257   Decl *Specialization;
258
259   /// Template argument deduction info
260   DeductionFailureInfo DeductionFailure;
261
262   void set(DeclAccessPair Found, Decl *Spec, DeductionFailureInfo Info) {
263     FoundDecl = Found;
264     Specialization = Spec;
265     DeductionFailure = Info;
266   }
267
268   /// Diagnose a template argument deduction failure.
269   void NoteDeductionFailure(Sema &S, bool ForTakingAddress);
270 };
271
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;
278   SourceLocation Loc;
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;
283
284   TemplateSpecCandidateSet(
285       const TemplateSpecCandidateSet &) = delete;
286   void operator=(const TemplateSpecCandidateSet &) = delete;
287
288   void destroyCandidates();
289
290 public:
291   TemplateSpecCandidateSet(SourceLocation Loc, bool ForTakingAddress = false)
292       : Loc(Loc), ForTakingAddress(ForTakingAddress) {}
293   ~TemplateSpecCandidateSet() { destroyCandidates(); }
294
295   SourceLocation getLocation() const { return Loc; }
296
297   /// \brief Clear out all of the candidates.
298   /// TODO: This may be unnecessary.
299   void clear();
300
301   typedef SmallVector<TemplateSpecCandidate, 16>::iterator iterator;
302   iterator begin() { return Candidates.begin(); }
303   iterator end() { return Candidates.end(); }
304
305   size_t size() const { return Candidates.size(); }
306   bool empty() const { return Candidates.empty(); }
307
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();
313   }
314
315   void NoteCandidates(Sema &S, SourceLocation Loc);
316
317   void NoteCandidates(Sema &S, SourceLocation Loc) const {
318     const_cast<TemplateSpecCandidateSet *>(this)->NoteCandidates(S, Loc);
319   }
320 };
321
322 } // end namespace clang
323
324 #endif