]> granicus.if.org Git - clang/commitdiff
Patch toward synthesizing non-trivial destructors. WIP
authorFariborz Jahanian <fjahanian@apple.com>
Sun, 16 Aug 2009 19:36:17 +0000 (19:36 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Sun, 16 Aug 2009 19:36:17 +0000 (19:36 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@79199 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CodeGenModule.cpp
lib/CodeGen/CodeGenModule.h

index 70aee8f2c3e50e445a40e2028cb1c3015381a856..a92e6d9251901fed805d84b910be8d7caeb1747c 100644 (file)
@@ -657,6 +657,8 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(const char *MangledName,
       else if (!ClassDecl->hasUserDeclaredConstructor())
         DeferredDeclsToEmit.push_back(D);
     }
+    else if (isa<CXXDestructorDecl>(FD)) 
+       DeferredDestructorToEmit(D);
     else if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))
            if (MD->isCopyAssignment())
              DeferredCopyAssignmentToEmit(D);
@@ -766,6 +768,42 @@ void CodeGenModule::DeferredCopyAssignmentToEmit(GlobalDecl CopyAssignDecl) {
   DeferredDeclsToEmit.push_back(CopyAssignDecl);  
 }
 
+void CodeGenModule::DeferredDestructorToEmit(GlobalDecl DtorDecl) {
+  const CXXDestructorDecl *DD = cast<CXXDestructorDecl>(DtorDecl.getDecl());
+  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(DD->getDeclContext());
+  if (ClassDecl->hasTrivialDestructor() ||
+      ClassDecl->hasUserDeclaredDestructor())
+    return;
+
+  for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
+       Base != ClassDecl->bases_end(); ++Base) {
+    CXXRecordDecl *BaseClassDecl
+      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+    if (const CXXDestructorDecl *BaseDtor = 
+          BaseClassDecl->getDestructor(Context))
+      GetAddrOfCXXDestructor(BaseDtor, Dtor_Complete);
+  }
+  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+       FieldEnd = ClassDecl->field_end();
+       Field != FieldEnd; ++Field) {
+    QualType FieldType = Context.getCanonicalType((*Field)->getType());
+    if (const ArrayType *Array = Context.getAsArrayType(FieldType))
+      FieldType = Array->getElementType();
+    if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
+      if ((*Field)->isAnonymousStructOrUnion())
+        continue;
+      CXXRecordDecl *FieldClassDecl
+        = cast<CXXRecordDecl>(FieldClassType->getDecl());
+      if (const CXXDestructorDecl *FieldDtor = 
+            FieldClassDecl->getDestructor(Context))
+        GetAddrOfCXXDestructor(FieldDtor, Dtor_Complete);
+    }
+  }
+  DeferredDeclsToEmit.push_back(DtorDecl);
+}
+
+
 /// GetAddrOfFunction - Return the address of the given function.  If Ty is
 /// non-null, then this function will use the specified type if it has to
 /// create it (this occurs when we see a definition of the function).
index 8f69df51a51b9829e3edbdbe9517f49e1af46cc4..cb3f0ba6873657d4429874709a9d6e770f1065c9 100644 (file)
@@ -399,6 +399,7 @@ private:
                                         const VarDecl *D);
   void DeferredCopyConstructorToEmit(GlobalDecl D);
   void DeferredCopyAssignmentToEmit(GlobalDecl D);
+  void DeferredDestructorToEmit(GlobalDecl D);
   
   /// SetCommonAttributes - Set attributes which are common to any
   /// form of a global definition (alias, Objective-C method,