Factor out and centralize repeated 'getExpandedPackSize'.

This commit is contained in:
Richard Smith 2020-12-13 00:50:01 -08:00
parent b8c847ee73
commit abbd57e558
4 changed files with 33 additions and 67 deletions

View File

@ -3353,6 +3353,36 @@ inline TemplateDecl *getAsTypeTemplateDecl(Decl *D) {
: nullptr;
}
/// Check whether the template parameter is a pack expansion, and if so,
/// determine the number of parameters produced by that expansion. For instance:
///
/// \code
/// template<typename ...Ts> struct A {
/// template<Ts ...NTs, template<Ts> class ...TTs, typename ...Us> struct B;
/// };
/// \endcode
///
/// In \c A<int,int>::B, \c NTs and \c TTs have expanded pack size 2, and \c Us
/// is not a pack expansion, so returns an empty Optional.
inline Optional<unsigned> getExpandedPackSize(const NamedDecl *Param) {
if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
if (TTP->isExpandedParameterPack())
return TTP->getNumExpansionParameters();
}
if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
if (NTTP->isExpandedParameterPack())
return NTTP->getNumExpansionTypes();
}
if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
if (TTP->isExpandedParameterPack())
return TTP->getNumExpansionTemplateParameters();
}
return None;
}
} // namespace clang
#endif // LLVM_CLANG_AST_DECLTEMPLATE_H

View File

@ -102,24 +102,10 @@ unsigned TemplateParameterList::getMinRequiredArguments() const {
unsigned NumRequiredArgs = 0;
for (const NamedDecl *P : asArray()) {
if (P->isTemplateParameterPack()) {
if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
if (NTTP->isExpandedParameterPack()) {
NumRequiredArgs += NTTP->getNumExpansionTypes();
continue;
}
} else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
if (TTP->isExpandedParameterPack()) {
NumRequiredArgs += TTP->getNumExpansionParameters();
continue;
}
} else {
const auto *TP = cast<TemplateTemplateParmDecl>(P);
if (TP->isExpandedParameterPack()) {
NumRequiredArgs += TP->getNumExpansionTemplateParameters();
continue;
}
if (Optional<unsigned> Expansions = getExpandedPackSize(P)) {
NumRequiredArgs += *Expansions;
continue;
}
break;
}

View File

@ -5588,39 +5588,6 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param,
return false;
}
/// Check whether the template parameter is a pack expansion, and if so,
/// determine the number of parameters produced by that expansion. For instance:
///
/// \code
/// template<typename ...Ts> struct A {
/// template<Ts ...NTs, template<Ts> class ...TTs, typename ...Us> struct B;
/// };
/// \endcode
///
/// In \c A<int,int>::B, \c NTs and \c TTs have expanded pack size 2, and \c Us
/// is not a pack expansion, so returns an empty Optional.
static Optional<unsigned> getExpandedPackSize(NamedDecl *Param) {
if (TemplateTypeParmDecl *TTP
= dyn_cast<TemplateTypeParmDecl>(Param)) {
if (TTP->isExpandedParameterPack())
return TTP->getNumExpansionParameters();
}
if (NonTypeTemplateParmDecl *NTTP
= dyn_cast<NonTypeTemplateParmDecl>(Param)) {
if (NTTP->isExpandedParameterPack())
return NTTP->getNumExpansionTypes();
}
if (TemplateTemplateParmDecl *TTP
= dyn_cast<TemplateTemplateParmDecl>(Param)) {
if (TTP->isExpandedParameterPack())
return TTP->getNumExpansionTemplateParameters();
}
return None;
}
/// Diagnose a missing template argument.
template<typename TemplateParmDecl>
static bool diagnoseMissingArgument(Sema &S, SourceLocation Loc,

View File

@ -658,23 +658,6 @@ static TemplateParameter makeTemplateParameter(Decl *D) {
return TemplateParameter(cast<TemplateTemplateParmDecl>(D));
}
/// If \p Param is an expanded parameter pack, get the number of expansions.
static Optional<unsigned> getExpandedPackSize(NamedDecl *Param) {
if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
if (TTP->isExpandedParameterPack())
return TTP->getNumExpansionParameters();
if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param))
if (NTTP->isExpandedParameterPack())
return NTTP->getNumExpansionTypes();
if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param))
if (TTP->isExpandedParameterPack())
return TTP->getNumExpansionTemplateParameters();
return None;
}
/// A pack that we're currently deducing.
struct clang::DeducedPack {
// The index of the pack.