]> granicus.if.org Git - clang/commitdiff
Refactor instantiation of destructors to use the common CXXMethodDecl
authorDouglas Gregor <dgregor@apple.com>
Fri, 21 Aug 2009 22:43:28 +0000 (22:43 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 21 Aug 2009 22:43:28 +0000 (22:43 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@79682 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplateInstantiateDecl.cpp
test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1.cpp

index 9e05b3231e67b9dc7d0e7d0cec4185416fb7d2a4..ff97631e72a6301767ddcc2087382c8cdd68229b 100644 (file)
@@ -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) {
index 0321a7cfa35d9c232fae84f88e5fad09480f2efb..bd9a06de312b09130f88a915446f34c9c5f07fe0 100644 (file)
@@ -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