@@ -583,7 +583,7 @@ class FunctionTemplateSpecializationInfo final
583583 // / \code
584584 // / template<typename> struct A {
585585 // / template<typename> void f();
586- // / template<> void f<int>(); // ClassScopeFunctionSpecializationDecl
586+ // / template<> void f<int>();
587587 // / };
588588 // / \endcode
589589 // /
@@ -682,82 +682,48 @@ class MemberSpecializationInfo {
682682// / Provides information about a dependent function-template
683683// / specialization declaration.
684684// /
685- // / Since explicit function template specialization and instantiation
686- // / declarations can only appear in namespace scope, and you can only
687- // / specialize a member of a fully-specialized class, the only way to
688- // / get one of these is in a friend declaration like the following:
685+ // / This is used for function templates explicit specializations declared
686+ // / within class templates:
687+ // /
688+ // / \code
689+ // / template<typename> struct A {
690+ // / template<typename> void f();
691+ // / template<> void f<int>(); // DependentFunctionTemplateSpecializationInfo
692+ // / };
693+ // / \endcode
694+ // /
695+ // / As well as dependent friend declarations naming function template
696+ // / specializations declared within class templates:
689697// /
690698// / \code
691699// / template \<class T> void foo(T);
692700// / template \<class T> class A {
693- // / friend void foo<>(T);
701+ // / friend void foo<>(T); // DependentFunctionTemplateSpecializationInfo
694702// / };
695703// / \endcode
696704class DependentFunctionTemplateSpecializationInfo final
697705 : private llvm::TrailingObjects<DependentFunctionTemplateSpecializationInfo,
698- TemplateArgumentLoc,
699706 FunctionTemplateDecl *> {
700- // / The number of potential template candidates.
701- unsigned NumTemplates;
702-
703- // / The number of template arguments.
704- unsigned NumArgs;
705-
706- // / The locations of the left and right angle brackets.
707- SourceRange AngleLocs;
707+ friend TrailingObjects;
708708
709- size_t numTrailingObjects (OverloadToken<TemplateArgumentLoc>) const {
710- return NumArgs;
711- }
712- size_t numTrailingObjects (OverloadToken<FunctionTemplateDecl *>) const {
713- return NumTemplates;
714- }
709+ // / The number of candidates for the primary template.
710+ unsigned NumCandidates;
715711
716712 DependentFunctionTemplateSpecializationInfo (
717- const UnresolvedSetImpl &Templates ,
718- const TemplateArgumentListInfo &TemplateArgs );
713+ const UnresolvedSetImpl &Candidates ,
714+ const ASTTemplateArgumentListInfo *TemplateArgsWritten );
719715
720716public:
721- friend TrailingObjects;
717+ // / The template arguments as written in the sources, if provided.
718+ const ASTTemplateArgumentListInfo *TemplateArgumentsAsWritten;
722719
723720 static DependentFunctionTemplateSpecializationInfo *
724- Create (ASTContext &Context, const UnresolvedSetImpl &Templates,
725- const TemplateArgumentListInfo &TemplateArgs);
726-
727- // / Returns the number of function templates that this might
728- // / be a specialization of.
729- unsigned getNumTemplates () const { return NumTemplates; }
721+ Create (ASTContext &Context, const UnresolvedSetImpl &Candidates,
722+ const TemplateArgumentListInfo *TemplateArgs);
730723
731- // / Returns the i'th template candidate.
732- FunctionTemplateDecl *getTemplate (unsigned I) const {
733- assert (I < getNumTemplates () && " template index out of range" );
734- return getTrailingObjects<FunctionTemplateDecl *>()[I];
735- }
736-
737- // / Returns the explicit template arguments that were given.
738- const TemplateArgumentLoc *getTemplateArgs () const {
739- return getTrailingObjects<TemplateArgumentLoc>();
740- }
741-
742- // / Returns the number of explicit template arguments that were given.
743- unsigned getNumTemplateArgs () const { return NumArgs; }
744-
745- llvm::ArrayRef<TemplateArgumentLoc> arguments () const {
746- return llvm::ArrayRef (getTemplateArgs (), getNumTemplateArgs ());
747- }
748-
749- // / Returns the nth template argument.
750- const TemplateArgumentLoc &getTemplateArg (unsigned I) const {
751- assert (I < getNumTemplateArgs () && " template arg index out of range" );
752- return getTemplateArgs ()[I];
753- }
754-
755- SourceLocation getLAngleLoc () const {
756- return AngleLocs.getBegin ();
757- }
758-
759- SourceLocation getRAngleLoc () const {
760- return AngleLocs.getEnd ();
724+ // / Returns the candidates for the primary function template.
725+ ArrayRef<FunctionTemplateDecl *> getCandidates () const {
726+ return {getTrailingObjects<FunctionTemplateDecl *>(), NumCandidates};
761727 }
762728};
763729
@@ -2613,70 +2579,6 @@ class TypeAliasTemplateDecl : public RedeclarableTemplateDecl {
26132579 static bool classofKind (Kind K) { return K == TypeAliasTemplate; }
26142580};
26152581
2616- // / Declaration of a function specialization at template class scope.
2617- // /
2618- // / For example:
2619- // / \code
2620- // / template <class T>
2621- // / class A {
2622- // / template <class U> void foo(U a) { }
2623- // / template<> void foo(int a) { }
2624- // / }
2625- // / \endcode
2626- // /
2627- // / "template<> foo(int a)" will be saved in Specialization as a normal
2628- // / CXXMethodDecl. Then during an instantiation of class A, it will be
2629- // / transformed into an actual function specialization.
2630- // /
2631- // / FIXME: This is redundant; we could store the same information directly on
2632- // / the CXXMethodDecl as a DependentFunctionTemplateSpecializationInfo.
2633- class ClassScopeFunctionSpecializationDecl : public Decl {
2634- CXXMethodDecl *Specialization;
2635- const ASTTemplateArgumentListInfo *TemplateArgs;
2636-
2637- ClassScopeFunctionSpecializationDecl (
2638- DeclContext *DC, SourceLocation Loc, CXXMethodDecl *FD,
2639- const ASTTemplateArgumentListInfo *TemplArgs)
2640- : Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc),
2641- Specialization (FD), TemplateArgs(TemplArgs) {}
2642-
2643- ClassScopeFunctionSpecializationDecl (EmptyShell Empty)
2644- : Decl(Decl::ClassScopeFunctionSpecialization, Empty) {}
2645-
2646- virtual void anchor ();
2647-
2648- public:
2649- friend class ASTDeclReader ;
2650- friend class ASTDeclWriter ;
2651-
2652- CXXMethodDecl *getSpecialization () const { return Specialization; }
2653- bool hasExplicitTemplateArgs () const { return TemplateArgs; }
2654- const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten () const {
2655- return TemplateArgs;
2656- }
2657-
2658- static ClassScopeFunctionSpecializationDecl *
2659- Create (ASTContext &C, DeclContext *DC, SourceLocation Loc, CXXMethodDecl *FD,
2660- bool HasExplicitTemplateArgs,
2661- const TemplateArgumentListInfo &TemplateArgs) {
2662- return new (C, DC) ClassScopeFunctionSpecializationDecl (
2663- DC, Loc, FD,
2664- HasExplicitTemplateArgs
2665- ? ASTTemplateArgumentListInfo::Create (C, TemplateArgs)
2666- : nullptr );
2667- }
2668-
2669- static ClassScopeFunctionSpecializationDecl *
2670- CreateDeserialized (ASTContext &Context, unsigned ID);
2671-
2672- // Implement isa/cast/dyncast/etc.
2673- static bool classof (const Decl *D) { return classofKind (D->getKind ()); }
2674-
2675- static bool classofKind (Kind K) {
2676- return K == Decl::ClassScopeFunctionSpecialization;
2677- }
2678- };
2679-
26802582// / Represents a variable template specialization, which refers to
26812583// / a variable template with a given set of template arguments.
26822584// /
0 commit comments