diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CGDeclCXX.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CGDeclCXX.cpp | 80 |
1 files changed, 45 insertions, 35 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGDeclCXX.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGDeclCXX.cpp index 9ffcff2..7bdb9eb 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CGDeclCXX.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CGDeclCXX.cpp @@ -96,13 +96,14 @@ static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D, CXXDestructorDecl *dtor = record->getDestructor(); function = CGM.GetAddrOfCXXDestructor(dtor, Dtor_Complete); - argument = addr; + argument = llvm::ConstantExpr::getBitCast( + addr, CGF.getTypes().ConvertType(type)->getPointerTo()); // Otherwise, the standard logic requires a helper function. } else { - function = CodeGenFunction(CGM).generateDestroyHelper(addr, type, - CGF.getDestroyer(dtorKind), - CGF.needsEHCleanup(dtorKind)); + function = CodeGenFunction(CGM) + .generateDestroyHelper(addr, type, CGF.getDestroyer(dtorKind), + CGF.needsEHCleanup(dtorKind), &D); argument = llvm::Constant::getNullValue(CGF.Int8PtrTy); } @@ -149,7 +150,7 @@ void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D, assert(PerformInit && "cannot have constant initializer which needs " "destruction for reference"); unsigned Alignment = getContext().getDeclAlign(&D).getQuantity(); - RValue RV = EmitReferenceBindingToExpr(Init, &D); + RValue RV = EmitReferenceBindingToExpr(Init); EmitStoreOfScalar(RV.getScalarVal(), DeclPtr, false, Alignment, T); } @@ -161,23 +162,24 @@ CreateGlobalInitOrDestructFunction(CodeGenModule &CGM, /// Create a stub function, suitable for being passed to atexit, /// which passes the given address to the given destructor function. -static llvm::Constant *createAtExitStub(CodeGenModule &CGM, +static llvm::Constant *createAtExitStub(CodeGenModule &CGM, const VarDecl &VD, llvm::Constant *dtor, llvm::Constant *addr) { // Get the destructor function type, void(*)(void). llvm::FunctionType *ty = llvm::FunctionType::get(CGM.VoidTy, false); + SmallString<256> FnName; + { + llvm::raw_svector_ostream Out(FnName); + CGM.getCXXABI().getMangleContext().mangleDynamicAtExitDestructor(&VD, Out); + } llvm::Function *fn = - CreateGlobalInitOrDestructFunction(CGM, ty, - Twine("__dtor_", addr->getName())); + CreateGlobalInitOrDestructFunction(CGM, ty, FnName.str()); CodeGenFunction CGF(CGM); - // Initialize debug info if needed. - CGF.maybeInitializeDebugInfo(); - - CGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, fn, - CGM.getTypes().arrangeNullaryFunction(), - FunctionArgList(), SourceLocation()); + CGF.StartFunction(&VD, CGM.getContext().VoidTy, fn, + CGM.getTypes().arrangeNullaryFunction(), FunctionArgList(), + SourceLocation()); llvm::CallInst *call = CGF.Builder.CreateCall(dtor, addr); @@ -192,10 +194,11 @@ static llvm::Constant *createAtExitStub(CodeGenModule &CGM, } /// Register a global destructor using the C atexit runtime function. -void CodeGenFunction::registerGlobalDtorWithAtExit(llvm::Constant *dtor, +void CodeGenFunction::registerGlobalDtorWithAtExit(const VarDecl &VD, + llvm::Constant *dtor, llvm::Constant *addr) { // Create a function which calls the destructor. - llvm::Constant *dtorStub = createAtExitStub(CGM, dtor, addr); + llvm::Constant *dtorStub = createAtExitStub(CGM, VD, dtor, addr); // extern "C" int atexit(void (*f)(void)); llvm::FunctionType *atexitTy = @@ -257,10 +260,15 @@ CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D, llvm::GlobalVariable *Addr, bool PerformInit) { llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false); + SmallString<256> FnName; + { + llvm::raw_svector_ostream Out(FnName); + getCXXABI().getMangleContext().mangleDynamicInitializer(D, Out); + } // Create a variable initialization function. llvm::Function *Fn = - CreateGlobalInitOrDestructFunction(*this, FTy, "__cxx_global_var_init"); + CreateGlobalInitOrDestructFunction(*this, FTy, FnName.str()); CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D, Addr, PerformInit); @@ -278,6 +286,20 @@ CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D, OrderGlobalInits Key(order, PrioritizedCXXGlobalInits.size()); PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn)); DelayedCXXInitPosition.erase(D); + } else if (D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization && + D->getTemplateSpecializationKind() != TSK_Undeclared) { + // C++ [basic.start.init]p2: + // Definitions of explicitly specialized class template static data + // members have ordered initialization. Other class template static data + // members (i.e., implicitly or explicitly instantiated specializations) + // have unordered initialization. + // + // As a consequence, we can put them into their own llvm.global_ctors entry. + // This should allow GlobalOpt to fire more often, and allow us to implement + // the Microsoft C++ ABI, which uses COMDAT elimination to avoid double + // initializaiton. + AddGlobalCtor(Fn); + DelayedCXXInitPosition.erase(D); } else { llvm::DenseMap<const Decl *, unsigned>::iterator I = DelayedCXXInitPosition.find(D); @@ -386,8 +408,8 @@ void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, llvm::GlobalVariable *Addr, bool PerformInit) { // Check if we need to emit debug info for variable initializer. - if (!D->hasAttr<NoDebugAttr>()) - maybeInitializeDebugInfo(); + if (D->hasAttr<NoDebugAttr>()) + DebugInfo = NULL; // disable debug info indefinitely for this function StartFunction(GlobalDecl(D), getContext().VoidTy, Fn, getTypes().arrangeNullaryFunction(), @@ -410,9 +432,6 @@ void CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef<llvm::Constant *> Decls, llvm::GlobalVariable *Guard) { - // Initialize debug info if needed. - maybeInitializeDebugInfo(); - StartFunction(GlobalDecl(), getContext().VoidTy, Fn, getTypes().arrangeNullaryFunction(), FunctionArgList(), SourceLocation()); @@ -459,9 +478,6 @@ CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn, void CodeGenFunction::GenerateCXXGlobalDtorsFunc(llvm::Function *Fn, const std::vector<std::pair<llvm::WeakVH, llvm::Constant*> > &DtorsAndObjects) { - // Initialize debug info if needed. - maybeInitializeDebugInfo(); - StartFunction(GlobalDecl(), getContext().VoidTy, Fn, getTypes().arrangeNullaryFunction(), FunctionArgList(), SourceLocation()); @@ -481,11 +497,9 @@ void CodeGenFunction::GenerateCXXGlobalDtorsFunc(llvm::Function *Fn, /// generateDestroyHelper - Generates a helper function which, when /// invoked, destroys the given object. -llvm::Function * -CodeGenFunction::generateDestroyHelper(llvm::Constant *addr, - QualType type, - Destroyer *destroyer, - bool useEHCleanupForArray) { +llvm::Function *CodeGenFunction::generateDestroyHelper( + llvm::Constant *addr, QualType type, Destroyer *destroyer, + bool useEHCleanupForArray, const VarDecl *VD) { FunctionArgList args; ImplicitParamDecl dst(0, SourceLocation(), 0, getContext().VoidPtrTy); args.push_back(&dst); @@ -498,11 +512,7 @@ CodeGenFunction::generateDestroyHelper(llvm::Constant *addr, llvm::Function *fn = CreateGlobalInitOrDestructFunction(CGM, FTy, "__cxx_global_array_dtor"); - // Initialize debug info if needed. - maybeInitializeDebugInfo(); - - StartFunction(GlobalDecl(), getContext().VoidTy, fn, FI, args, - SourceLocation()); + StartFunction(VD, getContext().VoidTy, fn, FI, args, SourceLocation()); emitDestroy(addr, type, destroyer, useEHCleanupForArray); |