Revert "PR14569: Omit debug info for thunks"
This reverts commit r189320. Alexey Samsonov and Dmitry Vyukov presented some arguments for keeping these around - though it still seems like those tasks could be solved by a tool just using the symbol table. In a very small number of cases, thunks may be inlined & debug info might be able to save profilers & similar tools from misclassifying those cases as part of the caller. The extra changes here plumb through the VarDecl for various cases to CodeGenFunction - this provides better fidelity through a few APIs but generally just causes the CGF::StartFunction to fallback to using the name of the IR function as the name in the debug info. The changes to debug-info-global-ctor-dtor.cpp seem like goodness. The two names that go missing (in favor of only emitting those names as linkage names) are names that can be demangled - emitting them only as the linkage name should encourage tools to do just that. Again, thanks to Dinesh Dwivedi for investigation/work on this issue. llvm-svn: 189421
This commit is contained in:
parent
7ca1d30e49
commit
ebe87e1cfa
|
@ -227,7 +227,7 @@ void CGCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
|
|||
CGM.ErrorUnsupported(&D, "non-trivial TLS destruction");
|
||||
|
||||
// The default behavior is to use atexit.
|
||||
CGF.registerGlobalDtorWithAtExit(dtor, addr);
|
||||
CGF.registerGlobalDtorWithAtExit(D, dtor, addr);
|
||||
}
|
||||
|
||||
/// Returns the adjustment, in bytes, required for the given
|
||||
|
|
|
@ -2450,7 +2450,7 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType,
|
|||
llvm::DIArray TParamsArray;
|
||||
if (!HasDecl) {
|
||||
// Use llvm function name.
|
||||
Name = Fn->getName();
|
||||
LinkageName = Fn->getName();
|
||||
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
||||
// If there is a DISubprogram for this function available then use it.
|
||||
llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator
|
||||
|
|
|
@ -100,9 +100,9 @@ static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D,
|
|||
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
@ -161,7 +161,7 @@ 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).
|
||||
|
@ -172,9 +172,9 @@ static llvm::Constant *createAtExitStub(CodeGenModule &CGM,
|
|||
|
||||
CodeGenFunction CGF(CGM);
|
||||
|
||||
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);
|
||||
|
||||
|
@ -189,10 +189,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 =
|
||||
|
@ -485,11 +486,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);
|
||||
|
@ -502,8 +501,7 @@ CodeGenFunction::generateDestroyHelper(llvm::Constant *addr,
|
|||
llvm::Function *fn =
|
||||
CreateGlobalInitOrDestructFunction(CGM, FTy, "__cxx_global_array_dtor");
|
||||
|
||||
StartFunction(GlobalDecl(), getContext().VoidTy, fn, FI, args,
|
||||
SourceLocation());
|
||||
StartFunction(VD, getContext().VoidTy, fn, FI, args, SourceLocation());
|
||||
|
||||
emitDestroy(addr, type, destroyer, useEHCleanupForArray);
|
||||
|
||||
|
|
|
@ -261,7 +261,8 @@ pushTemporaryCleanup(CodeGenFunction &CGF, const MaterializeTemporaryExpr *M,
|
|||
if (E->getType()->isArrayType()) {
|
||||
CleanupFn = CodeGenFunction(CGF.CGM).generateDestroyHelper(
|
||||
cast<llvm::Constant>(ReferenceTemporary), E->getType(),
|
||||
CodeGenFunction::destroyCXXObject, CGF.getLangOpts().Exceptions);
|
||||
CodeGenFunction::destroyCXXObject, CGF.getLangOpts().Exceptions,
|
||||
dyn_cast_or_null<VarDecl>(M->getExtendingDecl()));
|
||||
CleanupArg = llvm::Constant::getNullValue(CGF.Int8PtrTy);
|
||||
} else {
|
||||
CleanupFn =
|
||||
|
|
|
@ -292,7 +292,6 @@ void CodeGenFunction::GenerateVarArgsThunk(
|
|||
void CodeGenFunction::GenerateThunk(llvm::Function *Fn,
|
||||
const CGFunctionInfo &FnInfo,
|
||||
GlobalDecl GD, const ThunkInfo &Thunk) {
|
||||
DebugInfo = NULL; // debug info for thunks is not required or desired
|
||||
const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
|
||||
const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
|
||||
QualType ThisType = MD->getThisType(getContext());
|
||||
|
|
|
@ -1021,10 +1021,10 @@ public:
|
|||
bool useEHCleanupForArray);
|
||||
void emitDestroy(llvm::Value *addr, QualType type, Destroyer *destroyer,
|
||||
bool useEHCleanupForArray);
|
||||
llvm::Function *generateDestroyHelper(llvm::Constant *addr,
|
||||
QualType type,
|
||||
llvm::Function *generateDestroyHelper(llvm::Constant *addr, QualType type,
|
||||
Destroyer *destroyer,
|
||||
bool useEHCleanupForArray);
|
||||
bool useEHCleanupForArray,
|
||||
const VarDecl *VD);
|
||||
void emitArrayDestroy(llvm::Value *begin, llvm::Value *end,
|
||||
QualType type, Destroyer *destroyer,
|
||||
bool checkZeroLength, bool useEHCleanup);
|
||||
|
@ -2305,7 +2305,8 @@ public:
|
|||
|
||||
/// Call atexit() with a function that passes the given argument to
|
||||
/// the given function.
|
||||
void registerGlobalDtorWithAtExit(llvm::Constant *fn, llvm::Constant *addr);
|
||||
void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::Constant *fn,
|
||||
llvm::Constant *addr);
|
||||
|
||||
/// Emit code in this function to perform a guarded variable
|
||||
/// initialization. Guarded initializations are used when it's not
|
||||
|
|
|
@ -1310,7 +1310,7 @@ void ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
|
|||
return CGM.AddCXXDtorEntry(dtor, addr);
|
||||
}
|
||||
|
||||
CGF.registerGlobalDtorWithAtExit(dtor, addr);
|
||||
CGF.registerGlobalDtorWithAtExit(D, dtor, addr);
|
||||
}
|
||||
|
||||
/// Get the appropriate linkage for the wrapper function. This is essentially
|
||||
|
|
|
@ -22,6 +22,6 @@ void foo() {
|
|||
// CHECK-NOKEXT: [ DW_TAG_subprogram ] [line 13] [local] [def] [__cxx_global_array_dtor]
|
||||
// CHECK-NOKEXT: [ DW_TAG_subprogram ] [line 13] [local] [def] [__dtor_]
|
||||
// CHECK-NOKEXT: [ DW_TAG_subprogram ] [line 16] [local] [def] [__dtor__ZZ3foovE4stat]
|
||||
// CHECK-NOKEXT: [ DW_TAG_subprogram ] [line {{.*}}] [local] [def] [_GLOBAL__I_a]
|
||||
// CHECK-NOKEXT: [ DW_TAG_subprogram ] [line {{.*}}] [local] [def]{{$}}
|
||||
|
||||
// CHECK-KEXT: [ DW_TAG_subprogram ] [line {{.*}}] [local] [def] [_GLOBAL__D_a]
|
||||
// CHECK-KEXT: [ DW_TAG_subprogram ] [line {{.*}}] [local] [def]{{$}}
|
||||
|
|
|
@ -14,4 +14,4 @@ struct C : A, B {
|
|||
|
||||
void C::f() { }
|
||||
|
||||
// CHECK-NOT: [ DW_TAG_subprogram ] [line 15] [def] [_ZThn{{4|8}}_N1C1fEv]
|
||||
// CHECK: metadata !"_ZThn{{4|8}}_N1C1fEv", i32 15, {{.*}} ; [ DW_TAG_subprogram ] [line 15] [def]{{$}}
|
||||
|
|
Loading…
Reference in New Issue