]> granicus.if.org Git - clang/commitdiff
Block Code Gen. API. Call destructor on descriptior
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 8 Jun 2010 20:57:22 +0000 (20:57 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 8 Jun 2010 20:57:22 +0000 (20:57 +0000)
entry previously constructed via copy constructor.

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

lib/CodeGen/CGBlocks.cpp
test/CodeGenCXX/copy-in-cplus-object.cpp

index b2d7f2e81d4cbf1b51c3184ff12bc6a42a02567c..f07b7bbbda9712bed6889edeca561e63fecdc6bd 100644 (file)
@@ -361,8 +361,36 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
           Builder.CreateStore(Loc, Addr);
           continue;
         } else {
-            if (BDRE->getCopyConstructorExpr())
-              E = BDRE->getCopyConstructorExpr();
+          if (BDRE->getCopyConstructorExpr()) {
+            E = BDRE->getCopyConstructorExpr();
+            // Code to destruct copy-constructed descriptor element for
+            // copied-in class object.
+            // TODO: Refactor this into common code with mostly similar
+            // CodeGenFunction::EmitLocalBlockVarDecl
+            QualType DtorTy = E->getType();
+            if (const RecordType *RT = DtorTy->getAs<RecordType>())
+              if (CXXRecordDecl *ClassDecl = 
+                    dyn_cast<CXXRecordDecl>(RT->getDecl())) {
+                if (!ClassDecl->hasTrivialDestructor()) {
+                  const CXXDestructorDecl *D = 
+                    ClassDecl->getDestructor(getContext());
+                  assert(D && "BuildBlockLiteralTmp - destructor is nul");
+                  {
+                    // Normal destruction. 
+                    DelayedCleanupBlock Scope(*this);
+                    EmitCXXDestructorCall(D, Dtor_Complete, 
+                                          /*ForVirtualBase=*/false, Addr);
+                    // Make sure to jump to the exit block.
+                    EmitBranch(Scope.getCleanupExitBlock());
+                  }
+                  if (Exceptions) {
+                    EHCleanupBlock Cleanup(*this);
+                    EmitCXXDestructorCall(D, Dtor_Complete, 
+                                          /*ForVirtualBase=*/false, Addr);
+                  }
+                }
+              }
+          }
             else {
               E = new (getContext()) DeclRefExpr(const_cast<ValueDecl*>(VD),
                                             VD->getType().getNonReferenceType(),
index cac6155f5cf1b7967ebab4a49a122ffa64e1f4a2..bdfca5e4ee0a21ea0bf47f68f0643063aaa8823e 100644 (file)
@@ -9,6 +9,7 @@ struct TestObject
 {
        TestObject(const TestObject& inObj, int def = 100,  const S &Silly = "silly");
        TestObject();
+       ~TestObject();
        TestObject& operator=(const TestObject& inObj);
        int version() const;
 
@@ -23,4 +24,5 @@ void testRoutine() {
 // CHECK: call void @_ZN1SC1EPKc
 // CHECK: call void @_ZN10TestObjectC1ERKS_iRK1S
 // CHECK: call void @_ZN1SD1Ev
-
+// CHECK: call void @_ZN10TestObjectD1Ev
+// CHECK: call void @_ZN10TestObjectD1Ev