forked from OSchip/llvm-project
Only set the point of instantiation for an implicit or explicit
instantiation once we have committed to performing the instantiation. As part of this, make our makeshift template-instantiation location information suck slightly less. Fixes PR5264. llvm-svn: 85209
This commit is contained in:
parent
d169e6c281
commit
ef6ab417c1
|
@ -3189,7 +3189,7 @@ public:
|
|||
bool Complain = true);
|
||||
|
||||
bool
|
||||
InstantiateClassTemplateSpecialization(
|
||||
InstantiateClassTemplateSpecialization(SourceLocation PointOfInstantiation,
|
||||
ClassTemplateSpecializationDecl *ClassTemplateSpec,
|
||||
TemplateSpecializationKind TSK,
|
||||
bool Complain = true);
|
||||
|
|
|
@ -3726,8 +3726,6 @@ Sema::ActOnExplicitInstantiation(Scope *S,
|
|||
Specialization->setLexicalDeclContext(CurContext);
|
||||
CurContext->addDecl(Specialization);
|
||||
|
||||
Specialization->setPointOfInstantiation(TemplateNameLoc);
|
||||
|
||||
// C++ [temp.explicit]p3:
|
||||
// A definition of a class template or class member template
|
||||
// shall be in scope at the point of the explicit instantiation of
|
||||
|
@ -3739,7 +3737,7 @@ Sema::ActOnExplicitInstantiation(Scope *S,
|
|||
= cast_or_null<ClassTemplateSpecializationDecl>(
|
||||
Specialization->getDefinition(Context));
|
||||
if (!Def)
|
||||
InstantiateClassTemplateSpecialization(Specialization, TSK);
|
||||
InstantiateClassTemplateSpecialization(TemplateNameLoc, Specialization, TSK);
|
||||
else // Instantiate the members of this class template specialization.
|
||||
InstantiateClassTemplateSpecializationMembers(TemplateNameLoc, Def, TSK);
|
||||
|
||||
|
@ -4280,6 +4278,13 @@ namespace {
|
|||
/// \brief Returns the name of the entity whose type is being rebuilt.
|
||||
DeclarationName getBaseEntity() { return Entity; }
|
||||
|
||||
/// \brief Sets the "base" location and entity when that
|
||||
/// information is known based on another transformation.
|
||||
void setBase(SourceLocation Loc, DeclarationName Entity) {
|
||||
this->Loc = Loc;
|
||||
this->Entity = Entity;
|
||||
}
|
||||
|
||||
/// \brief Transforms an expression by returning the expression itself
|
||||
/// (an identity function).
|
||||
///
|
||||
|
|
|
@ -392,6 +392,13 @@ namespace {
|
|||
/// \brief Returns the name of the entity being instantiated, if any.
|
||||
DeclarationName getBaseEntity() { return Entity; }
|
||||
|
||||
/// \brief Sets the "base" location and entity when that
|
||||
/// information is known based on another transformation.
|
||||
void setBase(SourceLocation Loc, DeclarationName Entity) {
|
||||
this->Loc = Loc;
|
||||
this->Entity = Entity;
|
||||
}
|
||||
|
||||
/// \brief Transform the given declaration by instantiating a reference to
|
||||
/// this declaration.
|
||||
Decl *TransformDecl(Decl *D);
|
||||
|
@ -849,6 +856,10 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
|
|||
= Instantiation->getMemberSpecializationInfo()) {
|
||||
MSInfo->setTemplateSpecializationKind(TSK);
|
||||
MSInfo->setPointOfInstantiation(PointOfInstantiation);
|
||||
} else if (ClassTemplateSpecializationDecl *Spec
|
||||
= dyn_cast<ClassTemplateSpecializationDecl>(Instantiation)) {
|
||||
Spec->setTemplateSpecializationKind(TSK);
|
||||
Spec->setPointOfInstantiation(PointOfInstantiation);
|
||||
}
|
||||
|
||||
InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation);
|
||||
|
@ -915,6 +926,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
|
|||
|
||||
bool
|
||||
Sema::InstantiateClassTemplateSpecialization(
|
||||
SourceLocation PointOfInstantiation,
|
||||
ClassTemplateSpecializationDecl *ClassTemplateSpec,
|
||||
TemplateSpecializationKind TSK,
|
||||
bool Complain) {
|
||||
|
@ -932,10 +944,9 @@ Sema::InstantiateClassTemplateSpecialization(
|
|||
// declaration (C++0x [temp.explicit]p10); go ahead and perform the
|
||||
// explicit instantiation.
|
||||
ClassTemplateSpec->setSpecializationKind(TSK);
|
||||
InstantiateClassTemplateSpecializationMembers(
|
||||
/*FIXME?*/ClassTemplateSpec->getPointOfInstantiation(),
|
||||
ClassTemplateSpec,
|
||||
TSK);
|
||||
InstantiateClassTemplateSpecializationMembers(PointOfInstantiation,
|
||||
ClassTemplateSpec,
|
||||
TSK);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1019,8 +1030,7 @@ Sema::InstantiateClassTemplateSpecialization(
|
|||
if (Ambiguous) {
|
||||
// Partial ordering did not produce a clear winner. Complain.
|
||||
ClassTemplateSpec->setInvalidDecl();
|
||||
Diag(ClassTemplateSpec->getPointOfInstantiation(),
|
||||
diag::err_partial_spec_ordering_ambiguous)
|
||||
Diag(PointOfInstantiation, diag::err_partial_spec_ordering_ambiguous)
|
||||
<< ClassTemplateSpec;
|
||||
|
||||
// Print the matching partial specializations.
|
||||
|
@ -1053,12 +1063,9 @@ Sema::InstantiateClassTemplateSpecialization(
|
|||
Pattern = OrigTemplate->getTemplatedDecl();
|
||||
}
|
||||
|
||||
// Note that this is an instantiation.
|
||||
ClassTemplateSpec->setSpecializationKind(TSK);
|
||||
|
||||
bool Result = InstantiateClass(ClassTemplateSpec->getPointOfInstantiation(),
|
||||
ClassTemplateSpec, Pattern,
|
||||
getTemplateInstantiationArgs(ClassTemplateSpec),
|
||||
bool Result = InstantiateClass(PointOfInstantiation, ClassTemplateSpec,
|
||||
Pattern,
|
||||
getTemplateInstantiationArgs(ClassTemplateSpec),
|
||||
TSK,
|
||||
Complain);
|
||||
|
||||
|
|
|
@ -1694,13 +1694,10 @@ bool Sema::RequireCompleteType(SourceLocation Loc, QualType T,
|
|||
if (const RecordType *Record = T->getAs<RecordType>()) {
|
||||
if (ClassTemplateSpecializationDecl *ClassTemplateSpec
|
||||
= dyn_cast<ClassTemplateSpecializationDecl>(Record->getDecl())) {
|
||||
if (ClassTemplateSpec->getSpecializationKind() == TSK_Undeclared) {
|
||||
if (Loc.isValid())
|
||||
ClassTemplateSpec->setPointOfInstantiation(Loc);
|
||||
return InstantiateClassTemplateSpecialization(ClassTemplateSpec,
|
||||
if (ClassTemplateSpec->getSpecializationKind() == TSK_Undeclared)
|
||||
return InstantiateClassTemplateSpecialization(Loc, ClassTemplateSpec,
|
||||
TSK_ImplicitInstantiation,
|
||||
/*Complain=*/diag != 0);
|
||||
}
|
||||
} else if (CXXRecordDecl *Rec
|
||||
= dyn_cast<CXXRecordDecl>(Record->getDecl())) {
|
||||
if (CXXRecordDecl *Pattern = Rec->getInstantiatedFromMemberClass()) {
|
||||
|
@ -1708,13 +1705,11 @@ bool Sema::RequireCompleteType(SourceLocation Loc, QualType T,
|
|||
assert(MSInfo && "Missing member specialization information?");
|
||||
// This record was instantiated from a class within a template.
|
||||
if (MSInfo->getTemplateSpecializationKind()
|
||||
!= TSK_ExplicitSpecialization) {
|
||||
MSInfo->setPointOfInstantiation(Loc);
|
||||
!= TSK_ExplicitSpecialization)
|
||||
return InstantiateClass(Loc, Rec, Pattern,
|
||||
getTemplateInstantiationArgs(Rec),
|
||||
TSK_ImplicitInstantiation,
|
||||
/*Complain=*/diag != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1884,6 +1884,7 @@ TreeTransform<Derived>::TransformTemplateArgument(const TemplateArgument &Arg) {
|
|||
return Arg;
|
||||
|
||||
case TemplateArgument::Type: {
|
||||
TemporaryBase Rebase(*this, Arg.getLocation(), DeclarationName());
|
||||
QualType T = getDerived().TransformType(Arg.getAsType());
|
||||
if (T.isNull())
|
||||
return TemplateArgument();
|
||||
|
@ -1891,6 +1892,10 @@ TreeTransform<Derived>::TransformTemplateArgument(const TemplateArgument &Arg) {
|
|||
}
|
||||
|
||||
case TemplateArgument::Declaration: {
|
||||
DeclarationName Name;
|
||||
if (NamedDecl *ND = dyn_cast<NamedDecl>(Arg.getAsDecl()))
|
||||
Name = ND->getDeclName();
|
||||
TemporaryBase Rebase(*this, Arg.getLocation(), Name);
|
||||
Decl *D = getDerived().TransformDecl(Arg.getAsDecl());
|
||||
if (!D)
|
||||
return TemplateArgument();
|
||||
|
|
|
@ -9,14 +9,12 @@ template void f0(int); // okay
|
|||
// template shall be in scope at the point of the explicit instantiation of
|
||||
// the member function template.
|
||||
struct X0; // expected-note 2{{forward declaration}}
|
||||
template<typename> struct X1; // expected-note 2{{declared here}} \
|
||||
// expected-note 3{{forward declaration}}
|
||||
template<typename> struct X1; // expected-note 5{{declared here}}
|
||||
|
||||
// FIXME: Repeated diagnostics here!
|
||||
template void X0::f0<int>(int); // expected-error 2{{incomplete type}} \
|
||||
// expected-error{{invalid token after}}
|
||||
template void X1<int>::f0<int>(int); // expected-error{{implicit instantiation of undefined template}} \
|
||||
// expected-error{{incomplete type}} \\
|
||||
template void X1<int>::f0<int>(int); // expected-error 2{{implicit instantiation of undefined template}} \
|
||||
// expected-error{{invalid token}}
|
||||
|
||||
// A definition of a class template or class member template shall be in scope
|
||||
|
@ -37,10 +35,10 @@ template struct X2<int>::Inner<float>; // expected-error{{explicit instantiation
|
|||
// A definition of a class template shall be in scope at the point of an
|
||||
// explicit instantiation of a member function or a static data member of the
|
||||
// class template.
|
||||
template void X1<int>::f1(int); // expected-error{{incomplete type}} \
|
||||
template void X1<int>::f1(int); // expected-error{{undefined template}} \
|
||||
// expected-error{{does not refer}}
|
||||
|
||||
template int X1<int>::member; // expected-error{{incomplete type}} \
|
||||
template int X1<int>::member; // expected-error{{undefined template}} \
|
||||
// expected-error{{does not refer}}
|
||||
|
||||
// A definition of a member class of a class template shall be in scope at the
|
||||
|
|
|
@ -20,8 +20,7 @@ int test_incomplete_specs(A<double, double> *a1,
|
|||
A<double> *a2)
|
||||
{
|
||||
(void)a1->x; // expected-error{{incomplete definition of type 'A<double, double>'}}
|
||||
(void)a2->x; // expected-error{{implicit instantiation of undefined template 'struct A<double, int>'}} \
|
||||
// expected-note{{first required here}}
|
||||
(void)a2->x; // expected-error{{implicit instantiation of undefined template 'struct A<double, int>'}}
|
||||
}
|
||||
|
||||
typedef float FLOAT;
|
||||
|
@ -71,8 +70,7 @@ namespace N {
|
|||
}
|
||||
|
||||
// Diagnose specialization errors
|
||||
struct A<double> { }; // expected-error{{template specialization requires 'template<>'}} \
|
||||
// expected-error{{after instantiation}}
|
||||
struct A<double> { }; // expected-error{{template specialization requires 'template<>'}}
|
||||
|
||||
template<> struct ::A<double>;
|
||||
|
||||
|
@ -100,3 +98,9 @@ template<> struct N::B<char> {
|
|||
int testf(int x) { return f(x); }
|
||||
};
|
||||
|
||||
// PR5264
|
||||
template <typename T> class Foo;
|
||||
Foo<int>* v;
|
||||
Foo<int>& F() { return *v; }
|
||||
template <typename T> class Foo {};
|
||||
Foo<int> x;
|
||||
|
|
Loading…
Reference in New Issue