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