Author: djtodoro Date: Wed Jun 26 23:44:44 2019 New Revision: 364502 URL: http://llvm.org/viewvc/llvm-project?rev=364502&view=rev Log: [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 <aso...@cisco.com> Co-authored-by: Nikola Prica <nikola.pr...@rt-rk.com> Co-authored-by: Ivan Baev <ib...@cisco.com> Differential Revision: https://reviews.llvm.org/D60714 Added: cfe/trunk/test/CodeGen/debug-info-extern-call.c Modified: cfe/trunk/include/clang/AST/Decl.h cfe/trunk/lib/CodeGen/CGDebugInfo.cpp cfe/trunk/lib/CodeGen/CGDebugInfo.h cfe/trunk/lib/CodeGen/CGExpr.cpp Modified: cfe/trunk/include/clang/AST/Decl.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=364502&r1=364501&r2=364502&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/Decl.h (original) +++ cfe/trunk/include/clang/AST/Decl.h Wed Jun 26 23:44:44 2019 @@ -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 { Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=364502&r1=364501&r2=364502&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original) +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Wed Jun 26 23:44:44 2019 @@ -3619,7 +3619,7 @@ void CGDebugInfo::EmitFunctionStart(Glob } 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(Globa 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(Globa 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) { Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.h?rev=364502&r1=364501&r2=364502&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGDebugInfo.h (original) +++ cfe/trunk/lib/CodeGen/CGDebugInfo.h Wed Jun 26 23:44:44 2019 @@ -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); Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=364502&r1=364501&r2=364502&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Wed Jun 26 23:44:44 2019 @@ -4856,7 +4856,19 @@ RValue CodeGenFunction::EmitCall(QualTyp 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:: Added: cfe/trunk/test/CodeGen/debug-info-extern-call.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/debug-info-extern-call.c?rev=364502&view=auto ============================================================================== --- cfe/trunk/test/CodeGen/debug-info-extern-call.c (added) +++ cfe/trunk/test/CodeGen/debug-info-extern-call.c Wed Jun 26 23:44:44 2019 @@ -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; +} + _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits