diff options
Diffstat (limited to 'clang/lib/AST/DeclTemplate.cpp')
-rw-r--r-- | clang/lib/AST/DeclTemplate.cpp | 55 |
1 files changed, 48 insertions, 7 deletions
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 25235c56ec46..ec8b00a9eb7d 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -68,12 +68,16 @@ TemplateParameterList::TemplateParameterList(const ASTContext& C, if (!IsPack && TTP->getTemplateParameters()->containsUnexpandedParameterPack()) ContainsUnexpandedParameterPack = true; - } else if (const TypeConstraint *TC = - cast<TemplateTypeParmDecl>(P)->getTypeConstraint()) { - if (TC->getImmediatelyDeclaredConstraint() - ->containsUnexpandedParameterPack()) - ContainsUnexpandedParameterPack = true; - HasConstrainedParameters = true; + } else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) { + if (const TypeConstraint *TC = TTP->getTypeConstraint()) { + if (TC->getImmediatelyDeclaredConstraint() + ->containsUnexpandedParameterPack()) + ContainsUnexpandedParameterPack = true; + } + if (TTP->hasTypeConstraint()) + HasConstrainedParameters = true; + } else { + llvm_unreachable("unexpcted template parameter type"); } // FIXME: If a default argument contains an unexpanded parameter pack, the // template parameter list does too. @@ -86,6 +90,30 @@ TemplateParameterList::TemplateParameterList(const ASTContext& C, } } +bool TemplateParameterList::containsUnexpandedParameterPack() const { + if (ContainsUnexpandedParameterPack) + return true; + if (!HasConstrainedParameters) + return false; + + // An implicit constrained parameter might have had a use of an unexpanded + // pack added to it after the template parameter list was created. All + // implicit parameters are at the end of the parameter list. + for (const NamedDecl *Param : llvm::reverse(asArray())) { + if (!Param->isImplicit()) + break; + + if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) { + const auto *TC = TTP->getTypeConstraint(); + if (TC && TC->getImmediatelyDeclaredConstraint() + ->containsUnexpandedParameterPack()) + return true; + } + } + + return false; +} + TemplateParameterList * TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, @@ -167,6 +195,18 @@ bool TemplateParameterList::hasAssociatedConstraints() const { return HasRequiresClause || HasConstrainedParameters; } +bool TemplateParameterList::shouldIncludeTypeForArgument( + const TemplateParameterList *TPL, unsigned Idx) { + if (!TPL || Idx >= TPL->size()) + return true; + const NamedDecl *TemplParam = TPL->getParam(Idx); + if (const auto *ParamValueDecl = + dyn_cast<NonTypeTemplateParmDecl>(TemplParam)) + if (ParamValueDecl->getType()->getContainedDeducedType()) + return true; + return false; +} + namespace clang { void *allocateDefaultArgStorageChain(const ASTContext &C) { @@ -1420,8 +1460,9 @@ void TypeConstraint::print(llvm::raw_ostream &OS, PrintingPolicy Policy) const { ConceptName.printName(OS, Policy); if (hasExplicitTemplateArgs()) { OS << "<"; + // FIXME: Find corresponding parameter for argument for (auto &ArgLoc : ArgsAsWritten->arguments()) - ArgLoc.getArgument().print(Policy, OS); + ArgLoc.getArgument().print(Policy, OS, /*IncludeType*/ false); OS << ">"; } } |