Coverage Report

Created: 2023-05-31 04:38

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