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