diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-03-25 00:34:44 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-03-25 00:34:44 +0000 |
commit | bb969ed4193e2eadabfaa0dfd0b94312b6146349 (patch) | |
tree | fa9763dce185b77fd0c2441d2fa4d853b2182175 | |
parent | 90e4143ac2ce23ccfcf8c6d68e951f813f6fb31f (diff) |
Template instantiation for conversion functions
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67664 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 31 | ||||
-rw-r--r-- | test/SemaTemplate/instantiate-method.cpp | 11 |
2 files changed, 42 insertions, 0 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 4738dfbd8e..97fd2ed5f4 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -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(), diff --git a/test/SemaTemplate/instantiate-method.cpp b/test/SemaTemplate/instantiate-method.cpp index 3a52c62d69..daea7465dc 100644 --- a/test/SemaTemplate/instantiate-method.cpp +++ b/test/SemaTemplate/instantiate-method.cpp @@ -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; +} |