Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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
      : 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
        DeducedDepth(Info.DeducedDepth), ExplicitArgs(Info.ExplicitArgs) {}
76
 
77
  /// Returns the location at which template argument is
78
  /// occurring.
79
  SourceLocation getLocation() const {
80
    return Loc;
81
  }
82
 
83
  /// The depth of template parameters for which deduction is being
84
  /// performed.
85
  unsigned getDeducedDepth() const {
86
    return DeducedDepth;
87
  }
88
 
89
  /// Get the number of explicitly-specified arguments.
90
  unsigned getNumExplicitArgs() const {
91
    return ExplicitArgs;
92
  }
93
 
94
  /// Take ownership of the deduced template argument lists.
95
  TemplateArgumentList *takeSugared() {
96
    TemplateArgumentList *Result = DeducedSugared;
97
    DeducedSugared = nullptr;
98
    return Result;
99
  }
100
  TemplateArgumentList *takeCanonical() {
101
    TemplateArgumentList *Result = DeducedCanonical;
102
    DeducedCanonical = nullptr;
103
    return Result;
104
  }
105
 
106
  /// Take ownership of the SFINAE diagnostic.
107
  void takeSFINAEDiagnostic(PartialDiagnosticAt &PD) {
108
    assert(HasSFINAEDiagnostic);
109
    PD.first = SuppressedDiagnostics.front().first;
110
    PD.second.swap(SuppressedDiagnostics.front().second);
111
    clearSFINAEDiagnostic();
112
  }
113
 
114
  /// Discard any SFINAE diagnostics.
115
  void clearSFINAEDiagnostic() {
116
    SuppressedDiagnostics.clear();
117
    HasSFINAEDiagnostic = false;
118
  }
119
 
120
  /// Peek at the SFINAE diagnostic.
121
  const PartialDiagnosticAt &peekSFINAEDiagnostic() const {
122
    assert(HasSFINAEDiagnostic);
123
    return SuppressedDiagnostics.front();
124
  }
125
 
126
  /// Provide an initial template argument list that contains the
127
  /// explicitly-specified arguments.
128
  void setExplicitArgs(TemplateArgumentList *NewDeducedSugared,
129
                       TemplateArgumentList *NewDeducedCanonical) {
130
    assert(NewDeducedSugared->size() == NewDeducedCanonical->size());
131
    DeducedSugared = NewDeducedSugared;
132
    DeducedCanonical = NewDeducedCanonical;
133
    ExplicitArgs = DeducedSugared->size();
134
  }
135
 
136
  /// Provide a new template argument list that contains the
137
  /// results of template argument deduction.
138
  void reset(TemplateArgumentList *NewDeducedSugared,
139
             TemplateArgumentList *NewDeducedCanonical) {
140
    DeducedSugared = NewDeducedSugared;
141
    DeducedCanonical = NewDeducedCanonical;
142
  }
143
 
144
  /// Is a SFINAE diagnostic available?
145
  bool hasSFINAEDiagnostic() const {
146
    return HasSFINAEDiagnostic;
147
  }
148
 
149
  /// Set the diagnostic which caused the SFINAE failure.
150
  void addSFINAEDiagnostic(SourceLocation Loc, PartialDiagnostic PD) {
151
    // Only collect the first diagnostic.
152
    if (HasSFINAEDiagnostic)
153
      return;
154
    SuppressedDiagnostics.clear();
155
    SuppressedDiagnostics.emplace_back(Loc, std::move(PD));
156
    HasSFINAEDiagnostic = true;
157
  }
158
 
159
  /// Add a new diagnostic to the set of diagnostics
160
  void addSuppressedDiagnostic(SourceLocation Loc,
161
                               PartialDiagnostic PD) {
162
    if (HasSFINAEDiagnostic)
163
      return;
164
    SuppressedDiagnostics.emplace_back(Loc, std::move(PD));
165
  }
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
  diag_iterator diag_begin() const { return SuppressedDiagnostics.begin(); }
173
 
174
  /// Returns an iterator at the end of the sequence of suppressed
175
  /// diagnostics.
176
  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
  void set(DeclAccessPair Found, Decl *Spec, DeductionFailureInfo Info) {
313
    FoundDecl = Found;
314
    Specialization = Spec;
315
    DeductionFailure = Info;
316
  }
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
      : Loc(Loc), ForTakingAddress(ForTakingAddress) {}
340
  TemplateSpecCandidateSet(const TemplateSpecCandidateSet &) = delete;
341
  TemplateSpecCandidateSet &
342
  operator=(const TemplateSpecCandidateSet &) = delete;
343
  ~TemplateSpecCandidateSet() { destroyCandidates(); }
344
 
345
  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
  iterator begin() { return Candidates.begin(); }
354
  iterator end() { return Candidates.end(); }
355
 
356
  size_t size() const { return Candidates.size(); }
357
  bool empty() const { return Candidates.empty(); }
358
 
359
  /// Add a new candidate with NumConversions conversion sequence slots
360
  /// to the overload set.
361
  TemplateSpecCandidate &addCandidate() {
362
    Candidates.emplace_back();
363
    return Candidates.back();
364
  }
365
 
366
  void NoteCandidates(Sema &S, SourceLocation Loc);
367
 
368
  void NoteCandidates(Sema &S, SourceLocation Loc) const {
369
    const_cast<TemplateSpecCandidateSet *>(this)->NoteCandidates(S, Loc);
370
  }
371
};
372
 
373
} // namespace clang
374
 
375
#endif // LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H