Coverage Report

Created: 2019-02-21 13:17

/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
// 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
17
#include "clang/AST/DeclAccessPair.h"
18
#include "clang/AST/DeclTemplate.h"
19
#include "clang/AST/TemplateBase.h"
20
#include "clang/Basic/PartialDiagnostic.h"
21
#include "clang/Basic/SourceLocation.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.
39
class TemplateDeductionInfo {
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
3.40M
      : Loc(Loc), DeducedDepth(DeducedDepth) {}
64
  TemplateDeductionInfo(const TemplateDeductionInfo &) = delete;
65
  TemplateDeductionInfo &operator=(const TemplateDeductionInfo &) = delete;
66
67
  /// Returns the location at which template argument is
68
  /// occurring.
69
3.57M
  SourceLocation getLocation() const {
70
3.57M
    return Loc;
71
3.57M
  }
72
73
  /// The depth of template parameters for which deduction is being
74
  /// performed.
75
2.50M
  unsigned getDeducedDepth() const {
76
2.50M
    return DeducedDepth;
77
2.50M
  }
78
79
  /// Get the number of explicitly-specified arguments.
80
85.2k
  unsigned getNumExplicitArgs() const {
81
85.2k
    return ExplicitArgs;
82
85.2k
  }
83
84
  /// Take ownership of the deduced template argument list.
85
352k
  TemplateArgumentList *take() {
86
352k
    TemplateArgumentList *Result = Deduced;
87
352k
    Deduced = nullptr;
88
352k
    return Result;
89
352k
  }
90
91
  /// Take ownership of the SFINAE diagnostic.
92
123k
  void takeSFINAEDiagnostic(PartialDiagnosticAt &PD) {
93
123k
    assert(HasSFINAEDiagnostic);
94
123k
    PD.first = SuppressedDiagnostics.front().first;
95
123k
    PD.second.swap(SuppressedDiagnostics.front().second);
96
123k
    clearSFINAEDiagnostic();
97
123k
  }
98
99
  /// Discard any SFINAE diagnostics.
100
123k
  void clearSFINAEDiagnostic() {
101
123k
    SuppressedDiagnostics.clear();
102
123k
    HasSFINAEDiagnostic = false;
103
123k
  }
104
105
  /// Peek at the SFINAE diagnostic.
106
0
  const PartialDiagnosticAt &peekSFINAEDiagnostic() const {
107
0
    assert(HasSFINAEDiagnostic);
108
0
    return SuppressedDiagnostics.front();
109
0
  }
110
111
  /// Provide an initial template argument list that contains the
112
  /// explicitly-specified arguments.
113
354k
  void setExplicitArgs(TemplateArgumentList *NewDeduced) {
114
354k
    Deduced = NewDeduced;
115
354k
    ExplicitArgs = Deduced->size();
116
354k
  }
117
118
  /// Provide a new template argument list that contains the
119
  /// results of template argument deduction.
120
972k
  void reset(TemplateArgumentList *NewDeduced) {
121
972k
    Deduced = NewDeduced;
122
972k
  }
123
124
  /// Is a SFINAE diagnostic available?
125
252k
  bool hasSFINAEDiagnostic() const {
126
252k
    return HasSFINAEDiagnostic;
127
252k
  }
128
129
  /// Set the diagnostic which caused the SFINAE failure.
130
126k
  void addSFINAEDiagnostic(SourceLocation Loc, PartialDiagnostic PD) {
131
126k
    // Only collect the first diagnostic.
132
126k
    if (HasSFINAEDiagnostic)
133
0
      return;
134
126k
    SuppressedDiagnostics.clear();
135
126k
    SuppressedDiagnostics.emplace_back(Loc, std::move(PD));
136
126k
    HasSFINAEDiagnostic = true;
137
126k
  }
138
139
  /// Add a new diagnostic to the set of diagnostics
140
  void addSuppressedDiagnostic(SourceLocation Loc,
141
8.80k
                               PartialDiagnostic PD) {
142
8.80k
    if (HasSFINAEDiagnostic)
143
6.12k
      return;
144
2.68k
    SuppressedDiagnostics.emplace_back(Loc, std::move(PD));
145
2.68k
  }
146
147
  /// Iterator over the set of suppressed diagnostics.
148
  using diag_iterator = SmallVectorImpl<PartialDiagnosticAt>::const_iterator;
149
150
  /// Returns an iterator at the beginning of the sequence of suppressed
151
  /// diagnostics.
152
578k
  diag_iterator diag_begin() const { return SuppressedDiagnostics.begin(); }
153
154
  /// Returns an iterator at the end of the sequence of suppressed
155
  /// diagnostics.
156
578k
  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.
172
  TemplateParameter Param;
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.
194
  TemplateArgument FirstArg;
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.
208
  TemplateArgument SecondArg;
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.
220
  SmallVector<DeducedPack *, 8> PendingDeducedPacks;
221
};
222
223
} // namespace sema
224
225
/// A structure used to record information about a failed
226
/// template argument deduction, for diagnosis.
227
0
struct DeductionFailureInfo {
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.
239
  alignas(PartialDiagnosticAt) char Diagnostic[sizeof(PartialDiagnosticAt)];
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.
276
struct TemplateSpecCandidate {
277
  /// The declaration that was looked up, together with its access.
278
  /// Might be a UsingShadowDecl, but usually a FunctionTemplateDecl.
279
  DeclAccessPair FoundDecl;
280
281
  /// Specialization - The actual specialization that this candidate
282
  /// represents. When NULL, this may be a built-in candidate.
283
  Decl *Specialization;
284
285
  /// Template argument deduction info
286
  DeductionFailureInfo DeductionFailure;
287
288
685k
  void set(DeclAccessPair Found, Decl *Spec, DeductionFailureInfo Info) {
289
685k
    FoundDecl = Found;
290
685k
    Specialization = Spec;
291
685k
    DeductionFailure = Info;
292
685k
  }
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.
302
class TemplateSpecCandidateSet {
303
  SmallVector<TemplateSpecCandidate, 16> Candidates;
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
1.11M
      : Loc(Loc), ForTakingAddress(ForTakingAddress) {}
316
  TemplateSpecCandidateSet(const TemplateSpecCandidateSet &) = delete;
317
  TemplateSpecCandidateSet &
318
  operator=(const TemplateSpecCandidateSet &) = delete;
319
1.11M
  ~TemplateSpecCandidateSet() { destroyCandidates(); }
320
321
936k
  SourceLocation getLocation() const { return Loc; }
322
323
  /// Clear out all of the candidates.
324
  /// TODO: This may be unnecessary.
325
  void clear();
326
327
  using iterator = SmallVector<TemplateSpecCandidate, 16>::iterator;
328
329
1.11M
  iterator begin() { return Candidates.begin(); }
330
1.11M
  iterator end() { return Candidates.end(); }
331
332
125
  size_t size() const { return Candidates.size(); }
333
47
  bool empty() const { return Candidates.empty(); }
334
335
  /// Add a new candidate with NumConversions conversion sequence slots
336
  /// to the overload set.
337
685k
  TemplateSpecCandidate &addCandidate() {
338
685k
    Candidates.emplace_back();
339
685k
    return Candidates.back();
340
685k
  }
341
342
  void NoteCandidates(Sema &S, SourceLocation Loc);
343
344
14
  void NoteCandidates(Sema &S, SourceLocation Loc) const {
345
14
    const_cast<TemplateSpecCandidateSet *>(this)->NoteCandidates(S, Loc);
346
14
  }
347
};
348
349
} // namespace clang
350
351
#endif // LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H