diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-03-24 16:43:20 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-03-24 16:43:20 +0000 |
commit | 615c5d4674355ba830b9978f462ca7a8c5d15f85 (patch) | |
tree | 83a3de169a3431836c81d07aaf20b32233bdf4d0 /lib/Sema/SemaTemplateInstantiateDecl.cpp | |
parent | 37e217cf4d4ca7923833552c62f023001e74632f (diff) |
Template instantiation for constructors
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67623 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 685b9cfd5b..4738dfbd8e 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -44,6 +44,7 @@ namespace { Decl *VisitStaticAssertDecl(StaticAssertDecl *D); Decl *VisitEnumDecl(EnumDecl *D); Decl *VisitCXXMethodDecl(CXXMethodDecl *D); + Decl *VisitCXXConstructorDecl(CXXConstructorDecl *D); Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D); Decl *VisitParmVarDecl(ParmVarDecl *D); Decl *VisitOriginalParmVarDecl(OriginalParmVarDecl *D); @@ -247,6 +248,50 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D) { return Method; } +Decl *TemplateDeclInstantiator::VisitCXXConstructorDecl(CXXConstructorDecl *D) { + llvm::SmallVector<ParmVarDecl *, 16> Params; + QualType T = InstantiateFunctionType(D, Params); + if (T.isNull()) + return 0; + + // Build the instantiated method declaration. + CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner); + QualType ClassTy = SemaRef.Context.getTypeDeclType(Record); + DeclarationName Name + = SemaRef.Context.DeclarationNames.getCXXConstructorName(ClassTy); + CXXConstructorDecl *Constructor + = CXXConstructorDecl::Create(SemaRef.Context, Record, D->getLocation(), + Name, T, D->isExplicit(), D->isInline(), + false); + + // Attach the parameters + for (unsigned P = 0; P < Params.size(); ++P) + Params[P]->setOwningFunction(Constructor); + Constructor->setParams(SemaRef.Context, &Params[0], Params.size()); + + if (InitMethodInstantiation(Constructor, D)) + Constructor->setInvalidDecl(); + + NamedDecl *PrevDecl + = SemaRef.LookupQualifiedName(Owner, Name, Sema::LookupOrdinaryName, true); + + // In C++, the previous declaration we find might be a tag type + // (class or enum). In this case, the new declaration will hide the + // tag type. Note that this does does not apply if we're declaring a + // typedef (C++ [dcl.typedef]p4). + if (PrevDecl && PrevDecl->getIdentifierNamespace() == Decl::IDNS_Tag) + PrevDecl = 0; + bool Redeclaration = false; + bool OverloadableAttrRequired = false; + if (SemaRef.CheckFunctionDeclaration(Constructor, PrevDecl, Redeclaration, + /*FIXME:*/OverloadableAttrRequired)) + Constructor->setInvalidDecl(); + + if (!Constructor->isInvalidDecl()) + Owner->addDecl(Constructor); + return Constructor; +} + Decl *TemplateDeclInstantiator::VisitCXXDestructorDecl(CXXDestructorDecl *D) { llvm::SmallVector<ParmVarDecl *, 16> Params; QualType T = InstantiateFunctionType(D, Params); |