[cfe-commits] r77608 - in /cfe/trunk: include/clang/AST/DeclCXX.h lib/CodeGen/CGCXX.cpp lib/CodeGen/CodeGenFunction.cpp lib/CodeGen/CodeGenFunction.h

Fariborz Jahanian fjahanian at apple.com
Thu Jul 30 10:49:11 PDT 2009


Author: fjahanian
Date: Thu Jul 30 12:49:11 2009
New Revision: 77608

URL: http://llvm.org/viewvc/llvm-project?rev=77608&view=rev
Log:
Patch for future ir-gen for destructor calls.

Modified:
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/lib/CodeGen/CGCXX.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=77608&r1=77607&r2=77608&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Thu Jul 30 12:49:11 2009
@@ -1096,7 +1096,7 @@
     return 0;
   }
   /// getMemberToDestroy - Get the member for the given object.
-  FieldDecl *getMemberToDestroy(uintptr_t Member) { 
+  FieldDecl *getMemberToDestroy(uintptr_t Member) const { 
     if (isMemberToDestroy(Member))
       return reinterpret_cast<FieldDecl *>(Member); 
     return 0;

Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=77608&r1=77607&r2=77608&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Thu Jul 30 12:49:11 2009
@@ -489,7 +489,7 @@
 /// base classes and non-static data members belonging to this constructor.
 void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD) {
   const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
-  assert(ClassDecl->vbases_begin() == ClassDecl->vbases_end()
+  assert(!ClassDecl->isPolymorphic()
          && "FIXME. virtual base initialization unsupported");
   
   for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(),
@@ -538,3 +538,43 @@
     }
   }
 }
+
+/// EmitDtorEpilogue - Emit all code that comes at the end of class's
+/// destructor. This is to call destructors on members and base classes 
+/// in reverse order of their construction.
+void CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD) {
+  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(DD->getDeclContext());
+  assert(!ClassDecl->isPolymorphic() &&
+         "FIXME. polymorphic destruction not supported");
+  (void)ClassDecl;  // prevent warning.
+  
+  for (CXXDestructorDecl::destr_const_iterator *B = DD->destr_begin(),
+       *E = DD->destr_end(); B != E; ++B) {
+    uintptr_t BaseOrMember = (*B);
+    if (DD->isMemberToDestroy(BaseOrMember)) {
+      FieldDecl *FD = DD->getMemberToDestroy(BaseOrMember);
+      QualType FieldType = getContext().getCanonicalType((FD)->getType());
+      assert(!getContext().getAsArrayType(FieldType) 
+             && "FIXME. Field arrays destruction unsupported");
+      const RecordType *RT = FieldType->getAs<RecordType>();
+      CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
+      if (FieldClassDecl->hasTrivialDestructor())
+        continue;
+      llvm::Value *LoadOfThis = LoadCXXThis();
+      LValue LHS = EmitLValueForField(LoadOfThis, FD, false, 0);
+      EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()),
+                            Dtor_Complete, LHS.getAddress());
+    }
+    else {
+      const RecordType *RT =
+        DD->getAnyBaseClassToDestroy(BaseOrMember)->getAs<RecordType>();
+      CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl());
+      if (BaseClassDecl->hasTrivialDestructor())
+        continue;
+      llvm::Value *V = AddressCXXOfBaseClass(LoadCXXThis(), 
+                                             ClassDecl,BaseClassDecl);
+      EmitCXXDestructorCall(BaseClassDecl->getDestructor(getContext()),
+                            Dtor_Complete, V);
+    }
+  }
+}

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=77608&r1=77607&r2=77608&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Thu Jul 30 12:49:11 2009
@@ -234,6 +234,8 @@
     if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD))
       EmitCtorPrologue(CD);
     EmitStmt(S);
+    if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(FD))
+      EmitDtorEpilogue(DD);
     FinishFunction(S->getRBracLoc());
   }
 

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=77608&r1=77607&r2=77608&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Thu Jul 30 12:49:11 2009
@@ -359,7 +359,12 @@
   void FinishFunction(SourceLocation EndLoc=SourceLocation());
 
   void EmitCtorPrologue(const CXXConstructorDecl *CD);
-
+  
+  /// EmitDtorEpilogue - Emit all code that comes at the end of class's
+  /// destructor. This is to call destructors on members and base classes 
+  /// in reverse order of their construction.
+  void EmitDtorEpilogue(const CXXDestructorDecl *DD);
+  
   /// EmitFunctionProlog - Emit the target specific LLVM code to load the
   /// arguments for the given function. This is also responsible for naming the
   /// LLVM function arguments.





More information about the cfe-commits mailing list