Coverage Report

Created: 2018-11-16 02:38

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