diff options
Diffstat (limited to 'include/clang/AST/DeclTemplate.h')
-rw-r--r-- | include/clang/AST/DeclTemplate.h | 81 |
1 files changed, 53 insertions, 28 deletions
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index d553e739c388..2af95c02c460 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -21,7 +21,6 @@ #include "llvm/ADT/PointerUnion.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/TrailingObjects.h" -#include <limits> #include <utility> namespace clang { @@ -49,7 +48,8 @@ NamedDecl *getAsNamedDecl(TemplateParameter P); /// \brief Stores a list of template parameters for a TemplateDecl and its /// derived classes. class TemplateParameterList final - : private llvm::TrailingObjects<TemplateParameterList, NamedDecl *> { + : private llvm::TrailingObjects<TemplateParameterList, NamedDecl *, + Expr *> { /// The location of the 'template' keyword. SourceLocation TemplateLoc; @@ -59,26 +59,35 @@ class TemplateParameterList final /// The number of template parameters in this template /// parameter list. - unsigned NumParams : 31; + unsigned NumParams : 30; /// Whether this template parameter list contains an unexpanded parameter /// pack. unsigned ContainsUnexpandedParameterPack : 1; + /// Whether this template parameter list has an associated requires-clause + unsigned HasRequiresClause : 1; + protected: size_t numTrailingObjects(OverloadToken<NamedDecl *>) const { return NumParams; } + size_t numTrailingObjects(OverloadToken<Expr *>) const { + return HasRequiresClause; + } + TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc, - ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc); + ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc, + Expr *RequiresClause); public: static TemplateParameterList *Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef<NamedDecl *> Params, - SourceLocation RAngleLoc); + SourceLocation RAngleLoc, + Expr *RequiresClause); /// \brief Iterates through the template parameters in this list. typedef NamedDecl** iterator; @@ -130,6 +139,16 @@ public: return ContainsUnexpandedParameterPack; } + /// \brief The constraint-expression of the associated requires-clause. + Expr *getRequiresClause() { + return HasRequiresClause ? *getTrailingObjects<Expr *>() : nullptr; + } + + /// \brief The constraint-expression of the associated requires-clause. + const Expr *getRequiresClause() const { + return HasRequiresClause ? *getTrailingObjects<Expr *>() : nullptr; + } + SourceLocation getTemplateLoc() const { return TemplateLoc; } SourceLocation getLAngleLoc() const { return LAngleLoc; } SourceLocation getRAngleLoc() const { return RAngleLoc; } @@ -139,36 +158,37 @@ public: } friend TrailingObjects; - template <size_t N> friend class FixedSizeTemplateParameterListStorage; + + template <size_t N, bool HasRequiresClause> + friend class FixedSizeTemplateParameterListStorage; + +public: + // FIXME: workaround for MSVC 2013; remove when no longer needed + using FixedSizeStorageOwner = TrailingObjects::FixedSizeStorageOwner; }; -/// \brief Stores a list of template parameters for a TemplateDecl and its -/// derived classes. Suitable for creating on the stack. -template <size_t N> class FixedSizeTemplateParameterListStorage { - // This is kinda ugly: TemplateParameterList usually gets allocated - // in a block of memory with NamedDecls appended to it. Here, to get - // it stack allocated, we include the params as a separate - // variable. After allocation, the TemplateParameterList object - // treats them as part of itself. - TemplateParameterList List; - NamedDecl *Params[N]; +/// \brief Stores a list of template parameters and the associated +/// requires-clause (if any) for a TemplateDecl and its derived classes. +/// Suitable for creating on the stack. +template <size_t N, bool HasRequiresClause> +class FixedSizeTemplateParameterListStorage + : public TemplateParameterList::FixedSizeStorageOwner { + typename TemplateParameterList::FixedSizeStorage< + NamedDecl *, Expr *>::with_counts< + N, HasRequiresClause ? 1u : 0u + >::type storage; public: FixedSizeTemplateParameterListStorage(SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef<NamedDecl *> Params, - SourceLocation RAngleLoc) - : List(TemplateLoc, LAngleLoc, Params, RAngleLoc) { - // Because we're doing an evil layout hack above, have some - // asserts, just to double-check everything is laid out like - // expected. - assert(sizeof(*this) == - TemplateParameterList::totalSizeToAlloc<NamedDecl *>(N) && - "Object layout not as expected"); - assert(this->Params == List.getTrailingObjects<NamedDecl *>() && - "Object layout not as expected"); - } - TemplateParameterList *get() { return &List; } + SourceLocation RAngleLoc, + Expr *RequiresClause) + : FixedSizeStorageOwner( + (assert(N == Params.size()), + assert(HasRequiresClause == static_cast<bool>(RequiresClause)), + new (static_cast<void *>(&storage)) TemplateParameterList( + TemplateLoc, LAngleLoc, Params, RAngleLoc, RequiresClause))) {} }; /// \brief A template argument list. @@ -356,6 +376,11 @@ public: return TemplateParams; } + /// Get the constraint-expression from the associated requires-clause (if any) + const Expr *getRequiresClause() const { + return TemplateParams ? TemplateParams->getRequiresClause() : nullptr; + } + /// Get the underlying, templated declaration. NamedDecl *getTemplatedDecl() const { return TemplatedDecl.getPointer(); } |