Template instantiation for conversion functions

llvm-svn: 67664
This commit is contained in:
Douglas Gregor 2009-03-25 00:34:44 +00:00
parent 7b7b3f0817
commit 1880ba59f3
2 changed files with 42 additions and 0 deletions

View File

@ -46,6 +46,7 @@ namespace {
Decl *VisitCXXMethodDecl(CXXMethodDecl *D);
Decl *VisitCXXConstructorDecl(CXXConstructorDecl *D);
Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D);
Decl *VisitCXXConversionDecl(CXXConversionDecl *D);
Decl *VisitParmVarDecl(ParmVarDecl *D);
Decl *VisitOriginalParmVarDecl(OriginalParmVarDecl *D);
@ -320,6 +321,36 @@ Decl *TemplateDeclInstantiator::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
return Destructor;
}
Decl *TemplateDeclInstantiator::VisitCXXConversionDecl(CXXConversionDecl *D) {
llvm::SmallVector<ParmVarDecl *, 16> Params;
QualType T = InstantiateFunctionType(D, Params);
if (T.isNull())
return 0;
assert(Params.size() == 0 && "Destructor with parameters?");
// Build the instantiated conversion declaration.
CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
QualType ConvTy
= SemaRef.Context.getCanonicalType(T->getAsFunctionType()->getResultType());
CXXConversionDecl *Conversion
= CXXConversionDecl::Create(SemaRef.Context, Record,
D->getLocation(),
SemaRef.Context.DeclarationNames.getCXXConversionFunctionName(ConvTy),
T, D->isInline(), D->isExplicit());
if (InitMethodInstantiation(Conversion, D))
Conversion->setInvalidDecl();
bool Redeclaration = false;
bool OverloadableAttrRequired = false;
NamedDecl *PrevDecl = 0;
if (SemaRef.CheckFunctionDeclaration(Conversion, PrevDecl, Redeclaration,
/*FIXME:*/OverloadableAttrRequired))
Conversion->setInvalidDecl();
Owner->addDecl(Conversion);
return Conversion;
}
Decl *TemplateDeclInstantiator::VisitParmVarDecl(ParmVarDecl *D) {
QualType OrigT = SemaRef.InstantiateType(D->getOriginalType(), TemplateArgs,
NumTemplateArgs, D->getLocation(),

View File

@ -61,3 +61,14 @@ void test_constructors() {
Constructors<int> ci1(17);
Constructors<int> ci2 = ci1;
}
template<typename T>
struct ConvertsTo {
operator T();
};
void test_converts_to(ConvertsTo<int> ci, ConvertsTo<int *> cip) {
int i = ci;
int *ip = cip;
}