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 | 4044d995c9e549e5ff0c44a8b6f389b41c2b0878 (patch) | |
tree | f94abc6874ab811f011708fe5887d20fa1f3f4fb /clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | |
parent | 9fc30d5c30bff7115f998a79918620fa7ad14e93 (diff) | |
download | bcm5719-llvm-4044d995c9e549e5ff0c44a8b6f389b41c2b0878.tar.gz bcm5719-llvm-4044d995c9e549e5ff0c44a8b6f389b41c2b0878.zip |
Template instantiation for constructors
llvm-svn: 67623
Diffstat (limited to 'clang/lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 685b9cfd5b9..4738dfbd8e7 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/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); |