hubert.reinterpretcast updated this revision to Diff 57216. hubert.reinterpretcast added a comment.
Set requires-clause when creating TemplateParameterLists; NFC Removes the default argument for the requires-clause constraint expression in TemplateParameterList::Create. An appropriate argument is supplied at the various call sites. Serialization changes will be left until the feature is otherwise complete so that the version number does not need to be bumped multiple times. http://reviews.llvm.org/D19322 Files: include/clang/AST/DeclTemplate.h lib/AST/ASTContext.cpp lib/AST/ASTImporter.cpp lib/AST/DeclTemplate.cpp lib/Sema/SemaLambda.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateDeduction.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTWriter.cpp
Index: lib/Serialization/ASTWriter.cpp =================================================================== --- lib/Serialization/ASTWriter.cpp +++ lib/Serialization/ASTWriter.cpp @@ -5359,6 +5359,7 @@ AddSourceLocation(TemplateParams->getTemplateLoc()); AddSourceLocation(TemplateParams->getLAngleLoc()); AddSourceLocation(TemplateParams->getRAngleLoc()); + // TODO: Concepts Record->push_back(TemplateParams->size()); for (const auto &P : *TemplateParams) AddDeclRef(P); Index: lib/Serialization/ASTReader.cpp =================================================================== --- lib/Serialization/ASTReader.cpp +++ lib/Serialization/ASTReader.cpp @@ -7892,9 +7892,10 @@ while (NumParams--) Params.push_back(ReadDeclAs<NamedDecl>(F, Record, Idx)); + // TODO: Concepts TemplateParameterList* TemplateParams = TemplateParameterList::Create(Context, TemplateLoc, LAngleLoc, - Params, RAngleLoc); + Params, RAngleLoc, nullptr); return TemplateParams; } Index: lib/Sema/SemaTemplateInstantiateDecl.cpp =================================================================== --- lib/Sema/SemaTemplateInstantiateDecl.cpp +++ lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2947,10 +2947,14 @@ if (Invalid) return nullptr; + // Note: we substitute into associated constraints later + Expr *const UninstantiatedRequiresClause = L->getRequiresClause(); + TemplateParameterList *InstL = TemplateParameterList::Create(SemaRef.Context, L->getTemplateLoc(), L->getLAngleLoc(), Params, - L->getRAngleLoc()); + L->getRAngleLoc(), + UninstantiatedRequiresClause); return InstL; } Index: lib/Sema/SemaTemplateDeduction.cpp =================================================================== --- lib/Sema/SemaTemplateDeduction.cpp +++ lib/Sema/SemaTemplateDeduction.cpp @@ -4022,8 +4022,8 @@ nullptr, false, false); QualType TemplArg = QualType(TemplParam->getTypeForDecl(), 0); NamedDecl *TemplParamPtr = TemplParam; - FixedSizeTemplateParameterListStorage<1> TemplateParamsSt( - Loc, Loc, TemplParamPtr, Loc); + FixedSizeTemplateParameterListStorage<1, false> TemplateParamsSt( + Loc, Loc, TemplParamPtr, Loc, nullptr); QualType FuncParam = SubstituteAutoTransform(*this, TemplArg).Apply(Type); assert(!FuncParam.isNull() && Index: lib/Sema/SemaTemplate.cpp =================================================================== --- lib/Sema/SemaTemplate.cpp +++ lib/Sema/SemaTemplate.cpp @@ -831,11 +831,10 @@ if (ExportLoc.isValid()) Diag(ExportLoc, diag::warn_template_export_unsupported); - // FIXME: store RequiresClause return TemplateParameterList::Create( Context, TemplateLoc, LAngleLoc, llvm::makeArrayRef((NamedDecl *const *)Params.data(), Params.size()), - RAngleLoc); + RAngleLoc, RequiresClause); } static void SetNestedNameSpecifier(TagDecl *T, const CXXScopeSpec &SS) { @@ -1953,7 +1952,7 @@ // Fabricate an empty template parameter list for the invented header. return TemplateParameterList::Create(Context, SourceLocation(), SourceLocation(), None, - SourceLocation()); + SourceLocation(), nullptr); } return nullptr; Index: lib/Sema/SemaLambda.cpp =================================================================== --- lib/Sema/SemaLambda.cpp +++ lib/Sema/SemaLambda.cpp @@ -235,7 +235,7 @@ /*Template kw loc*/ SourceLocation(), LAngleLoc, llvm::makeArrayRef((NamedDecl *const *)LSI->AutoTemplateParams.data(), LSI->AutoTemplateParams.size()), - RAngleLoc); + RAngleLoc, nullptr); } return LSI->GLTemplateParameterList; } Index: lib/AST/DeclTemplate.cpp =================================================================== --- lib/AST/DeclTemplate.cpp +++ lib/AST/DeclTemplate.cpp @@ -31,9 +31,11 @@ TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef<NamedDecl *> Params, - SourceLocation RAngleLoc) + SourceLocation RAngleLoc, + Expr *RequiresClause) : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc), - NumParams(Params.size()), ContainsUnexpandedParameterPack(false) { + NumParams(Params.size()), ContainsUnexpandedParameterPack(false), + HasRequiresClause(static_cast<bool>(RequiresClause)) { assert(this->NumParams == NumParams && "Too many template parameters"); for (unsigned Idx = 0; Idx < NumParams; ++Idx) { NamedDecl *P = Params[Idx]; @@ -52,15 +54,21 @@ // template parameter list does too. } } + if (RequiresClause) { + *getTrailingObjects<Expr *>() = RequiresClause; + } } -TemplateParameterList *TemplateParameterList::Create( - const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, - ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc) { - void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *>(Params.size()), +TemplateParameterList * +TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc, + SourceLocation LAngleLoc, + ArrayRef<NamedDecl *> Params, + SourceLocation RAngleLoc, Expr *RequiresClause) { + void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>( + Params.size(), RequiresClause ? 1u : 0u), llvm::alignOf<TemplateParameterList>()); return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params, - RAngleLoc); + RAngleLoc, RequiresClause); } unsigned TemplateParameterList::getMinRequiredArguments() const { @@ -1211,7 +1219,7 @@ // <typename T, T ...Ints> NamedDecl *P[2] = {T, N}; auto *TPL = TemplateParameterList::Create( - C, SourceLocation(), SourceLocation(), P, SourceLocation()); + C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr); // template <typename T, ...Ints> class IntSeq auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create( @@ -1236,7 +1244,7 @@ // template <template <typename T, T ...Ints> class IntSeq, typename T, T N> return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(), - Params, SourceLocation()); + Params, SourceLocation(), nullptr); } static TemplateParameterList *createBuiltinTemplateParameterList( Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -2245,11 +2245,22 @@ ToParams.push_back(cast<NamedDecl>(To)); } + Expr *ToRequiresClause; + if (Expr *const R = Params->getRequiresClause()) { + ToRequiresClause = Importer.Import(R); + if (!ToRequiresClause) + return nullptr; + } + else { + ToRequiresClause = nullptr; + } + return TemplateParameterList::Create(Importer.getToContext(), Importer.Import(Params->getTemplateLoc()), Importer.Import(Params->getLAngleLoc()), ToParams, - Importer.Import(Params->getRAngleLoc())); + Importer.Import(Params->getRAngleLoc()), + ToRequiresClause); } TemplateArgument Index: lib/AST/ASTContext.cpp =================================================================== --- lib/AST/ASTContext.cpp +++ lib/AST/ASTContext.cpp @@ -653,6 +653,10 @@ cast<TemplateTemplateParmDecl>(*P))); } + assert(!TTP->getRequiresClause() && + "Unexpected requires-clause on template template-parameter"); + constexpr Expr *const CanonRequiresClause = nullptr; + TemplateTemplateParmDecl *CanonTTP = TemplateTemplateParmDecl::Create(*this, getTranslationUnitDecl(), SourceLocation(), TTP->getDepth(), @@ -662,7 +666,8 @@ TemplateParameterList::Create(*this, SourceLocation(), SourceLocation(), CanonParams, - SourceLocation())); + SourceLocation(), + CanonRequiresClause)); // Get the new insert position for the node we care about. Canonical = CanonTemplateTemplateParms.FindNodeOrInsertPos(ID, InsertPos); Index: include/clang/AST/DeclTemplate.h =================================================================== --- include/clang/AST/DeclTemplate.h +++ include/clang/AST/DeclTemplate.h @@ -46,7 +46,8 @@ /// \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; @@ -56,26 +57,35 @@ /// 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; @@ -127,6 +137,16 @@ 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; } @@ -136,36 +156,33 @@ } friend TrailingObjects; - template <size_t N> friend class FixedSizeTemplateParameterListStorage; + + template <size_t N, bool HasRequiresClause> + friend class FixedSizeTemplateParameterListStorage; }; -/// \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. @@ -355,6 +372,11 @@ 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(); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits