]> granicus.if.org Git - clang/commitdiff
ir-gen patch to destruct array members. WIP.
authorFariborz Jahanian <fjahanian@apple.com>
Thu, 20 Aug 2009 20:54:15 +0000 (20:54 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Thu, 20 Aug 2009 20:54:15 +0000 (20:54 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@79565 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGCXX.cpp
lib/CodeGen/CodeGenFunction.h

index 2ec7c473414cd6db842e1a48d79daa13a4d40d70..72aa9fc090e6aac0c42cabcf78dbaf10f6f0f555 100644 (file)
@@ -412,6 +412,12 @@ CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
   EmitBlock(AfterFor, true);
 }
 
+void
+CodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
+                                           const ArrayType *Array,
+                                           llvm::Value *This) {
+}
+
 void
 CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, 
                                         CXXCtorType Type, 
@@ -1314,12 +1320,8 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD) {
       QualType FieldType = getContext().getCanonicalType((*Field)->getType());
       const ConstantArrayType *Array = 
         getContext().getAsConstantArrayType(FieldType);
-      if (Array) {
-        FieldType = Array->getElementType();
-        while (const ConstantArrayType *AT = 
-                getContext().getAsConstantArrayType(FieldType))
-          FieldType = AT->getElementType();
-      }
+      if (Array)
+        FieldType = getContext().getBaseElementType(FieldType);
       if (!FieldType->getAs<RecordType>() || Field->isAnonymousStructOrUnion())
         continue;
       const RecordType *ClassRec = FieldType->getAs<RecordType>();
@@ -1374,16 +1376,27 @@ void CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD) {
     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 ConstantArrayType *Array = 
+        getContext().getAsConstantArrayType(FieldType);
+      if (Array)
+        FieldType = getContext().getBaseElementType(FieldType);
       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());
+      if (Array) {
+        const llvm::Type *BasePtr = ConvertType(FieldType);
+        BasePtr = llvm::PointerType::getUnqual(BasePtr);
+        llvm::Value *BaseAddrPtr = 
+          Builder.CreateBitCast(LHS.getAddress(), BasePtr);
+        EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(getContext()), 
+                                  Array, BaseAddrPtr);
+      }
+      else
+        EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()),
+                              Dtor_Complete, LHS.getAddress());
     } else {
       const RecordType *RT =
         DD->getAnyBaseClassToDestroy(BaseOrMember)->getAs<RecordType>();
@@ -1407,7 +1420,8 @@ void CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD) {
        FieldEnd = ClassDecl->field_end();
        Field != FieldEnd; ++Field) {
     QualType FieldType = getContext().getCanonicalType((*Field)->getType());
-    // FIXME. Assert on arrays for now.
+    if (getContext().getAsConstantArrayType(FieldType))
+      FieldType = getContext().getBaseElementType(FieldType);
     if (const RecordType *RT = FieldType->getAs<RecordType>()) {
       CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
       if (FieldClassDecl->hasTrivialDestructor())
@@ -1419,12 +1433,25 @@ void CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD) {
     for (int i = DestructedFields.size() -1; i >= 0; --i) {
       FieldDecl *Field = DestructedFields[i];
       QualType FieldType = Field->getType();
+      const ConstantArrayType *Array = 
+        getContext().getAsConstantArrayType(FieldType);
+        if (Array)
+          FieldType = getContext().getBaseElementType(FieldType);
       const RecordType *RT = FieldType->getAs<RecordType>();
       CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
       llvm::Value *LoadOfThis = LoadCXXThis();
       LValue LHS = EmitLValueForField(LoadOfThis, Field, false, 0);
-      EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()),
-                            Dtor_Complete, LHS.getAddress());
+      if (Array) {
+        const llvm::Type *BasePtr = ConvertType(FieldType);
+        BasePtr = llvm::PointerType::getUnqual(BasePtr);
+        llvm::Value *BaseAddrPtr = 
+        Builder.CreateBitCast(LHS.getAddress(), BasePtr);
+        EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(getContext()), 
+                                  Array, BaseAddrPtr);
+      }
+      else
+        EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()),
+                              Dtor_Complete, LHS.getAddress());
     }
   
   llvm::SmallVector<CXXRecordDecl*, 4> DestructedBases;
index b4cbc965d54d0757ad93d1f4c95507333d6e21df..71614c451ced40157e71844af46e5d497607ffcc 100644 (file)
@@ -587,6 +587,10 @@ public:
                                   const ArrayType *Array,
                                   llvm::Value *This);
 
+  void EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
+                                 const ArrayType *Array,
+                                 llvm::Value *This);
+  
   void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type,
                              llvm::Value *This);