Add support for generating (very basic) C++ destructors. These aren't called by anything yet.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69343 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp
index e42b6fd..3a7fe9c 100644
--- a/lib/CodeGen/Mangle.cpp
+++ b/lib/CodeGen/Mangle.cpp
@@ -29,16 +29,19 @@
     ASTContext &Context;
     llvm::raw_ostream &Out;
 
-    const CXXConstructorDecl *Ctor;
+    const CXXMethodDecl *Structor;
+    unsigned StructorType;
     CXXCtorType CtorType;
     
   public:
     CXXNameMangler(ASTContext &C, llvm::raw_ostream &os)
-      : Context(C), Out(os), Ctor(0), CtorType(Ctor_Complete) { }
+      : Context(C), Out(os), Structor(0), StructorType(0) { }
 
     bool mangle(const NamedDecl *D);
     void mangleGuardVariable(const VarDecl *D);
+    
     void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type);
+    void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type);
 
   private:
     bool mangleFunctionDecl(const FunctionDecl *FD);
@@ -63,6 +66,7 @@
     void mangleType(const ObjCInterfaceType *T);
     void mangleExpression(Expr *E);
     void mangleCXXCtorType(CXXCtorType T);
+    void mangleCXXDtorType(CXXDtorType T);
   };
 }
 
@@ -132,9 +136,18 @@
 
 void CXXNameMangler::mangleCXXCtor(const CXXConstructorDecl *D, 
                                    CXXCtorType Type) {
-  assert(!Ctor && "Ctor already set!");
-  Ctor = D;
-  CtorType = Type;
+  assert(!Structor && "Structor already set!");
+  Structor = D;
+  StructorType = Type;
+  
+  mangle(D);
+}
+
+void CXXNameMangler::mangleCXXDtor(const CXXDestructorDecl *D, 
+                                   CXXDtorType Type) {
+  assert(!Structor && "Structor already set!");
+  Structor = D;
+  StructorType = Type;
   
   mangle(D);
 }
@@ -198,10 +211,10 @@
     break;
 
   case DeclarationName::CXXConstructorName:
-    if (ND == Ctor)
+    if (ND == Structor)
       // If the named decl is the C++ constructor we're mangling, use the 
       // type we were given.
-      mangleCXXCtorType(CtorType);
+      mangleCXXCtorType(static_cast<CXXCtorType>(StructorType));
     else
       // Otherwise, use the complete constructor name. This is relevant if a
       // class with a constructor is declared within a constructor.
@@ -209,13 +222,14 @@
     break;
 
   case DeclarationName::CXXDestructorName:
-    // <ctor-dtor-name> ::= D0  # deleting destructor
-    //                  ::= D1  # complete object destructor
-    //                  ::= D2  # base object destructor
-    //
-    // FIXME: We don't even have all of these destructors in the AST
-    // yet.
-    Out << "D0";
+    if (ND == Structor)
+      // If the named decl is the C++ destructor we're mangling, use the 
+      // type we were given.
+      mangleCXXDtorType(static_cast<CXXDtorType>(StructorType));
+    else
+      // Otherwise, use the complete destructor name. This is relevant if a
+      // class with a destructor is declared within a destructor.
+      mangleCXXDtorType(Dtor_Complete);
     break;
 
   case DeclarationName::CXXConversionFunctionName:
@@ -612,6 +626,24 @@
   }
 }
 
+void CXXNameMangler::mangleCXXDtorType(CXXDtorType T) {
+  // <ctor-dtor-name> ::= D0  # deleting destructor
+  //                  ::= D1  # complete object destructor
+  //                  ::= D2  # base object destructor
+  //
+  switch (T) {
+  case Dtor_Deleting:
+    Out << "D0";
+    break;
+  case Dtor_Complete:
+    Out << "D1";
+    break;
+  case Dtor_Base:
+    Out << "D2";
+    break;
+  }
+}
+
 namespace clang {
   /// \brief Mangles the name of the declaration D and emits that name
   /// to the given output stream.
@@ -648,5 +680,15 @@
     
     os.flush();
   }
+  
+  void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
+                     ASTContext &Context, llvm::raw_ostream &os) {
+    CXXNameMangler Mangler(Context, os);
+    Mangler.mangleCXXDtor(D, Type);
+    
+    os.flush();
+  }
+  
+  
 }