diff options
| -rw-r--r-- | clang/include/clang/AST/DeclTemplate.h | 81 | ||||
| -rw-r--r-- | clang/lib/AST/ASTContext.cpp | 7 | ||||
| -rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 12 | ||||
| -rw-r--r-- | clang/lib/AST/DeclTemplate.cpp | 28 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaLambda.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 5 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 4 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 6 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 1 |
10 files changed, 102 insertions, 47 deletions
diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index 10ec5aa9fce..35356e72372 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -46,7 +46,8 @@ typedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*, /// \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,36 @@ 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: + // FIXME: remove default argument for RequiresClause static TemplateParameterList *Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef<NamedDecl *> Params, - SourceLocation RAngleLoc); + SourceLocation RAngleLoc, + Expr *RequiresClause = nullptr); /// \brief Iterates through the template parameters in this list. typedef NamedDecl** iterator; @@ -127,6 +138,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; } @@ -136,36 +157,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. @@ -353,6 +375,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(); } diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 0d6ad9d0d60..2aa6a148e3e 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -651,6 +651,10 @@ ASTContext::getCanonicalTemplateTemplateParmDecl( cast<TemplateTemplateParmDecl>(*P))); } + assert(!TTP->getRequiresClause() && + "Unexpected requires-clause on template template-parameter"); + LLVM_CONSTEXPR Expr *const CanonRequiresClause = nullptr; + TemplateTemplateParmDecl *CanonTTP = TemplateTemplateParmDecl::Create(*this, getTranslationUnitDecl(), SourceLocation(), TTP->getDepth(), @@ -660,7 +664,8 @@ ASTContext::getCanonicalTemplateTemplateParmDecl( 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); diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index bc1f9f96a06..76b495f84d5 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -2262,11 +2262,21 @@ TemplateParameterList *ASTNodeImporter::ImportTemplateParameterList( 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 diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 37943cdd5b7..bcc8878eeae 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -31,9 +31,11 @@ using namespace clang; 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 @@ TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc, // 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 { @@ -1169,7 +1177,7 @@ createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) { // <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( @@ -1194,7 +1202,7 @@ createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) { // 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 * @@ -1215,7 +1223,7 @@ createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) { NamedDecl *Params[] = {Index, Ts}; return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(), llvm::makeArrayRef(Params), - SourceLocation()); + SourceLocation(), nullptr); } static TemplateParameterList *createBuiltinTemplateParameterList( diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 472637ba800..a9462228d6c 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -235,7 +235,7 @@ getGenericLambdaTemplateParameterList(LambdaScopeInfo *LSI, Sema &SemaRef) { /*Template kw loc*/ SourceLocation(), LAngleLoc, llvm::makeArrayRef((NamedDecl *const *)LSI->AutoTemplateParams.data(), LSI->AutoTemplateParams.size()), - RAngleLoc); + RAngleLoc, nullptr); } return LSI->GLTemplateParameterList; } diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 7fc5db82d32..fbae4ec5c42 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -832,11 +832,10 @@ Sema::ActOnTemplateParameterList(unsigned Depth, 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) { @@ -1956,7 +1955,7 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier( // Fabricate an empty template parameter list for the invented header. return TemplateParameterList::Create(Context, SourceLocation(), SourceLocation(), None, - SourceLocation()); + SourceLocation(), nullptr); } return nullptr; diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 5740bc712e8..6fb3b53f91c 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -4036,8 +4036,8 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result) { 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() && diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 967c2beec4c..208afa6de60 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2932,10 +2932,14 @@ TemplateDeclInstantiator::SubstTemplateParams(TemplateParameterList *L) { 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; } diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 491a0febd50..ec9503aa78f 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -7905,9 +7905,10 @@ ASTReader::ReadTemplateParameterList(ModuleFile &F, 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; } diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 9a1e4f6778b..42e5b35f6d7 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -5381,6 +5381,7 @@ void ASTRecordWriter::AddTemplateParameterList( AddSourceLocation(TemplateParams->getTemplateLoc()); AddSourceLocation(TemplateParams->getLAngleLoc()); AddSourceLocation(TemplateParams->getRAngleLoc()); + // TODO: Concepts Record->push_back(TemplateParams->size()); for (const auto &P : *TemplateParams) AddDeclRef(P); |

