clang  10.0.0svn
TemplateDeduction.h
Go to the documentation of this file.
1 //===- TemplateDeduction.h - C++ template argument deduction ----*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file provides types used with Sema's template argument deduction
10 // routines.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
15 #define LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
16 
18 #include "clang/AST/DeclTemplate.h"
19 #include "clang/AST/TemplateBase.h"
22 #include "llvm/ADT/Optional.h"
23 #include "llvm/ADT/SmallVector.h"
24 #include <cassert>
25 #include <cstddef>
26 #include <utility>
27 
28 namespace clang {
29 
30 class Decl;
31 struct DeducedPack;
32 class Sema;
33 
34 namespace sema {
35 
36 /// Provides information about an attempted template argument
37 /// deduction, whose success or failure was described by a
38 /// TemplateDeductionResult value.
40  /// The deduced template argument list.
41  TemplateArgumentList *Deduced = nullptr;
42 
43  /// The source location at which template argument
44  /// deduction is occurring.
45  SourceLocation Loc;
46 
47  /// Have we suppressed an error during deduction?
48  bool HasSFINAEDiagnostic = false;
49 
50  /// The template parameter depth for which we're performing deduction.
51  unsigned DeducedDepth;
52 
53  /// The number of parameters with explicitly-specified template arguments,
54  /// up to and including the partially-specified pack (if any).
55  unsigned ExplicitArgs = 0;
56 
57  /// Warnings (and follow-on notes) that were suppressed due to
58  /// SFINAE while performing template argument deduction.
59  SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics;
60 
61 public:
62  TemplateDeductionInfo(SourceLocation Loc, unsigned DeducedDepth = 0)
63  : Loc(Loc), DeducedDepth(DeducedDepth) {}
66 
67  /// Returns the location at which template argument is
68  /// occurring.
70  return Loc;
71  }
72 
73  /// The depth of template parameters for which deduction is being
74  /// performed.
75  unsigned getDeducedDepth() const {
76  return DeducedDepth;
77  }
78 
79  /// Get the number of explicitly-specified arguments.
80  unsigned getNumExplicitArgs() const {
81  return ExplicitArgs;
82  }
83 
84  /// Take ownership of the deduced template argument list.
86  TemplateArgumentList *Result = Deduced;
87  Deduced = nullptr;
88  return Result;
89  }
90 
91  /// Take ownership of the SFINAE diagnostic.
93  assert(HasSFINAEDiagnostic);
94  PD.first = SuppressedDiagnostics.front().first;
95  PD.second.swap(SuppressedDiagnostics.front().second);
97  }
98 
99  /// Discard any SFINAE diagnostics.
101  SuppressedDiagnostics.clear();
102  HasSFINAEDiagnostic = false;
103  }
104 
105  /// Peek at the SFINAE diagnostic.
107  assert(HasSFINAEDiagnostic);
108  return SuppressedDiagnostics.front();
109  }
110 
111  /// Provide an initial template argument list that contains the
112  /// explicitly-specified arguments.
114  Deduced = NewDeduced;
115  ExplicitArgs = Deduced->size();
116  }
117 
118  /// Provide a new template argument list that contains the
119  /// results of template argument deduction.
120  void reset(TemplateArgumentList *NewDeduced) {
121  Deduced = NewDeduced;
122  }
123 
124  /// Is a SFINAE diagnostic available?
125  bool hasSFINAEDiagnostic() const {
126  return HasSFINAEDiagnostic;
127  }
128 
129  /// Set the diagnostic which caused the SFINAE failure.
131  // Only collect the first diagnostic.
132  if (HasSFINAEDiagnostic)
133  return;
134  SuppressedDiagnostics.clear();
135  SuppressedDiagnostics.emplace_back(Loc, std::move(PD));
136  HasSFINAEDiagnostic = true;
137  }
138 
139  /// Add a new diagnostic to the set of diagnostics
141  PartialDiagnostic PD) {
142  if (HasSFINAEDiagnostic)
143  return;
144  SuppressedDiagnostics.emplace_back(Loc, std::move(PD));
145  }
146 
147  /// Iterator over the set of suppressed diagnostics.
149 
150  /// Returns an iterator at the beginning of the sequence of suppressed
151  /// diagnostics.
152  diag_iterator diag_begin() const { return SuppressedDiagnostics.begin(); }
153 
154  /// Returns an iterator at the end of the sequence of suppressed
155  /// diagnostics.
156  diag_iterator diag_end() const { return SuppressedDiagnostics.end(); }
157 
158  /// The template parameter to which a template argument
159  /// deduction failure refers.
160  ///
161  /// Depending on the result of template argument deduction, this
162  /// template parameter may have different meanings:
163  ///
164  /// TDK_Incomplete: this is the first template parameter whose
165  /// corresponding template argument was not deduced.
166  ///
167  /// TDK_IncompletePack: this is the expanded parameter pack for
168  /// which we deduced too few arguments.
169  ///
170  /// TDK_Inconsistent: this is the template parameter for which
171  /// two different template argument values were deduced.
173 
174  /// The first template argument to which the template
175  /// argument deduction failure refers.
176  ///
177  /// Depending on the result of the template argument deduction,
178  /// this template argument may have different meanings:
179  ///
180  /// TDK_IncompletePack: this is the number of arguments we deduced
181  /// for the pack.
182  ///
183  /// TDK_Inconsistent: this argument is the first value deduced
184  /// for the corresponding template parameter.
185  ///
186  /// TDK_SubstitutionFailure: this argument is the template
187  /// argument we were instantiating when we encountered an error.
188  ///
189  /// TDK_DeducedMismatch: this is the parameter type, after substituting
190  /// deduced arguments.
191  ///
192  /// TDK_NonDeducedMismatch: this is the component of the 'parameter'
193  /// of the deduction, directly provided in the source code.
195 
196  /// The second template argument to which the template
197  /// argument deduction failure refers.
198  ///
199  /// TDK_Inconsistent: this argument is the second value deduced
200  /// for the corresponding template parameter.
201  ///
202  /// TDK_DeducedMismatch: this is the (adjusted) call argument type.
203  ///
204  /// TDK_NonDeducedMismatch: this is the mismatching component of the
205  /// 'argument' of the deduction, from which we are deducing arguments.
206  ///
207  /// FIXME: Finish documenting this.
209 
210  /// The index of the function argument that caused a deduction
211  /// failure.
212  ///
213  /// TDK_DeducedMismatch: this is the index of the argument that had a
214  /// different argument type from its substituted parameter type.
215  unsigned CallArgIndex = 0;
216 
217  /// Information on packs that we're currently expanding.
218  ///
219  /// FIXME: This should be kept internal to SemaTemplateDeduction.
221 };
222 
223 } // namespace sema
224 
225 /// A structure used to record information about a failed
226 /// template argument deduction, for diagnosis.
228  /// A Sema::TemplateDeductionResult.
229  unsigned Result : 8;
230 
231  /// Indicates whether a diagnostic is stored in Diagnostic.
232  unsigned HasDiagnostic : 1;
233 
234  /// Opaque pointer containing additional data about
235  /// this deduction failure.
236  void *Data;
237 
238  /// A diagnostic indicating why deduction failed.
240 
241  /// Retrieve the diagnostic which caused this deduction failure,
242  /// if any.
243  PartialDiagnosticAt *getSFINAEDiagnostic();
244 
245  /// Retrieve the template parameter this deduction failure
246  /// refers to, if any.
247  TemplateParameter getTemplateParameter();
248 
249  /// Retrieve the template argument list associated with this
250  /// deduction failure, if any.
251  TemplateArgumentList *getTemplateArgumentList();
252 
253  /// Return the first template argument this deduction failure
254  /// refers to, if any.
255  const TemplateArgument *getFirstArg();
256 
257  /// Return the second template argument this deduction failure
258  /// refers to, if any.
259  const TemplateArgument *getSecondArg();
260 
261  /// Return the index of the call argument that this deduction
262  /// failure refers to, if any.
263  llvm::Optional<unsigned> getCallArgIndex();
264 
265  /// Free any memory associated with this deduction failure.
266  void Destroy();
267 };
268 
269 /// TemplateSpecCandidate - This is a generalization of OverloadCandidate
270 /// which keeps track of template argument deduction failure info, when
271 /// handling explicit specializations (and instantiations) of templates
272 /// beyond function overloading.
273 /// For now, assume that the candidates are non-matching specializations.
274 /// TODO: In the future, we may need to unify/generalize this with
275 /// OverloadCandidate.
277  /// The declaration that was looked up, together with its access.
278  /// Might be a UsingShadowDecl, but usually a FunctionTemplateDecl.
280 
281  /// Specialization - The actual specialization that this candidate
282  /// represents. When NULL, this may be a built-in candidate.
284 
285  /// Template argument deduction info
287 
288  void set(DeclAccessPair Found, Decl *Spec, DeductionFailureInfo Info) {
289  FoundDecl = Found;
290  Specialization = Spec;
291  DeductionFailure = Info;
292  }
293 
294  /// Diagnose a template argument deduction failure.
295  void NoteDeductionFailure(Sema &S, bool ForTakingAddress);
296 };
297 
298 /// TemplateSpecCandidateSet - A set of generalized overload candidates,
299 /// used in template specializations.
300 /// TODO: In the future, we may need to unify/generalize this with
301 /// OverloadCandidateSet.
304  SourceLocation Loc;
305 
306  // Stores whether we're taking the address of these candidates. This helps us
307  // produce better error messages when dealing with the pass_object_size
308  // attribute on parameters.
309  bool ForTakingAddress;
310 
311  void destroyCandidates();
312 
313 public:
314  TemplateSpecCandidateSet(SourceLocation Loc, bool ForTakingAddress = false)
315  : Loc(Loc), ForTakingAddress(ForTakingAddress) {}
318  operator=(const TemplateSpecCandidateSet &) = delete;
319  ~TemplateSpecCandidateSet() { destroyCandidates(); }
320 
321  SourceLocation getLocation() const { return Loc; }
322 
323  /// Clear out all of the candidates.
324  /// TODO: This may be unnecessary.
325  void clear();
326 
328 
329  iterator begin() { return Candidates.begin(); }
330  iterator end() { return Candidates.end(); }
331 
332  size_t size() const { return Candidates.size(); }
333  bool empty() const { return Candidates.empty(); }
334 
335  /// Add a new candidate with NumConversions conversion sequence slots
336  /// to the overload set.
338  Candidates.emplace_back();
339  return Candidates.back();
340  }
341 
342  void NoteCandidates(Sema &S, SourceLocation Loc);
343 
344  void NoteCandidates(Sema &S, SourceLocation Loc) const {
345  const_cast<TemplateSpecCandidateSet *>(this)->NoteCandidates(S, Loc);
346  }
347 };
348 
349 } // namespace clang
350 
351 #endif // LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
llvm::PointerUnion3< TemplateTypeParmDecl *, NonTypeTemplateParmDecl *, TemplateTemplateParmDecl * > TemplateParameter
Stores a template parameter of any kind.
Definition: DeclTemplate.h:61
const PartialDiagnosticAt & peekSFINAEDiagnostic() const
Peek at the SFINAE diagnostic.
A structure used to record information about a failed template argument deduction, for diagnosis.
Provides information about an attempted template argument deduction, whose success or failure was des...
unsigned size() const
Retrieve the number of template arguments in this template argument list.
Definition: DeclTemplate.h:274
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:88
TemplateDeductionInfo & operator=(const TemplateDeductionInfo &)=delete
Defines the C++ template declaration subclasses.
virtual void clear()
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
void addSuppressedDiagnostic(SourceLocation Loc, PartialDiagnostic PD)
Add a new diagnostic to the set of diagnostics.
void clearSFINAEDiagnostic()
Discard any SFINAE diagnostics.
Decl * Specialization
Specialization - The actual specialization that this candidate represents.
TemplateParameter Param
The template parameter to which a template argument deduction failure refers.
void NoteCandidates(Sema &S, SourceLocation Loc) const
TemplateSpecCandidateSet - A set of generalized overload candidates, used in template specializations...
DeductionFailureInfo DeductionFailure
Template argument deduction info.
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:328
void reset(TemplateArgumentList *NewDeduced)
Provide a new template argument list that contains the results of template argument deduction...
unsigned Result
A Sema::TemplateDeductionResult.
void setExplicitArgs(TemplateArgumentList *NewDeduced)
Provide an initial template argument list that contains the explicitly-specified arguments.
TemplateSpecCandidateSet(SourceLocation Loc, bool ForTakingAddress=false)
bool Destroy(InterpState &S, CodePtr OpPC, uint32_t I)
Definition: Interp.h:794
SourceLocation getLocation() const
Returns the location at which template argument is occurring.
void takeSFINAEDiagnostic(PartialDiagnosticAt &PD)
Take ownership of the SFINAE diagnostic.
TemplateDeductionInfo(SourceLocation Loc, unsigned DeducedDepth=0)
SmallVector< DeducedPack *, 8 > PendingDeducedPacks
Information on packs that we&#39;re currently expanding.
Encodes a location in the source.
void addSFINAEDiagnostic(SourceLocation Loc, PartialDiagnostic PD)
Set the diagnostic which caused the SFINAE failure.
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs. ...
unsigned HasDiagnostic
Indicates whether a diagnostic is stored in Diagnostic.
unsigned getDeducedDepth() const
The depth of template parameters for which deduction is being performed.
diag_iterator diag_end() const
Returns an iterator at the end of the sequence of suppressed diagnostics.
DeclAccessPair FoundDecl
The declaration that was looked up, together with its access.
SourceLocation getLocation() const
A POD class for pairing a NamedDecl* with an access specifier.
Represents a template argument.
Definition: TemplateBase.h:50
Dataflow Directional Tag Classes.
TemplateSpecCandidate & addCandidate()
Add a new candidate with NumConversions conversion sequence slots to the overload set...
void * Data
Opaque pointer containing additional data about this deduction failure.
bool hasSFINAEDiagnostic() const
Is a SFINAE diagnostic available?
TemplateArgumentList * take()
Take ownership of the deduced template argument list.
TemplateSpecCandidate - This is a generalization of OverloadCandidate which keeps track of template a...
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream...
A template argument list.
Definition: DeclTemplate.h:214
Defines the clang::SourceLocation class and associated facilities.
unsigned getNumExplicitArgs() const
Get the number of explicitly-specified arguments.
TemplateArgument SecondArg
The second template argument to which the template argument deduction failure refers.
A little helper class (which is basically a smart pointer that forwards info from DiagnosticsEngine) ...
Definition: Diagnostic.h:1317
unsigned CallArgIndex
The index of the function argument that caused a deduction failure.
TemplateArgument FirstArg
The first template argument to which the template argument deduction failure refers.
SmallVectorImpl< PartialDiagnosticAt >::const_iterator diag_iterator
Iterator over the set of suppressed diagnostics.
SmallVector< TemplateSpecCandidate, 16 >::iterator iterator
diag_iterator diag_begin() const
Returns an iterator at the beginning of the sequence of suppressed diagnostics.