@@ -345,15 +345,23 @@ MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs(
345
345
using namespace TemplateInstArgsHelpers ;
346
346
const Decl *CurDecl = ND;
347
347
348
- if (!ND )
348
+ if (!CurDecl )
349
349
CurDecl = Decl::castFromDeclContext (DC);
350
350
351
351
if (Innermost) {
352
352
Result.addOuterTemplateArguments (const_cast <NamedDecl *>(ND),
353
353
Innermost->asArray (), Final);
354
- if (CurDecl->getDeclContext ()->isFileContext ())
355
- if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(CurDecl))
356
- HandleDefaultTempArgIntoTempTempParam (TTP, Result);
354
+ // Populate placeholder template arguments for TemplateTemplateParmDecls
355
+ // that live in a file-scope DeclContext. This is essential for the case
356
+ // e.g.
357
+ //
358
+ // template <class> concept Concept = false;
359
+ // template <template <Concept C> class T> void foo(T<int>)
360
+ //
361
+ // where parameter C has a depth of 1 but the substituting argument `int`
362
+ // has a depth of 0.
363
+ if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(CurDecl))
364
+ HandleDefaultTempArgIntoTempTempParam (TTP, Result);
357
365
CurDecl = Response::UseNextDecl (CurDecl).NextDecl ;
358
366
}
359
367
@@ -384,10 +392,8 @@ MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs(
384
392
R = Response::ChangeDecl (CTD->getLexicalDeclContext ());
385
393
} else if (!isa<DeclContext>(CurDecl)) {
386
394
R = Response::DontClearRelativeToPrimaryNextDecl (CurDecl);
387
- if (CurDecl->getDeclContext ()->isTranslationUnit ()) {
388
- if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(CurDecl)) {
389
- R = HandleDefaultTempArgIntoTempTempParam (TTP, Result);
390
- }
395
+ if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(CurDecl)) {
396
+ R = HandleDefaultTempArgIntoTempTempParam (TTP, Result);
391
397
}
392
398
} else {
393
399
R = HandleGenericDeclContext (CurDecl);
0 commit comments