@@ -34,6 +34,7 @@ class NestedNameSpecifier;
3434enum OverloadedOperatorKind : int ;
3535class OverloadedTemplateStorage ;
3636class AssumedTemplateStorage ;
37+ class DeducedTemplateStorage ;
3738struct PrintingPolicy ;
3839class QualifiedTemplateName ;
3940class SubstTemplateTemplateParmPackStorage ;
@@ -50,16 +51,17 @@ class UncommonTemplateNameStorage {
5051 enum Kind {
5152 Overloaded,
5253 Assumed, // defined in DeclarationName.h
54+ Deduced,
5355 SubstTemplateTemplateParm,
5456 SubstTemplateTemplateParmPack
5557 };
5658
5759 struct BitsTag {
5860 LLVM_PREFERRED_TYPE (Kind)
59- unsigned Kind : 2 ;
61+ unsigned Kind : 3 ;
6062
6163 // The template parameter index.
62- unsigned Index : 15 ;
64+ unsigned Index : 14 ;
6365
6466 // / The pack index, or the number of stored templates
6567 // / or template arguments, depending on which subclass we have.
@@ -90,6 +92,12 @@ class UncommonTemplateNameStorage {
9092 : nullptr ;
9193 }
9294
95+ DeducedTemplateStorage *getAsDeducedTemplateName () {
96+ return Bits.Kind == Deduced
97+ ? reinterpret_cast <DeducedTemplateStorage *>(this )
98+ : nullptr ;
99+ }
100+
93101 SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm () {
94102 return Bits.Kind == SubstTemplateTemplateParm
95103 ? reinterpret_cast <SubstTemplateTemplateParmStorage *>(this )
@@ -172,6 +180,15 @@ class SubstTemplateTemplateParmPackStorage : public UncommonTemplateNameStorage,
172180 unsigned Index, bool Final);
173181};
174182
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+
175192// / Represents a C++ template name within the type system.
176193// /
177194// / A C++ template name refers to a template within the C++ type
@@ -246,6 +263,10 @@ class TemplateName {
246263 // / A template name that refers to a template declaration found through a
247264 // / specific using shadow declaration.
248265 UsingTemplate,
266+
267+ // / A template name that refers to another TemplateName with deduced default
268+ // / arguments.
269+ DeducedTemplate,
249270 };
250271
251272 TemplateName () = default ;
@@ -257,6 +278,7 @@ class TemplateName {
257278 explicit TemplateName (QualifiedTemplateName *Qual);
258279 explicit TemplateName (DependentTemplateName *Dep);
259280 explicit TemplateName (UsingShadowDecl *Using);
281+ explicit TemplateName (DeducedTemplateStorage *Deduced);
260282
261283 // / Determine whether this template name is NULL.
262284 bool isNull () const ;
@@ -271,7 +293,13 @@ class TemplateName {
271293 // / to, if any. If the template name does not refer to a specific
272294 // / declaration because it is a dependent name, or if it refers to a
273295 // / 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 ;
275303
276304 // / Retrieve the underlying, overloaded function template
277305 // / declarations that this template name refers to, if known.
@@ -313,6 +341,11 @@ class TemplateName {
313341 // / template declaration is introduced, if any.
314342 UsingShadowDecl *getAsUsingShadowDecl () const ;
315343
344+ // / Retrieve the deduced template info, if any.
345+ DeducedTemplateStorage *getAsDeducedTemplateName () const ;
346+
347+ std::optional<TemplateName> desugar (bool IgnoreDeduced) const ;
348+
316349 TemplateName getUnderlying () const ;
317350
318351 TemplateNameDependence getDependence () const ;
@@ -412,6 +445,30 @@ class SubstTemplateTemplateParmStorage
412445 std::optional<unsigned > PackIndex);
413446};
414447
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+
415472inline TemplateName TemplateName::getUnderlying () const {
416473 if (SubstTemplateTemplateParmStorage *subst
417474 = getAsSubstTemplateTemplateParm ())
0 commit comments