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