aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/DeclTemplate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/DeclTemplate.cpp')
-rw-r--r--clang/lib/AST/DeclTemplate.cpp55
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 << ">";
}
}