зеркало из https://github.com/microsoft/clang-1.git
Refactor instantiation of destructors to use the common CXXMethodDecl
code, fixing a problem where instantiations of out-of-line destructor definitions would had the wrong lexical context. Introduce tests for out-of-line definitions of the constructors, destructors, and conversion functions of a class template partial specialization. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@79682 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
c28bbc2d22
Коммит
17e32f30e2
|
@ -488,17 +488,23 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D) {
|
|||
CXXMethodDecl *Method = 0;
|
||||
|
||||
DeclarationName Name = D->getDeclName();
|
||||
CXXConstructorDecl *ConstructorD = dyn_cast<CXXConstructorDecl>(D);
|
||||
if (ConstructorD) {
|
||||
if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
|
||||
QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
|
||||
Name = SemaRef.Context.DeclarationNames.getCXXConstructorName(
|
||||
SemaRef.Context.getCanonicalType(ClassTy));
|
||||
Method = CXXConstructorDecl::Create(SemaRef.Context, Record,
|
||||
ConstructorD->getLocation(),
|
||||
Constructor->getLocation(),
|
||||
Name, T,
|
||||
ConstructorD->getDeclaratorInfo(),
|
||||
ConstructorD->isExplicit(),
|
||||
ConstructorD->isInline(), false);
|
||||
Constructor->getDeclaratorInfo(),
|
||||
Constructor->isExplicit(),
|
||||
Constructor->isInline(), false);
|
||||
} else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) {
|
||||
QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
|
||||
Name = SemaRef.Context.DeclarationNames.getCXXDestructorName(
|
||||
SemaRef.Context.getCanonicalType(ClassTy));
|
||||
Method = CXXDestructorDecl::Create(SemaRef.Context, Record,
|
||||
Destructor->getLocation(), Name,
|
||||
T, Destructor->isInline(), false);
|
||||
} else {
|
||||
Method = CXXMethodDecl::Create(SemaRef.Context, Record, D->getLocation(),
|
||||
D->getDeclName(), T, D->getDeclaratorInfo(),
|
||||
|
@ -558,34 +564,7 @@ Decl *TemplateDeclInstantiator::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
|
|||
}
|
||||
|
||||
Decl *TemplateDeclInstantiator::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
|
||||
Sema::LocalInstantiationScope Scope(SemaRef);
|
||||
|
||||
llvm::SmallVector<ParmVarDecl *, 4> Params;
|
||||
QualType T = InstantiateFunctionType(D, Params);
|
||||
if (T.isNull())
|
||||
return 0;
|
||||
assert(Params.size() == 0 && "Destructor with parameters?");
|
||||
|
||||
// Build the instantiated destructor declaration.
|
||||
CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
|
||||
CanQualType ClassTy =
|
||||
SemaRef.Context.getCanonicalType(SemaRef.Context.getTypeDeclType(Record));
|
||||
CXXDestructorDecl *Destructor
|
||||
= CXXDestructorDecl::Create(SemaRef.Context, Record,
|
||||
D->getLocation(),
|
||||
SemaRef.Context.DeclarationNames.getCXXDestructorName(ClassTy),
|
||||
T, D->isInline(), false);
|
||||
Destructor->setInstantiationOfMemberFunction(D);
|
||||
if (InitMethodInstantiation(Destructor, D))
|
||||
Destructor->setInvalidDecl();
|
||||
|
||||
bool Redeclaration = false;
|
||||
bool OverloadableAttrRequired = false;
|
||||
NamedDecl *PrevDecl = 0;
|
||||
SemaRef.CheckFunctionDeclaration(Destructor, PrevDecl, Redeclaration,
|
||||
/*FIXME:*/OverloadableAttrRequired);
|
||||
Owner->addDecl(Destructor);
|
||||
return Destructor;
|
||||
return VisitCXXMethodDecl(D);
|
||||
}
|
||||
|
||||
Decl *TemplateDeclInstantiator::VisitCXXConversionDecl(CXXConversionDecl *D) {
|
||||
|
|
|
@ -5,11 +5,22 @@ struct A;
|
|||
|
||||
template<typename T>
|
||||
struct A<T*, 2> {
|
||||
A(T);
|
||||
~A();
|
||||
|
||||
void f(T*);
|
||||
|
||||
operator T*();
|
||||
|
||||
static T value;
|
||||
};
|
||||
|
||||
template<class X> void A<X*, 2>::f(X*) { }
|
||||
|
||||
template<class X> X A<X*, 2>::value;
|
||||
|
||||
template<class X> A<X*, 2>::A(X) { value = 0; }
|
||||
|
||||
template<class X> A<X*, 2>::~A() { }
|
||||
|
||||
template<class X> A<X*, 2>::operator X*() { return 0; }
|
Загрузка…
Ссылка в новой задаче