Coverage Report

Created: 2020-02-25 14:32

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