Don't generate any code for an explicit call to a trivial destructor. 

Now that parsing, semantic analysis, and (I think) code generation of
pseudo-destructor expressions and explicit destructor calls works,
update the example-dynarray.cpp test to destroy the objects it
allocates and update the test to actually compile + link.
The code seems correct, but the Clang-compiled version dies with a
malloc error. Time to debug!



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81025 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 7655f47..4f0d9a0 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -178,6 +178,11 @@
   assert(MD->isInstance() && 
          "Trying to emit a member call expr on a static method!");
 
+  // A call to a trivial destructor requires no code generation.
+  if (const CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(MD))
+    if (Destructor->isTrivial())
+      return RValue::get(0);
+  
   const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
   
   CallArgList Args;
@@ -218,6 +223,9 @@
   llvm::Value *Callee;
   if (MD->isVirtual() && !ME->hasQualifier())
     Callee = BuildVirtualCall(MD, This, Ty);
+  else if (const CXXDestructorDecl *Destructor 
+             = dyn_cast<CXXDestructorDecl>(MD))
+    Callee = CGM.GetAddrOfFunction(GlobalDecl(Destructor, Dtor_Complete), Ty);
   else
     Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty);
   
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 802df06..cde6e89 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -812,7 +812,7 @@
   // If there was no specific requested type, just convert it now.
   if (!Ty)
     Ty = getTypes().ConvertType(GD.getDecl()->getType());
-  return GetOrCreateLLVMFunction(getMangledName(GD.getDecl()), Ty, GD);
+  return GetOrCreateLLVMFunction(getMangledName(GD), Ty, GD);
 }
 
 /// CreateRuntimeFunction - Create a new runtime function with the specified
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index e5a4c6f..f8c59f4 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -2634,7 +2634,7 @@
 }
 
 void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,
-                                            CXXDestructorDecl *Destructor) {
+                                    CXXDestructorDecl *Destructor) {
   assert((Destructor->isImplicit() && !Destructor->isUsed()) &&
          "DefineImplicitDestructor - call it for implicit default dtor");
   
diff --git a/test/SemaTemplate/example-dynarray.cpp b/test/SemaTemplate/example-dynarray.cpp
index 7dcc508..0b8d605 100644
--- a/test/SemaTemplate/example-dynarray.cpp
+++ b/test/SemaTemplate/example-dynarray.cpp
@@ -1,4 +1,4 @@
-// RUN: clang-cc -fsyntax-only -verify %s
+// RUN: clang %s -o %t
 #include <stddef.h>
 #include <stdlib.h>
 #include <assert.h>
@@ -24,6 +24,9 @@
   }
   
   ~dynarray() {
+    for (unsigned I = 0, N = size(); I != N; ++I)
+      Start[I].~T();
+    
     free(Start);
   }
 
@@ -33,7 +36,9 @@
     for (unsigned I = 0, N = other.size(); I != N; ++I)
       new (NewStart + I) T(other[I]);
 
-    // FIXME: destroy everything in Start
+    for (unsigned I = 0, N = size(); I != N; ++I)
+      Start[I].~T();
+    
     free(Start);
     Start = NewStart;
     Last = End = NewStart + other.size();
@@ -46,8 +51,8 @@
   void push_back(const T& value);
   
   void pop_back() {
-    // FIXME: destruct old value
     --Last;
+    Last->~T();
   }
 
   T& operator[](unsigned Idx) {
@@ -99,7 +104,8 @@
     for (unsigned I = 0; I != Size; ++I)
       new (NewStart + I) T(Start[I]);
     
-    // FIXME: destruct old values
+    for (unsigned I = 0, N = size(); I != N; ++I)
+      Start[I].~T();
     free(Start);
     
     Start = NewStart;
diff --git a/www/cxx_status.html b/www/cxx_status.html
index 07d8a58..8193787 100644
--- a/www/cxx_status.html
+++ b/www/cxx_status.html
@@ -574,9 +574,9 @@
 <tr>
   <td>&nbsp;&nbsp;&nbsp;&nbsp;5.2.4 [expr.pseudo]</td>
   <td class="complete"></td>
-  <td class="medium"></td>
-  <td class="medium"></td>
-  <td></td>
+  <td class="complete"></td>
+  <td class="complete"></td>
+  <td class="complete"></td>
   <td></td>
 </tr>
 <tr>