From: Douglas Gregor Date: Wed, 2 Mar 2011 02:04:06 +0000 (+0000) Subject: When we're substituting into a parameter-type-list nested inside the pattern X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=406f98f6a5a7bde5707085af8d66204e7e76af45;p=clang When we're substituting into a parameter-type-list nested inside the pattern of an expansion, and we have a paramameter that is not a parameter pack, don't suppress substitution of parameter packs within this context. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126819 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 40acdab61c..9abb78bbf3 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -600,8 +600,8 @@ bool RecursiveASTVisitor::TraverseTemplateArgumentLoc( // FIXME: how can TSI ever be NULL? if (TypeSourceInfo *TSI = ArgLoc.getTypeSourceInfo()) return getDerived().TraverseTypeLoc(TSI->getTypeLoc()); - else - return true; + else + getDerived().TraverseType(Arg.getAsType()); } case TemplateArgument::Template: @@ -933,7 +933,11 @@ DEF_TRAVERSE_TYPELOC(FunctionProtoType, { const FunctionProtoType *T = TL.getTypePtr(); for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) { - TRY_TO(TraverseDecl(TL.getArg(I))); + if (TL.getArg(I)) { + TRY_TO(TraverseDecl(TL.getArg(I))); + } else if (I < T->getNumArgs()) { + TRY_TO(TraverseType(T->getArgType(I))); + } } for (FunctionProtoType::exception_iterator E = T->exception_begin(), @@ -1468,6 +1472,8 @@ bool RecursiveASTVisitor::TraverseDeclaratorHelper(DeclaratorDecl *D) { TRY_TO(TraverseNestedNameSpecifier(D->getQualifier())); if (D->getTypeSourceInfo()) TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc())); + else + TRY_TO(TraverseType(D->getType())); return true; } diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index c0f130da88..fa69e70d28 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -1510,6 +1510,7 @@ Sema::SubstBaseSpecifiers(CXXRecordDecl *Instantiation, } SourceLocation EllipsisLoc; + TypeSourceInfo *BaseTypeLoc; if (Base->isPackExpansion()) { // This is a pack expansion. See whether we should expand it now, or // wait until later. @@ -1560,13 +1561,18 @@ Sema::SubstBaseSpecifiers(CXXRecordDecl *Instantiation, // The resulting base specifier will (still) be a pack expansion. EllipsisLoc = Base->getEllipsisLoc(); + Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, -1); + BaseTypeLoc = SubstType(Base->getTypeSourceInfo(), + TemplateArgs, + Base->getSourceRange().getBegin(), + DeclarationName()); + } else { + BaseTypeLoc = SubstType(Base->getTypeSourceInfo(), + TemplateArgs, + Base->getSourceRange().getBegin(), + DeclarationName()); } - Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, -1); - TypeSourceInfo *BaseTypeLoc = SubstType(Base->getTypeSourceInfo(), - TemplateArgs, - Base->getSourceRange().getBegin(), - DeclarationName()); if (!BaseTypeLoc) { Invalid = true; continue; diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index bd1e67629a..fe1e9aa9d2 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -3827,6 +3827,7 @@ bool TreeTransform:: for (unsigned i = 0; i != NumParams; ++i) { if (ParmVarDecl *OldParm = Params[i]) { llvm::Optional NumExpansions; + ParmVarDecl *NewParm = 0; if (OldParm->isParameterPack()) { // We have a function parameter pack that may need to be expanded. llvm::SmallVector Unexpanded; @@ -3836,7 +3837,8 @@ bool TreeTransform:: PackExpansionTypeLoc ExpansionTL = cast(TL); TypeLoc Pattern = ExpansionTL.getPatternLoc(); SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded); - + assert(Unexpanded.size() > 0 && "Could not find parameter packs!"); + // Determine whether we should expand the parameter packs. bool ShouldExpand = false; bool RetainExpansion = false; @@ -3891,11 +3893,14 @@ bool TreeTransform:: // We'll substitute the parameter now without expanding the pack // expansion. + Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); + NewParm = getDerived().TransformFunctionTypeParam(OldParm, + NumExpansions); + } else { + NewParm = getDerived().TransformFunctionTypeParam(OldParm, + llvm::Optional()); } - - Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); - ParmVarDecl *NewParm = getDerived().TransformFunctionTypeParam(OldParm, - NumExpansions); + if (!NewParm) return true; @@ -3910,6 +3915,7 @@ bool TreeTransform:: QualType OldType = ParamTypes[i]; bool IsPackExpansion = false; llvm::Optional NumExpansions; + QualType NewType; if (const PackExpansionType *Expansion = dyn_cast(OldType)) { // We have a function parameter pack that may need to be expanded. @@ -3964,10 +3970,12 @@ bool TreeTransform:: // expansion. OldType = Expansion->getPattern(); IsPackExpansion = true; + Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); + NewType = getDerived().TransformType(OldType); + } else { + NewType = getDerived().TransformType(OldType); } - Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); - QualType NewType = getDerived().TransformType(OldType); if (NewType.isNull()) return true; diff --git a/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp b/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp index 2df6d33a89..cda9ac8b04 100644 --- a/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp +++ b/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp @@ -216,3 +216,21 @@ namespace ExpandingNonTypeTemplateParameters { tuple_of_values::apply::type tv4; // expected-error{{too many template arguments for class template 'apply'}} } + +namespace ExpandingFunctionParameters { + template + struct X0 { + typedef int type; + }; + + template + struct X1 { + template + typename X0::type f(U...); + }; + + void test() { + X1 x1; + x1.f(17, 3.14159); + } +}