@@ -34,6 +34,7 @@ class NestedNameSpecifier;
34
34
enum OverloadedOperatorKind : int ;
35
35
class OverloadedTemplateStorage ;
36
36
class AssumedTemplateStorage ;
37
+ class DeducedTemplateStorage ;
37
38
struct PrintingPolicy ;
38
39
class QualifiedTemplateName ;
39
40
class SubstTemplateTemplateParmPackStorage ;
@@ -50,16 +51,17 @@ class UncommonTemplateNameStorage {
50
51
enum Kind {
51
52
Overloaded,
52
53
Assumed, // defined in DeclarationName.h
54
+ Deduced,
53
55
SubstTemplateTemplateParm,
54
56
SubstTemplateTemplateParmPack
55
57
};
56
58
57
59
struct BitsTag {
58
60
LLVM_PREFERRED_TYPE (Kind)
59
- unsigned Kind : 2 ;
61
+ unsigned Kind : 3 ;
60
62
61
63
// The template parameter index.
62
- unsigned Index : 15 ;
64
+ unsigned Index : 14 ;
63
65
64
66
// / The pack index, or the number of stored templates
65
67
// / or template arguments, depending on which subclass we have.
@@ -90,6 +92,12 @@ class UncommonTemplateNameStorage {
90
92
: nullptr ;
91
93
}
92
94
95
+ DeducedTemplateStorage *getAsDeducedTemplateName () {
96
+ return Bits.Kind == Deduced
97
+ ? reinterpret_cast <DeducedTemplateStorage *>(this )
98
+ : nullptr ;
99
+ }
100
+
93
101
SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm () {
94
102
return Bits.Kind == SubstTemplateTemplateParm
95
103
? reinterpret_cast <SubstTemplateTemplateParmStorage *>(this )
@@ -172,6 +180,15 @@ class SubstTemplateTemplateParmPackStorage : public UncommonTemplateNameStorage,
172
180
unsigned Index, bool Final);
173
181
};
174
182
183
+ struct DefaultArguments {
184
+ // The position in the template parameter list
185
+ // the first argument corresponds to.
186
+ unsigned StartPos;
187
+ ArrayRef<TemplateArgument> Args;
188
+
189
+ operator bool () const { return !Args.empty (); }
190
+ };
191
+
175
192
// / Represents a C++ template name within the type system.
176
193
// /
177
194
// / A C++ template name refers to a template within the C++ type
@@ -246,6 +263,10 @@ class TemplateName {
246
263
// / A template name that refers to a template declaration found through a
247
264
// / specific using shadow declaration.
248
265
UsingTemplate,
266
+
267
+ // / A template name that refers to another TemplateName with deduced default
268
+ // / arguments.
269
+ DeducedTemplate,
249
270
};
250
271
251
272
TemplateName () = default ;
@@ -257,6 +278,7 @@ class TemplateName {
257
278
explicit TemplateName (QualifiedTemplateName *Qual);
258
279
explicit TemplateName (DependentTemplateName *Dep);
259
280
explicit TemplateName (UsingShadowDecl *Using);
281
+ explicit TemplateName (DeducedTemplateStorage *Deduced);
260
282
261
283
// / Determine whether this template name is NULL.
262
284
bool isNull () const ;
@@ -271,7 +293,13 @@ class TemplateName {
271
293
// / to, if any. If the template name does not refer to a specific
272
294
// / declaration because it is a dependent name, or if it refers to a
273
295
// / set of function templates, returns NULL.
274
- TemplateDecl *getAsTemplateDecl () const ;
296
+ TemplateDecl *getAsTemplateDecl (bool IgnoreDeduced = false ) const ;
297
+
298
+ // / Retrieves the underlying template declaration that
299
+ // / this template name refers to, along with the
300
+ // / deduced default arguments, if any.
301
+ std::pair<TemplateDecl *, DefaultArguments>
302
+ getTemplateDeclAndDefaultArgs () const ;
275
303
276
304
// / Retrieve the underlying, overloaded function template
277
305
// / declarations that this template name refers to, if known.
@@ -313,6 +341,11 @@ class TemplateName {
313
341
// / template declaration is introduced, if any.
314
342
UsingShadowDecl *getAsUsingShadowDecl () const ;
315
343
344
+ // / Retrieve the deduced template info, if any.
345
+ DeducedTemplateStorage *getAsDeducedTemplateName () const ;
346
+
347
+ std::optional<TemplateName> desugar (bool IgnoreDeduced) const ;
348
+
316
349
TemplateName getUnderlying () const ;
317
350
318
351
TemplateNameDependence getDependence () const ;
@@ -412,6 +445,30 @@ class SubstTemplateTemplateParmStorage
412
445
std::optional<unsigned > PackIndex);
413
446
};
414
447
448
+ class DeducedTemplateStorage : public UncommonTemplateNameStorage ,
449
+ public llvm::FoldingSetNode {
450
+ friend class ASTContext ;
451
+
452
+ TemplateName Underlying;
453
+
454
+ DeducedTemplateStorage (TemplateName Underlying,
455
+ const DefaultArguments &DefArgs);
456
+
457
+ public:
458
+ TemplateName getUnderlying () const { return Underlying; }
459
+
460
+ DefaultArguments getDefaultArguments () const {
461
+ return {/* StartPos=*/ Bits.Index ,
462
+ /* Args=*/ {reinterpret_cast <const TemplateArgument *>(this + 1 ),
463
+ Bits.Data }};
464
+ }
465
+
466
+ void Profile (llvm::FoldingSetNodeID &ID, const ASTContext &Context) const ;
467
+
468
+ static void Profile (llvm::FoldingSetNodeID &ID, const ASTContext &Context,
469
+ TemplateName Underlying, const DefaultArguments &DefArgs);
470
+ };
471
+
415
472
inline TemplateName TemplateName::getUnderlying () const {
416
473
if (SubstTemplateTemplateParmStorage *subst
417
474
= getAsSubstTemplateTemplateParm ())
0 commit comments