@@ -1565,6 +1565,33 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
15651565 Previous.clear ();
15661566 }
15671567
1568+ // HLSL Change Begin - back ported from llvm-project/4409a83c2935.
1569+ // Per [temp.inst], default arguments in function declarations at local scope
1570+ // are instantiated along with the enclosing declaration. For example:
1571+ //
1572+ // template<typename T>
1573+ // void ft() {
1574+ // void f(int = []{ return T::value; }());
1575+ // }
1576+ // template void ft<int>(); // error: type 'int' cannot be used prior
1577+ // to '::' because it has no members
1578+ //
1579+ // The error is issued during instantiation of ft<int>() because substitution
1580+ // into the default argument fails; the default argument is instantiated even
1581+ // though it is never used.
1582+ if (Function->isLocalExternDecl ()) {
1583+ for (ParmVarDecl *PVD : Function->parameters ()) {
1584+ if (!PVD->hasDefaultArg ())
1585+ continue ;
1586+ if (SemaRef.SubstDefaultArgument (D->getInnerLocStart (), PVD,
1587+ TemplateArgs)) {
1588+ Function->setInvalidDecl ();
1589+ return nullptr ;
1590+ }
1591+ }
1592+ }
1593+ // HLSL Change End - back ported from llvm-project/4409a83c2935.
1594+
15681595 SemaRef.CheckFunctionDeclaration (/* Scope*/ nullptr , Function, Previous,
15691596 isExplicitSpecialization);
15701597
@@ -1862,6 +1889,33 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
18621889 Previous.clear ();
18631890 }
18641891
1892+ // HLSL Change Begin - back ported from llvm-project/4409a83c2935.
1893+ // Per [temp.inst], default arguments in member functions of local classes
1894+ // are instantiated along with the member function declaration. For example:
1895+ //
1896+ // template<typename T>
1897+ // void ft() {
1898+ // struct lc {
1899+ // int operator()(int p = []{ return T::value; }());
1900+ // };
1901+ // }
1902+ // template void ft<int>(); // error: type 'int' cannot be used prior
1903+ // to '::'because it has no members
1904+ //
1905+ // The error is issued during instantiation of ft<int>()::lc::operator()
1906+ // because substitution into the default argument fails; the default argument
1907+ // is instantiated even though it is never used.
1908+ if (D->isInLocalScopeForInstantiation ()) {
1909+ for (unsigned P = 0 ; P < Params.size (); ++P) {
1910+ if (!Params[P]->hasDefaultArg ())
1911+ continue ;
1912+ if (SemaRef.SubstDefaultArgument (StartLoc, Params[P], TemplateArgs)) {
1913+ return nullptr ;
1914+ }
1915+ }
1916+ }
1917+ // HLSL Change End - back ported from llvm-project/4409a83c2935.
1918+
18651919 if (!IsClassScopeSpecialization)
18661920 SemaRef.CheckFunctionDeclaration (nullptr , Method, Previous, false );
18671921
@@ -3127,10 +3181,11 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D,
31273181// / Introduce the instantiated function parameters into the local
31283182// / instantiation scope, and set the parameter names to those used
31293183// / in the template.
3130- static bool addInstantiatedParametersToScope (Sema &S, FunctionDecl *Function,
3131- const FunctionDecl *PatternDecl,
3132- LocalInstantiationScope &Scope,
3133- const MultiLevelTemplateArgumentList &TemplateArgs) {
3184+ // / HLSL Change Begin - back ported from llvm-project/601377b23767.
3185+ bool Sema::addInstantiatedParametersToScope (
3186+ FunctionDecl *Function, const FunctionDecl *PatternDecl,
3187+ LocalInstantiationScope &Scope,
3188+ const MultiLevelTemplateArgumentList &TemplateArgs) {
31343189 unsigned FParamIdx = 0 ;
31353190 for (unsigned I = 0 , N = PatternDecl->getNumParams (); I != N; ++I) {
31363191 const ParmVarDecl *PatternParam = PatternDecl->getParamDecl (I);
@@ -3146,7 +3201,7 @@ static bool addInstantiatedParametersToScope(Sema &S, FunctionDecl *Function,
31463201 // it's instantiation-dependent.
31473202 // FIXME: Updating the type to work around this is at best fragile.
31483203 if (!PatternDecl->getType ()->isDependentType ()) {
3149- QualType T = S. SubstType (PatternParam->getType (), TemplateArgs,
3204+ QualType T = SubstType (PatternParam->getType (), TemplateArgs,
31503205 FunctionParam->getLocation (),
31513206 FunctionParam->getDeclName ());
31523207 if (T.isNull ())
@@ -3162,7 +3217,7 @@ static bool addInstantiatedParametersToScope(Sema &S, FunctionDecl *Function,
31623217 // Expand the parameter pack.
31633218 Scope.MakeInstantiatedLocalArgPack (PatternParam);
31643219 Optional<unsigned > NumArgumentsInExpansion
3165- = S. getNumArgumentsInExpansion (PatternParam->getType (), TemplateArgs);
3220+ = getNumArgumentsInExpansion (PatternParam->getType (), TemplateArgs);
31663221 assert (NumArgumentsInExpansion &&
31673222 " should only be called when all template arguments are known" );
31683223 QualType PatternType =
@@ -3171,8 +3226,8 @@ static bool addInstantiatedParametersToScope(Sema &S, FunctionDecl *Function,
31713226 ParmVarDecl *FunctionParam = Function->getParamDecl (FParamIdx);
31723227 FunctionParam->setDeclName (PatternParam->getDeclName ());
31733228 if (!PatternDecl->getType ()->isDependentType ()) {
3174- Sema::ArgumentPackSubstitutionIndexRAII SubstIndex (S , Arg);
3175- QualType T = S. SubstType (PatternType, TemplateArgs,
3229+ Sema::ArgumentPackSubstitutionIndexRAII SubstIndex (* this , Arg);
3230+ QualType T = SubstType (PatternType, TemplateArgs,
31763231 FunctionParam->getLocation (),
31773232 FunctionParam->getDeclName ());
31783233 if (T.isNull ())
@@ -3187,6 +3242,7 @@ static bool addInstantiatedParametersToScope(Sema &S, FunctionDecl *Function,
31873242
31883243 return false ;
31893244}
3245+ // / HLSL Change End - back ported from llvm-project/601377b23767.
31903246
31913247void Sema::InstantiateExceptionSpec (SourceLocation PointOfInstantiation,
31923248 FunctionDecl *Decl) {
@@ -3212,7 +3268,8 @@ void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation,
32123268 getTemplateInstantiationArgs (Decl, nullptr , /* RelativeToPrimary*/ true );
32133269
32143270 FunctionDecl *Template = Proto->getExceptionSpecTemplate ();
3215- if (addInstantiatedParametersToScope (*this , Decl, Template, Scope,
3271+ // HLSL Change - back ported from llvm-project/601377b23767.
3272+ if (addInstantiatedParametersToScope (Decl, Template, Scope,
32163273 TemplateArgs)) {
32173274 UpdateExceptionSpec (Decl, EST_None);
32183275 return ;
@@ -3494,7 +3551,8 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
34943551 // PushDeclContext because we don't have a scope.
34953552 Sema::ContextRAII savedContext (*this , Function);
34963553
3497- if (addInstantiatedParametersToScope (*this , Function, PatternDecl, Scope,
3554+ // HLSL Change - back ported from llvm-project/601377b23767.
3555+ if (addInstantiatedParametersToScope (Function, PatternDecl, Scope,
34983556 TemplateArgs))
34993557 return ;
35003558
0 commit comments