From 9f26a8d4a268f80bd9012207105f34613fb1b9f8 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Fri, 11 Apr 2014 23:45:01 +0000 Subject: [PATCH] Follow-up to r205999: Emit an artificial location (valid scope, line 0) for CXXGlobalInit/Dtor helper functions. This makes _GLOBAL__I_a regain its DW_AT_high/low_pc in the debug info. Thanks to echristo for catching this! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@206088 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGDeclCXX.cpp | 97 +++++++++++++++++------------- test/CodeGenCXX/globalinit-loc.cpp | 3 +- 2 files changed, 56 insertions(+), 44 deletions(-) diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp index 640e9fa92d..7a0ef8948e 100644 --- a/lib/CodeGen/CGDeclCXX.cpp +++ b/lib/CodeGen/CGDeclCXX.cpp @@ -431,43 +431,49 @@ void CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef Decls, llvm::GlobalVariable *Guard) { - StartFunction(GlobalDecl(), getContext().VoidTy, Fn, - getTypes().arrangeNullaryFunction(), FunctionArgList()); - - llvm::BasicBlock *ExitBlock = 0; - if (Guard) { - // If we have a guard variable, check whether we've already performed these - // initializations. This happens for TLS initialization functions. - llvm::Value *GuardVal = Builder.CreateLoad(Guard); - llvm::Value *Uninit = Builder.CreateIsNull(GuardVal, "guard.uninitialized"); - // Mark as initialized before initializing anything else. If the - // initializers use previously-initialized thread_local vars, that's - // probably supposed to be OK, but the standard doesn't say. - Builder.CreateStore(llvm::ConstantInt::get(GuardVal->getType(), 1), Guard); - llvm::BasicBlock *InitBlock = createBasicBlock("init"); - ExitBlock = createBasicBlock("exit"); - Builder.CreateCondBr(Uninit, InitBlock, ExitBlock); - EmitBlock(InitBlock); - } + { + ArtificialLocation AL(*this, Builder); + StartFunction(GlobalDecl(), getContext().VoidTy, Fn, + getTypes().arrangeNullaryFunction(), FunctionArgList()); + // Emit an artificial location for this function. + AL.Emit(); + + llvm::BasicBlock *ExitBlock = 0; + if (Guard) { + // If we have a guard variable, check whether we've already performed + // these initializations. This happens for TLS initialization functions. + llvm::Value *GuardVal = Builder.CreateLoad(Guard); + llvm::Value *Uninit = Builder.CreateIsNull(GuardVal, + "guard.uninitialized"); + // Mark as initialized before initializing anything else. If the + // initializers use previously-initialized thread_local vars, that's + // probably supposed to be OK, but the standard doesn't say. + Builder.CreateStore(llvm::ConstantInt::get(GuardVal->getType(),1), Guard); + llvm::BasicBlock *InitBlock = createBasicBlock("init"); + ExitBlock = createBasicBlock("exit"); + Builder.CreateCondBr(Uninit, InitBlock, ExitBlock); + EmitBlock(InitBlock); + } - RunCleanupsScope Scope(*this); + RunCleanupsScope Scope(*this); - // When building in Objective-C++ ARC mode, create an autorelease pool - // around the global initializers. - if (getLangOpts().ObjCAutoRefCount && getLangOpts().CPlusPlus) { - llvm::Value *token = EmitObjCAutoreleasePoolPush(); - EmitObjCAutoreleasePoolCleanup(token); - } + // When building in Objective-C++ ARC mode, create an autorelease pool + // around the global initializers. + if (getLangOpts().ObjCAutoRefCount && getLangOpts().CPlusPlus) { + llvm::Value *token = EmitObjCAutoreleasePoolPush(); + EmitObjCAutoreleasePoolCleanup(token); + } - for (unsigned i = 0, e = Decls.size(); i != e; ++i) - if (Decls[i]) - EmitRuntimeCall(Decls[i]); + for (unsigned i = 0, e = Decls.size(); i != e; ++i) + if (Decls[i]) + EmitRuntimeCall(Decls[i]); - Scope.ForceCleanup(); + Scope.ForceCleanup(); - if (ExitBlock) { - Builder.CreateBr(ExitBlock); - EmitBlock(ExitBlock); + if (ExitBlock) { + Builder.CreateBr(ExitBlock); + EmitBlock(ExitBlock); + } } FinishFunction(); @@ -476,17 +482,22 @@ CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn, void CodeGenFunction::GenerateCXXGlobalDtorsFunc(llvm::Function *Fn, const std::vector > &DtorsAndObjects) { - StartFunction(GlobalDecl(), getContext().VoidTy, Fn, - getTypes().arrangeNullaryFunction(), FunctionArgList()); - - // Emit the dtors, in reverse order from construction. - for (unsigned i = 0, e = DtorsAndObjects.size(); i != e; ++i) { - llvm::Value *Callee = DtorsAndObjects[e - i - 1].first; - llvm::CallInst *CI = Builder.CreateCall(Callee, - DtorsAndObjects[e - i - 1].second); - // Make sure the call and the callee agree on calling convention. - if (llvm::Function *F = dyn_cast(Callee)) - CI->setCallingConv(F->getCallingConv()); + { + ArtificialLocation AL(*this, Builder); + StartFunction(GlobalDecl(), getContext().VoidTy, Fn, + getTypes().arrangeNullaryFunction(), FunctionArgList()); + // Emit an artificial location for this function. + AL.Emit(); + + // Emit the dtors, in reverse order from construction. + for (unsigned i = 0, e = DtorsAndObjects.size(); i != e; ++i) { + llvm::Value *Callee = DtorsAndObjects[e - i - 1].first; + llvm::CallInst *CI = Builder.CreateCall(Callee, + DtorsAndObjects[e - i - 1].second); + // Make sure the call and the callee agree on calling convention. + if (llvm::Function *F = dyn_cast(Callee)) + CI->setCallingConv(F->getCallingConv()); + } } FinishFunction(); diff --git a/test/CodeGenCXX/globalinit-loc.cpp b/test/CodeGenCXX/globalinit-loc.cpp index bf3340c157..c6c27e379d 100644 --- a/test/CodeGenCXX/globalinit-loc.cpp +++ b/test/CodeGenCXX/globalinit-loc.cpp @@ -5,8 +5,9 @@ // with any source location. // // CHECK: define internal void @_GLOBAL__I_a -// CHECK-NOT: !dbg +// CHECK: !dbg ![[DBG:.*]] // CHECK: "_GLOBAL__I_a", i32 0, {{.*}}, i32 0} ; [ DW_TAG_subprogram ] [line 0] [local] [def] +// CHECK: ![[DBG]] = metadata !{i32 0, i32 0, # 99 "someheader.h" class A { public: -- 2.40.0