forked from OSchip/llvm-project
[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
This commit is contained in:
parent
852f45ba88
commit
0f65168566
|
@ -2396,6 +2396,8 @@ public:
|
|||
|
||||
bool doesDeclarationForceExternallyVisibleDefinition() const;
|
||||
|
||||
bool isStatic() const { return getStorageClass() == SC_Static; }
|
||||
|
||||
/// Whether this function declaration represents an C++ overloaded
|
||||
/// operator, e.g., "operator+".
|
||||
bool isOverloadedOperator() const {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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::
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
// RUN: %clang -Xclang -femit-debug-entry-values -g -O2 -target x86_64-none-linux-gnu -S -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK-EXT
|
||||
// CHECK-EXT: !DISubprogram(name: "fn1"
|
||||
|
||||
// RUN: %clang -g -O2 -target x86_64-none-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
|
||||
// CHECK-NOT: !DISubprogram(name: "fn1"
|
||||
|
||||
extern int fn1(int a, int b);
|
||||
|
||||
int fn2 () {
|
||||
int x = 4, y = 5;
|
||||
int res = fn1(x, y);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
Loading…
Reference in New Issue