diff options
author | Djordje Todorovic <djordje.todorovic@rt-rk.com> | 2019-06-27 06:44:44 +0000 |
---|---|---|
committer | Djordje Todorovic <djordje.todorovic@rt-rk.com> | 2019-06-27 06:44:44 +0000 |
commit | 0f6516856670a435461f56a9faeb4aa8a35a6679 (patch) | |
tree | 1728d36fc2d0d8d34b901342cc8e01d03557f654 /clang/lib | |
parent | 852f45ba88acb7aebfb015e88790df877038e9a9 (diff) | |
download | bcm5719-llvm-0f6516856670a435461f56a9faeb4aa8a35a6679.tar.gz bcm5719-llvm-0f6516856670a435461f56a9faeb4aa8a35a6679.zip |
[clang] Add DISuprogram and DIE for a func decl
Attach a unique DISubprogram to a function declaration that will be
used for call site debug info.
([7/13] Introduce the debug entry values.)
Co-authored-by: Ananth Sowda <asowda@cisco.com>
Co-authored-by: Nikola Prica <nikola.prica@rt-rk.com>
Co-authored-by: Ivan Baev <ibaev@cisco.com>
Differential Revision: https://reviews.llvm.org/D60714
llvm-svn: 364502
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.cpp | 38 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.h | 10 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 14 |
3 files changed, 56 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 2a701e04e17..f49d1ef8787 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -3619,7 +3619,7 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, SourceLocation Loc, } void CGDebugInfo::EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, - QualType FnType) { + QualType FnType, llvm::Function *Fn) { StringRef Name; StringRef LinkageName; @@ -3629,7 +3629,9 @@ void CGDebugInfo::EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero; llvm::DIFile *Unit = getOrCreateFile(Loc); - llvm::DIScope *FDContext = getDeclContextDescriptor(D); + bool IsDeclForCallSite = Fn ? true : false; + llvm::DIScope *FDContext = + IsDeclForCallSite ? Unit : getDeclContextDescriptor(D); llvm::DINodeArray TParamsArray; if (isa<FunctionDecl>(D)) { // If there is a DISubprogram for this function available then use it. @@ -3656,10 +3658,38 @@ void CGDebugInfo::EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, if (CGM.getLangOpts().Optimize) SPFlags |= llvm::DISubprogram::SPFlagOptimized; - DBuilder.retainType(DBuilder.createFunction( + llvm::DISubprogram *SP = DBuilder.createFunction( FDContext, Name, LinkageName, Unit, LineNo, getOrCreateFunctionType(D, FnType, Unit), ScopeLine, Flags, SPFlags, - TParamsArray.get(), getFunctionDeclaration(D))); + TParamsArray.get(), getFunctionDeclaration(D)); + + if (IsDeclForCallSite) + Fn->setSubprogram(SP); + + DBuilder.retainType(SP); +} + +void CGDebugInfo::EmitFuncDeclForCallSite(llvm::CallBase *CallOrInvoke, + QualType CalleeType, + const FunctionDecl *CalleeDecl) { + auto &CGOpts = CGM.getCodeGenOpts(); + if (!CGOpts.EnableDebugEntryValues || !CGM.getLangOpts().Optimize || + !CallOrInvoke || + CGM.getCodeGenOpts().getDebugInfo() < codegenoptions::LimitedDebugInfo) + return; + + auto *Func = CallOrInvoke->getCalledFunction(); + if (!Func) + return; + + // If there is no DISubprogram attached to the function being called, + // create the one describing the function in order to have complete + // call site debug info. + if (Func->getSubprogram()) + return; + + if (!CalleeDecl->isStatic() && !CalleeDecl->isInlined()) + EmitFunctionDecl(CalleeDecl, CalleeDecl->getLocation(), CalleeType, Func); } void CGDebugInfo::EmitInlineFunctionStart(CGBuilderTy &Builder, GlobalDecl GD) { diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index e26088a63d0..7edbea86633 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -409,7 +409,15 @@ public: void EmitInlineFunctionEnd(CGBuilderTy &Builder); /// Emit debug info for a function declaration. - void EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, QualType FnType); + /// \p Fn is set only when a declaration for a debug call site gets created. + void EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, + QualType FnType, llvm::Function *Fn = nullptr); + + /// Emit debug info for an extern function being called. + /// This is needed for call site debug info. + void EmitFuncDeclForCallSite(llvm::CallBase *CallOrInvoke, + QualType CalleeType, + const FunctionDecl *CalleeDecl); /// Constructs the debug code for exiting a function. void EmitFunctionEnd(CGBuilderTy &Builder, llvm::Function *Fn); diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index c2330e0844b..abe10d383dc 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -4856,7 +4856,19 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee Callee.setFunctionPointer(CalleePtr); } - return EmitCall(FnInfo, Callee, ReturnValue, Args, nullptr, E->getExprLoc()); + llvm::CallBase *CallOrInvoke = nullptr; + RValue Call = EmitCall(FnInfo, Callee, ReturnValue, Args, &CallOrInvoke, + E->getExprLoc()); + + // Generate function declaration DISuprogram in order to be used + // in debug info about call sites. + if (CGDebugInfo *DI = getDebugInfo()) { + if (auto *CalleeDecl = dyn_cast_or_null<FunctionDecl>(TargetDecl)) + DI->EmitFuncDeclForCallSite(CallOrInvoke, QualType(FnType, 0), + CalleeDecl); + } + + return Call; } LValue CodeGenFunction:: |