diff options
| author | Douglas Gregor <dgregor@apple.com> | 2009-08-21 22:43:28 +0000 | 
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2009-08-21 22:43:28 +0000 | 
| commit | e839486de9966bfc74079777a0318556afbe3cd7 (patch) | |
| tree | 8d0b059f3384df6d4ec94f8b78bd758fb12cdd5f | |
| parent | 8adc9734832677dc5af746f3033ab0b1c0e41aa9 (diff) | |
| download | bcm5719-llvm-e839486de9966bfc74079777a0318556afbe3cd7.tar.gz bcm5719-llvm-e839486de9966bfc74079777a0318556afbe3cd7.zip  | |
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.
llvm-svn: 79682
| -rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 47 | ||||
| -rw-r--r-- | clang/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1.cpp | 11 | 
2 files changed, 24 insertions, 34 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 9e05b3231e6..ff97631e72a 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -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) { diff --git a/clang/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1.cpp b/clang/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1.cpp index 0321a7cfa35..bd9a06de312 100644 --- a/clang/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1.cpp +++ b/clang/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1.cpp @@ -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; }
\ No newline at end of file  | 

