File indexing completed on 2026-05-10 08:37:05
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
0015 #define LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
0016
0017 #include "clang/Sema/Ownership.h"
0018 #include "clang/Sema/SemaConcept.h"
0019 #include "clang/AST/ASTConcept.h"
0020 #include "clang/AST/DeclAccessPair.h"
0021 #include "clang/AST/DeclTemplate.h"
0022 #include "clang/AST/TemplateBase.h"
0023 #include "clang/Basic/PartialDiagnostic.h"
0024 #include "clang/Basic/SourceLocation.h"
0025 #include "llvm/ADT/SmallVector.h"
0026 #include <cassert>
0027 #include <cstddef>
0028 #include <optional>
0029 #include <utility>
0030
0031 namespace clang {
0032
0033 class Decl;
0034 struct DeducedPack;
0035 class Sema;
0036 enum class TemplateDeductionResult;
0037
0038 namespace sema {
0039
0040
0041
0042
0043 class TemplateDeductionInfo {
0044
0045 TemplateArgumentList *DeducedSugared = nullptr, *DeducedCanonical = nullptr;
0046
0047
0048
0049 SourceLocation Loc;
0050
0051
0052 bool HasSFINAEDiagnostic = false;
0053
0054
0055
0056
0057 bool MatchedPackOnParmToNonPackOnArg = false;
0058
0059
0060 unsigned DeducedDepth;
0061
0062
0063
0064 unsigned ExplicitArgs = 0;
0065
0066
0067
0068 SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics;
0069
0070 public:
0071 TemplateDeductionInfo(SourceLocation Loc, unsigned DeducedDepth = 0)
0072 : Loc(Loc), DeducedDepth(DeducedDepth) {}
0073 TemplateDeductionInfo(const TemplateDeductionInfo &) = delete;
0074 TemplateDeductionInfo &operator=(const TemplateDeductionInfo &) = delete;
0075
0076 enum ForBaseTag { ForBase };
0077
0078
0079 TemplateDeductionInfo(ForBaseTag, const TemplateDeductionInfo &Info)
0080 : DeducedSugared(Info.DeducedSugared), Loc(Info.Loc),
0081 DeducedDepth(Info.DeducedDepth), ExplicitArgs(Info.ExplicitArgs) {}
0082
0083
0084
0085 SourceLocation getLocation() const {
0086 return Loc;
0087 }
0088
0089
0090
0091 unsigned getDeducedDepth() const {
0092 return DeducedDepth;
0093 }
0094
0095 bool hasMatchedPackOnParmToNonPackOnArg() const {
0096 return MatchedPackOnParmToNonPackOnArg;
0097 }
0098
0099 void setMatchedPackOnParmToNonPackOnArg() {
0100 MatchedPackOnParmToNonPackOnArg = true;
0101 }
0102
0103
0104 unsigned getNumExplicitArgs() const {
0105 return ExplicitArgs;
0106 }
0107
0108
0109 TemplateArgumentList *takeSugared() {
0110 TemplateArgumentList *Result = DeducedSugared;
0111 DeducedSugared = nullptr;
0112 return Result;
0113 }
0114 TemplateArgumentList *takeCanonical() {
0115 TemplateArgumentList *Result = DeducedCanonical;
0116 DeducedCanonical = nullptr;
0117 return Result;
0118 }
0119
0120
0121 void takeSFINAEDiagnostic(PartialDiagnosticAt &PD) {
0122 assert(HasSFINAEDiagnostic);
0123 PD.first = SuppressedDiagnostics.front().first;
0124 PD.second.swap(SuppressedDiagnostics.front().second);
0125 clearSFINAEDiagnostic();
0126 }
0127
0128
0129 void clearSFINAEDiagnostic() {
0130 SuppressedDiagnostics.clear();
0131 HasSFINAEDiagnostic = false;
0132 }
0133
0134
0135 const PartialDiagnosticAt &peekSFINAEDiagnostic() const {
0136 assert(HasSFINAEDiagnostic);
0137 return SuppressedDiagnostics.front();
0138 }
0139
0140
0141
0142 void setExplicitArgs(TemplateArgumentList *NewDeducedSugared,
0143 TemplateArgumentList *NewDeducedCanonical) {
0144 assert(NewDeducedSugared->size() == NewDeducedCanonical->size());
0145 DeducedSugared = NewDeducedSugared;
0146 DeducedCanonical = NewDeducedCanonical;
0147 ExplicitArgs = DeducedSugared->size();
0148 }
0149
0150
0151
0152 void reset(TemplateArgumentList *NewDeducedSugared,
0153 TemplateArgumentList *NewDeducedCanonical) {
0154 DeducedSugared = NewDeducedSugared;
0155 DeducedCanonical = NewDeducedCanonical;
0156 }
0157
0158
0159 bool hasSFINAEDiagnostic() const {
0160 return HasSFINAEDiagnostic;
0161 }
0162
0163
0164 void addSFINAEDiagnostic(SourceLocation Loc, PartialDiagnostic PD) {
0165
0166 if (HasSFINAEDiagnostic)
0167 return;
0168 SuppressedDiagnostics.clear();
0169 SuppressedDiagnostics.emplace_back(Loc, std::move(PD));
0170 HasSFINAEDiagnostic = true;
0171 }
0172
0173
0174 void addSuppressedDiagnostic(SourceLocation Loc,
0175 PartialDiagnostic PD) {
0176 if (HasSFINAEDiagnostic)
0177 return;
0178 SuppressedDiagnostics.emplace_back(Loc, std::move(PD));
0179 }
0180
0181
0182 using diag_iterator = SmallVectorImpl<PartialDiagnosticAt>::const_iterator;
0183
0184
0185
0186 diag_iterator diag_begin() const { return SuppressedDiagnostics.begin(); }
0187
0188
0189
0190 diag_iterator diag_end() const { return SuppressedDiagnostics.end(); }
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206 TemplateParameter Param;
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228 TemplateArgument FirstArg;
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242 TemplateArgument SecondArg;
0243
0244
0245
0246
0247
0248
0249 unsigned CallArgIndex = 0;
0250
0251
0252
0253
0254
0255
0256 bool AggregateDeductionCandidateHasMismatchedArity = false;
0257
0258
0259
0260
0261 SmallVector<DeducedPack *, 8> PendingDeducedPacks;
0262
0263
0264
0265 ConstraintSatisfaction AssociatedConstraintsSatisfaction;
0266 };
0267
0268 }
0269
0270
0271
0272 struct DeductionFailureInfo {
0273
0274 unsigned Result : 8;
0275
0276
0277 unsigned HasDiagnostic : 1;
0278
0279
0280
0281 void *Data;
0282
0283
0284 alignas(PartialDiagnosticAt) char Diagnostic[sizeof(PartialDiagnosticAt)];
0285
0286
0287
0288 PartialDiagnosticAt *getSFINAEDiagnostic();
0289
0290
0291
0292 TemplateParameter getTemplateParameter();
0293
0294
0295
0296 TemplateArgumentList *getTemplateArgumentList();
0297
0298
0299
0300 const TemplateArgument *getFirstArg();
0301
0302
0303
0304 const TemplateArgument *getSecondArg();
0305
0306
0307
0308 std::optional<unsigned> getCallArgIndex();
0309
0310
0311 void Destroy();
0312
0313 TemplateDeductionResult getResult() const {
0314 return static_cast<TemplateDeductionResult>(Result);
0315 }
0316 };
0317
0318
0319
0320
0321
0322
0323
0324
0325 struct TemplateSpecCandidate {
0326
0327
0328 DeclAccessPair FoundDecl;
0329
0330
0331
0332 Decl *Specialization;
0333
0334
0335 DeductionFailureInfo DeductionFailure;
0336
0337 void set(DeclAccessPair Found, Decl *Spec, DeductionFailureInfo Info) {
0338 FoundDecl = Found;
0339 Specialization = Spec;
0340 DeductionFailure = Info;
0341 }
0342
0343
0344 void NoteDeductionFailure(Sema &S, bool ForTakingAddress);
0345 };
0346
0347
0348
0349
0350
0351 class TemplateSpecCandidateSet {
0352 SmallVector<TemplateSpecCandidate, 16> Candidates;
0353 SourceLocation Loc;
0354
0355
0356
0357
0358 bool ForTakingAddress;
0359
0360 void destroyCandidates();
0361
0362 public:
0363 TemplateSpecCandidateSet(SourceLocation Loc, bool ForTakingAddress = false)
0364 : Loc(Loc), ForTakingAddress(ForTakingAddress) {}
0365 TemplateSpecCandidateSet(const TemplateSpecCandidateSet &) = delete;
0366 TemplateSpecCandidateSet &
0367 operator=(const TemplateSpecCandidateSet &) = delete;
0368 ~TemplateSpecCandidateSet() { destroyCandidates(); }
0369
0370 SourceLocation getLocation() const { return Loc; }
0371
0372
0373
0374 void clear();
0375
0376 using iterator = SmallVector<TemplateSpecCandidate, 16>::iterator;
0377
0378 iterator begin() { return Candidates.begin(); }
0379 iterator end() { return Candidates.end(); }
0380
0381 size_t size() const { return Candidates.size(); }
0382 bool empty() const { return Candidates.empty(); }
0383
0384
0385
0386 TemplateSpecCandidate &addCandidate() {
0387 Candidates.emplace_back();
0388 return Candidates.back();
0389 }
0390
0391 void NoteCandidates(Sema &S, SourceLocation Loc);
0392
0393 void NoteCandidates(Sema &S, SourceLocation Loc) const {
0394 const_cast<TemplateSpecCandidateSet *>(this)->NoteCandidates(S, Loc);
0395 }
0396 };
0397
0398 }
0399
0400 #endif