diff options
Diffstat (limited to 'include/clang')
-rw-r--r-- | include/clang/AST/Decl.h | 19 | ||||
-rw-r--r-- | include/clang/AST/DeclFriend.h | 10 | ||||
-rw-r--r-- | include/clang/AST/DeclTemplate.h | 75 |
3 files changed, 93 insertions, 11 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 569a94e8a1..a6a8b4cc84 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -31,7 +31,9 @@ class StringLiteral; class TemplateArgumentList; class MemberSpecializationInfo; class FunctionTemplateSpecializationInfo; +class DependentFunctionTemplateSpecializationInfo; class TypeLoc; +class UnresolvedSetImpl; /// \brief A container of type source information. /// @@ -1037,9 +1039,10 @@ private: /// FunctionTemplateSpecializationInfo, which contains information about /// the template being specialized and the template arguments involved in /// that specialization. - llvm::PointerUnion3<FunctionTemplateDecl *, + llvm::PointerUnion4<FunctionTemplateDecl *, MemberSpecializationInfo *, - FunctionTemplateSpecializationInfo *> + FunctionTemplateSpecializationInfo *, + DependentFunctionTemplateSpecializationInfo *> TemplateOrSpecialization; protected: @@ -1365,6 +1368,18 @@ public: void *InsertPos, TemplateSpecializationKind TSK = TSK_ImplicitInstantiation); + /// \brief Specifies that this function declaration is actually a + /// dependent function template specialization. + void setDependentTemplateSpecialization(ASTContext &Context, + const UnresolvedSetImpl &Templates, + const TemplateArgumentListInfo &TemplateArgs); + + DependentFunctionTemplateSpecializationInfo * + getDependentSpecializationInfo() const { + return TemplateOrSpecialization. + dyn_cast<DependentFunctionTemplateSpecializationInfo*>(); + } + /// \brief Determine what kind of template instantiation this function /// represents. TemplateSpecializationKind getTemplateSpecializationKind() const; diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h index 99ef738980..a20625da56 100644 --- a/include/clang/AST/DeclFriend.h +++ b/include/clang/AST/DeclFriend.h @@ -48,10 +48,6 @@ private: // Location of the 'friend' specifier. SourceLocation FriendLoc; - // FIXME: Hack to keep track of whether this was a friend function - // template specialization. - bool WasSpecialization; - friend class CXXRecordDecl::friend_iterator; friend class CXXRecordDecl; @@ -60,8 +56,7 @@ private: : Decl(Decl::Friend, DC, L), Friend(Friend), NextFriend(0), - FriendLoc(FriendL), - WasSpecialization(false) { + FriendLoc(FriendL) { } public: @@ -88,9 +83,6 @@ public: return FriendLoc; } - bool wasSpecialization() const { return WasSpecialization; } - void setSpecialization(bool WS) { WasSpecialization = WS; } - // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const FriendDecl *D) { return true; } diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 8d1a4caccb..bb24c3f5f0 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -376,6 +376,81 @@ public: PointOfInstantiation = POI; } }; + +/// \brief Provides information about a dependent function-template +/// specialization declaration. Since explicit function template +/// specialization and instantiation declarations can only appear in +/// namespace scope, and you can only specialize a member of a +/// fully-specialized class, the only way to get one of these is in +/// a friend declaration like the following: +/// +/// template <class T> void foo(T); +/// template <class T> class A { +/// friend void foo<>(T); +/// }; +class DependentFunctionTemplateSpecializationInfo { + union { + // Force sizeof to be a multiple of sizeof(void*) so that the + // trailing data is aligned. + void *Aligner; + + struct { + /// The number of potential template candidates. + unsigned NumTemplates; + + /// The number of template arguments. + unsigned NumArgs; + } d; + }; + + /// The locations of the left and right angle brackets. + SourceRange AngleLocs; + + FunctionTemplateDecl * const *getTemplates() const { + return reinterpret_cast<FunctionTemplateDecl*const*>(this+1); + } + + const TemplateArgumentLoc *getTemplateArgs() const { + return reinterpret_cast<const TemplateArgumentLoc*>( + getTemplates()[getNumTemplates()]); + } + +public: + DependentFunctionTemplateSpecializationInfo( + const UnresolvedSetImpl &Templates, + const TemplateArgumentListInfo &TemplateArgs); + + /// \brief Returns the number of function templates that this might + /// be a specialization of. + unsigned getNumTemplates() const { + return d.NumTemplates; + } + + /// \brief Returns the i'th template candidate. + FunctionTemplateDecl *getTemplate(unsigned I) const { + assert(I < getNumTemplates() && "template index out of range"); + return getTemplates()[I]; + } + + /// \brief Returns the number of explicit template arguments that were given. + unsigned getNumTemplateArgs() const { + return d.NumArgs; + } + + /// \brief Returns the nth template argument. + const TemplateArgumentLoc &getTemplateArg(unsigned I) const { + assert(I < getNumTemplateArgs() && "template arg index out of range"); + return getTemplateArgs()[I]; + } + + SourceLocation getLAngleLoc() const { + return AngleLocs.getBegin(); + } + + SourceLocation getRAngleLoc() const { + return AngleLocs.getEnd(); + } +}; /// Declaration of a template function. class FunctionTemplateDecl : public TemplateDecl { |