зеркало из https://github.com/microsoft/clang-1.git
Fix two issues with the substitution of template template parameters
when instantiating the declaration of a member template: - Only check if the have a template template argument at a specific position when we already know that we have template arguments at that level; otherwise, we're substituting for a level-reduced template template parameter. - When trying to find an instantiated declaration for a template template parameter, look into the instantiated scope. This was a typo, where we had two checks for TemplateTypeParmDecl, one of which should have been a TemplateTemplateParmDecl. With these changes, tramp3d-v4 passes -fsyntax-only. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95421 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
18aba0dd51
Коммит
6d3e627dac
|
@ -578,6 +578,14 @@ Decl *TemplateInstantiator::TransformDecl(Decl *D) {
|
|||
|
||||
if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(D)) {
|
||||
if (TTP->getDepth() < TemplateArgs.getNumLevels()) {
|
||||
// If the corresponding template argument is NULL or non-existent, it's
|
||||
// because we are performing instantiation from explicitly-specified
|
||||
// template arguments in a function template, but there were some
|
||||
// arguments left unspecified.
|
||||
if (!TemplateArgs.hasTemplateArgument(TTP->getDepth(),
|
||||
TTP->getPosition()))
|
||||
return D;
|
||||
|
||||
TemplateName Template
|
||||
= TemplateArgs(TTP->getDepth(), TTP->getPosition()).getAsTemplate();
|
||||
assert(!Template.isNull() && Template.getAsTemplateDecl() &&
|
||||
|
@ -585,14 +593,6 @@ Decl *TemplateInstantiator::TransformDecl(Decl *D) {
|
|||
return Template.getAsTemplateDecl();
|
||||
}
|
||||
|
||||
// If the corresponding template argument is NULL or non-existent, it's
|
||||
// because we are performing instantiation from explicitly-specified
|
||||
// template arguments in a function template, but there were some
|
||||
// arguments left unspecified.
|
||||
if (!TemplateArgs.hasTemplateArgument(TTP->getDepth(),
|
||||
TTP->getPosition()))
|
||||
return D;
|
||||
|
||||
// Fall through to find the instantiated declaration for this template
|
||||
// template parameter.
|
||||
}
|
||||
|
|
|
@ -2159,7 +2159,7 @@ NamedDecl *Sema::FindInstantiatedDecl(NamedDecl *D,
|
|||
const MultiLevelTemplateArgumentList &TemplateArgs) {
|
||||
DeclContext *ParentDC = D->getDeclContext();
|
||||
if (isa<ParmVarDecl>(D) || isa<NonTypeTemplateParmDecl>(D) ||
|
||||
isa<TemplateTypeParmDecl>(D) || isa<TemplateTypeParmDecl>(D) ||
|
||||
isa<TemplateTypeParmDecl>(D) || isa<TemplateTemplateParmDecl>(D) ||
|
||||
ParentDC->isFunctionOrMethod()) {
|
||||
// D is a local of some kind. Look into the map of local
|
||||
// declarations to their instantiations.
|
||||
|
|
|
@ -73,3 +73,15 @@ void test_incomplete_access(X1<int> *x1, X2<int> *x2) {
|
|||
float &fr = x1->get<float>();
|
||||
(void)x2->get<float>(); // expected-error{{implicit instantiation of undefined template}}
|
||||
}
|
||||
|
||||
// Instantiation of template template parameters in a member function
|
||||
// template.
|
||||
namespace TTP {
|
||||
template<int Dim> struct X {
|
||||
template<template<class> class M, class T> void f(const M<T>&);
|
||||
};
|
||||
|
||||
template<typename T> struct Y { };
|
||||
|
||||
void test_f(X<3> x, Y<int> y) { x.f(y); }
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче