[cfe-commits] r86701 - in /cfe/trunk: lib/CodeGen/CGCXX.cpp lib/CodeGen/CodeGenFunction.h test/CodeGenCXX/global-array-destruction.cpp

Fariborz Jahanian fjahanian at apple.com
Tue Nov 10 11:24:07 PST 2009


Author: fjahanian
Date: Tue Nov 10 13:24:06 2009
New Revision: 86701

URL: http://llvm.org/viewvc/llvm-project?rev=86701&view=rev
Log:
This patch implements Code gen. for destruction of
global array of objects.


Added:
    cfe/trunk/test/CodeGenCXX/global-array-destruction.cpp
Modified:
    cfe/trunk/lib/CodeGen/CGCXX.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Tue Nov 10 13:24:06 2009
@@ -27,7 +27,7 @@
 using namespace CodeGen;
 
 void
-CodeGenFunction::EmitCXXGlobalDtorRegistration(const CXXDestructorDecl *Dtor,
+CodeGenFunction::EmitCXXGlobalDtorRegistration(llvm::Constant *DtorFn,
                                                llvm::Constant *DeclPtr) {
   const llvm::Type *Int8PtrTy = 
     llvm::Type::getInt8Ty(VMContext)->getPointerTo();
@@ -55,9 +55,6 @@
 
   llvm::Constant *Handle = CGM.CreateRuntimeVariable(Int8PtrTy,
                                                      "__dso_handle");
-
-  llvm::Constant *DtorFn = CGM.GetAddrOfCXXDestructor(Dtor, Dtor_Complete);
-
   llvm::Value *Args[3] = { llvm::ConstantExpr::getBitCast(DtorFn, DtorFnTy),
                            llvm::ConstantExpr::getBitCast(DeclPtr, Int8PtrTy),
                            llvm::ConstantExpr::getBitCast(Handle, Int8PtrTy) };
@@ -82,11 +79,26 @@
     EmitComplexExprIntoAddr(Init, DeclPtr, isVolatile);
   } else {
     EmitAggExpr(Init, DeclPtr, isVolatile);
-
+    const ConstantArrayType *Array = getContext().getAsConstantArrayType(T);
+    if (Array)
+      T = getContext().getBaseElementType(Array);
+    
     if (const RecordType *RT = T->getAs<RecordType>()) {
       CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
-      if (!RD->hasTrivialDestructor())
-        EmitCXXGlobalDtorRegistration(RD->getDestructor(getContext()), DeclPtr);
+      if (!RD->hasTrivialDestructor()) {
+        llvm::Constant *DtorFn;
+        if (Array) {
+          DtorFn = CodeGenFunction(CGM).GenerateCXXAggrDestructorHelper(
+                                                RD->getDestructor(getContext()), 
+                                                Array, DeclPtr);
+          DeclPtr = 
+            llvm::Constant::getNullValue(llvm::Type::getInt8PtrTy(VMContext));
+        }
+        else
+          DtorFn = CGM.GetAddrOfCXXDestructor(RD->getDestructor(getContext()), 
+                                              Dtor_Complete);                                
+        EmitCXXGlobalDtorRegistration(DtorFn, DeclPtr);
+      }
     }
   }
 }
@@ -559,6 +571,50 @@
   EmitBlock(AfterFor, true);
 }
 
+/// EmitCXXAggrDestructorCall - Generates a helper function which when invoked,
+/// calls the default destructor on array elements in reverse order of 
+/// construction.
+llvm::Constant * 
+CodeGenFunction::GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D,
+                                                 const ArrayType *Array,
+                                                 llvm::Value *This) {
+  static int UniqueCount;
+  FunctionArgList Args;
+  ImplicitParamDecl *Dst =
+    ImplicitParamDecl::Create(getContext(), 0,
+                              SourceLocation(), 0,
+                              getContext().getPointerType(getContext().VoidTy));
+  Args.push_back(std::make_pair(Dst, Dst->getType()));
+  
+  llvm::SmallString<16> Name;
+  llvm::raw_svector_ostream(Name) << "__tcf_" << (++UniqueCount);
+  QualType R = getContext().VoidTy;
+  const CGFunctionInfo &FI = CGM.getTypes().getFunctionInfo(R, Args);
+  const llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI, false);
+  llvm::Function *Fn =
+    llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
+                           Name.c_str(),
+                           &CGM.getModule());
+  IdentifierInfo *II
+    = &CGM.getContext().Idents.get(Name.c_str());
+  FunctionDecl *FD = FunctionDecl::Create(getContext(),
+                                          getContext().getTranslationUnitDecl(),
+                                          SourceLocation(), II, R, 0,
+                                          FunctionDecl::Static,
+                                          false, true);
+  StartFunction(FD, R, Fn, Args, SourceLocation());
+  QualType BaseElementTy = getContext().getBaseElementType(Array);
+  const llvm::Type *BasePtr = ConvertType(BaseElementTy);
+  BasePtr = llvm::PointerType::getUnqual(BasePtr);
+  llvm::Value *BaseAddrPtr = Builder.CreateBitCast(This, BasePtr);
+  EmitCXXAggrDestructorCall(D, Array, BaseAddrPtr);
+  FinishFunction();
+  llvm::Type *Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),
+                                              0);
+  llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty);
+  return m;
+}
+
 void
 CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
                                         CXXCtorType Type,

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Nov 10 13:24:06 2009
@@ -646,6 +646,10 @@
                                  const ArrayType *Array,
                                  llvm::Value *This);
 
+  llvm::Constant * GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D,
+                                                const ArrayType *Array,
+                                                llvm::Value *This);
+
   void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type,
                              llvm::Value *This);
 
@@ -994,7 +998,7 @@
 
   /// EmitCXXGlobalDtorRegistration - Emits a call to register the global ptr
   /// with the C++ runtime so that its destructor will be called at exit.
-  void EmitCXXGlobalDtorRegistration(const CXXDestructorDecl *Dtor,
+  void EmitCXXGlobalDtorRegistration(llvm::Constant *DtorFn,
                                      llvm::Constant *DeclPtr);
 
   /// GenerateCXXGlobalInitFunc - Generates code for initializing global

Added: cfe/trunk/test/CodeGenCXX/global-array-destruction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/global-array-destruction.cpp?rev=86701&view=auto

==============================================================================
--- cfe/trunk/test/CodeGenCXX/global-array-destruction.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/global-array-destruction.cpp Tue Nov 10 13:24:06 2009
@@ -0,0 +1,33 @@
+// RUN: clang-cc -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+
+extern "C" int printf(...);
+
+int count;
+
+struct S {
+  S() : iS(++count) { printf("S::S(%d)\n", iS); }
+  ~S() { printf("S::~S(%d)\n", iS); }
+  int iS;
+};
+
+
+S arr[2][1];
+S s1;
+S arr1[3];
+static S sarr[4];
+
+int main () {}
+S arr2[2];
+static S sarr1[4];
+S s2;
+S arr3[3];
+
+// CHECK-LP64: call     ___cxa_atexit
+// CHECK-LP64: call     ___cxa_atexit
+// CHECK-LP64: call     ___cxa_atexit
+// CHECK-LP64: call     ___cxa_atexit
+// CHECK-LP64: call     ___cxa_atexit
+// CHECK-LP64: call     ___cxa_atexit
+// CHECK-LP64: call     ___cxa_atexit
+// CHECK-LP64: call     ___cxa_atexit





More information about the cfe-commits mailing list