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
20namespace clang {
21
22struct DeducedPack;
23class TemplateArgumentList;
24class Sema;
25
26namespace sema {
27
28/// \brief Provides information about an attempted template argument
29/// deduction, whose success or failure was described by a
30/// TemplateDeductionResult value.
31class 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
53public:
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.
201struct 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.
250struct 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.
276class 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
290public:
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
325