diff options
Diffstat (limited to 'include/clang/AST/DeclTemplate.h')
-rw-r--r-- | include/clang/AST/DeclTemplate.h | 130 |
1 files changed, 92 insertions, 38 deletions
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 7affc7e..8620116 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -50,7 +50,11 @@ class TemplateParameterList { /// The number of template parameters in this template /// parameter list. - unsigned NumParams; + unsigned NumParams : 31; + + /// Whether this template parameter list contains an unexpanded parameter + /// pack. + unsigned ContainsUnexpandedParameterPack : 1; protected: TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc, @@ -104,6 +108,12 @@ public: /// the second template parameter list will have depth 1, etc. unsigned getDepth() const; + /// \brief Determine whether this template parameter list contains an + /// unexpanded parameter pack. + bool containsUnexpandedParameterPack() const { + return ContainsUnexpandedParameterPack; + } + SourceLocation getTemplateLoc() const { return TemplateLoc; } SourceLocation getLAngleLoc() const { return LAngleLoc; } SourceLocation getRAngleLoc() const { return RAngleLoc; } @@ -139,8 +149,8 @@ class TemplateArgumentList { /// argument list. unsigned NumArguments; - TemplateArgumentList(const TemplateArgumentList &Other); // DO NOT IMPL - void operator=(const TemplateArgumentList &Other); // DO NOT IMPL + TemplateArgumentList(const TemplateArgumentList &Other) LLVM_DELETED_FUNCTION; + void operator=(const TemplateArgumentList &Other) LLVM_DELETED_FUNCTION; TemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs, bool Owned) @@ -233,12 +243,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const TemplateDecl *D) { return true; } - static bool classof(const RedeclarableTemplateDecl *D) { return true; } - static bool classof(const FunctionTemplateDecl *D) { return true; } - static bool classof(const ClassTemplateDecl *D) { return true; } - static bool classof(const TemplateTemplateParmDecl *D) { return true; } - static bool classof(const TypeAliasTemplateDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstTemplate && K <= lastTemplate; } @@ -678,10 +682,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const RedeclarableTemplateDecl *D) { return true; } - static bool classof(const FunctionTemplateDecl *D) { return true; } - static bool classof(const ClassTemplateDecl *D) { return true; } - static bool classof(const TypeAliasTemplateDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate; } @@ -827,7 +827,6 @@ public: // Implement isa/cast/dyncast support static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const FunctionTemplateDecl *D) { return true; } static bool classofKind(Kind K) { return K == FunctionTemplate; } friend class ASTDeclReader; @@ -969,7 +968,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const TemplateTypeParmDecl *D) { return true; } static bool classofKind(Kind K) { return K == TemplateTypeParm; } }; @@ -1090,8 +1088,17 @@ public: /// \endcode bool isParameterPack() const { return ParameterPack; } + /// \brief Whether this parameter pack is a pack expansion. + /// + /// A non-type template parameter pack is a pack expansion if its type + /// contains an unexpanded parameter pack. In this case, we will have + /// built a PackExpansionType wrapping the type. + bool isPackExpansion() const { + return ParameterPack && getType()->getAs<PackExpansionType>(); + } + /// \brief Whether this parameter is a non-type template parameter pack - /// that has different types at different positions. + /// that has a known list of different types at different positions. /// /// A parameter pack is an expanded parameter pack when the original /// parameter pack's type was itself a pack expansion, and that expansion @@ -1141,7 +1148,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const NonTypeTemplateParmDecl *D) { return true; } static bool classofKind(Kind K) { return K == NonTypeTemplateParm; } }; @@ -1165,23 +1171,47 @@ class TemplateTemplateParmDecl : public TemplateDecl, /// \brief Whether this parameter is a parameter pack. bool ParameterPack; + /// \brief Whether this template template parameter is an "expanded" + /// parameter pack, meaning that it is a pack expansion and we + /// already know the set of template parameters that expansion expands to. + bool ExpandedParameterPack; + + /// \brief The number of parameters in an expanded parameter pack. + unsigned NumExpandedParams; + TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D, unsigned P, bool ParameterPack, IdentifierInfo *Id, TemplateParameterList *Params) : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params), TemplateParmPosition(D, P), DefaultArgument(), - DefaultArgumentWasInherited(false), ParameterPack(ParameterPack) + DefaultArgumentWasInherited(false), ParameterPack(ParameterPack), + ExpandedParameterPack(false), NumExpandedParams(0) { } + TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, + unsigned D, unsigned P, + IdentifierInfo *Id, TemplateParameterList *Params, + unsigned NumExpansions, + TemplateParameterList * const *Expansions); + public: static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, unsigned P, bool ParameterPack, IdentifierInfo *Id, TemplateParameterList *Params); + static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC, + SourceLocation L, unsigned D, + unsigned P, + IdentifierInfo *Id, + TemplateParameterList *Params, + llvm::ArrayRef<TemplateParameterList*> Expansions); - static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C, + static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C, + unsigned ID, + unsigned NumExpansions); using TemplateParmPosition::getDepth; using TemplateParmPosition::getPosition; @@ -1195,6 +1225,49 @@ public: /// \endcode bool isParameterPack() const { return ParameterPack; } + /// \brief Whether this parameter pack is a pack expansion. + /// + /// A template template parameter pack is a pack expansion if its template + /// parameter list contains an unexpanded parameter pack. + bool isPackExpansion() const { + return ParameterPack && + getTemplateParameters()->containsUnexpandedParameterPack(); + } + + /// \brief Whether this parameter is a template template parameter pack that + /// has a known list of different template parameter lists at different + /// positions. + /// + /// A parameter pack is an expanded parameter pack when the original parameter + /// pack's template parameter list was itself a pack expansion, and that + /// expansion has already been expanded. For exampe, given: + /// + /// \code + /// template<typename...Types> struct Outer { + /// template<template<Types> class...Templates> struct Inner; + /// }; + /// \endcode + /// + /// The parameter pack \c Templates is a pack expansion, which expands the + /// pack \c Types. When \c Types is supplied with template arguments by + /// instantiating \c Outer, the instantiation of \c Templates is an expanded + /// parameter pack. + bool isExpandedParameterPack() const { return ExpandedParameterPack; } + + /// \brief Retrieves the number of expansion template parameters in + /// an expanded parameter pack. + unsigned getNumExpansionTemplateParameters() const { + assert(ExpandedParameterPack && "Not an expansion parameter pack"); + return NumExpandedParams; + } + + /// \brief Retrieve a particular expansion type within an expanded parameter + /// pack. + TemplateParameterList *getExpansionTemplateParameters(unsigned I) const { + assert(I < NumExpandedParams && "Out-of-range expansion type index"); + return reinterpret_cast<TemplateParameterList *const *>(this + 1)[I]; + } + /// \brief Determine whether this template parameter has a default /// argument. bool hasDefaultArgument() const { @@ -1238,7 +1311,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const TemplateTemplateParmDecl *D) { return true; } static bool classofKind(Kind K) { return K == TemplateTemplateParm; } friend class ASTDeclReader; @@ -1505,14 +1577,6 @@ public: K <= lastClassTemplateSpecialization; } - static bool classof(const ClassTemplateSpecializationDecl *) { - return true; - } - - static bool classof(const ClassTemplatePartialSpecializationDecl *) { - return true; - } - friend class ASTDeclReader; friend class ASTDeclWriter; }; @@ -1681,10 +1745,6 @@ public: return K == ClassTemplatePartialSpecialization; } - static bool classof(const ClassTemplatePartialSpecializationDecl *) { - return true; - } - friend class ASTDeclReader; friend class ASTDeclWriter; }; @@ -1886,7 +1946,6 @@ public: // Implement isa/cast/dyncast support static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ClassTemplateDecl *D) { return true; } static bool classofKind(Kind K) { return K == ClassTemplate; } friend class ASTDeclReader; @@ -1984,7 +2043,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Decl::FriendTemplate; } - static bool classof(const FriendTemplateDecl *D) { return true; } friend class ASTDeclReader; }; @@ -2059,7 +2117,6 @@ public: // Implement isa/cast/dyncast support static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const TypeAliasTemplateDecl *D) { return true; } static bool classofKind(Kind K) { return K == TypeAliasTemplate; } friend class ASTDeclReader; @@ -2123,9 +2180,6 @@ public: static bool classofKind(Kind K) { return K == Decl::ClassScopeFunctionSpecialization; } - static bool classof(const ClassScopeFunctionSpecializationDecl *D) { - return true; - } friend class ASTDeclReader; friend class ASTDeclWriter; |