Index: include/clang/AST/Decl.h =================================================================== --- include/clang/AST/Decl.h +++ include/clang/AST/Decl.h @@ -2370,6 +2370,8 @@ 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 { Index: lib/CodeGen/CGDebugInfo.h =================================================================== --- lib/CodeGen/CGDebugInfo.h +++ lib/CodeGen/CGDebugInfo.h @@ -405,7 +405,8 @@ void EmitInlineFunctionEnd(CGBuilderTy &Builder); /// Emit debug info for a function declaration. - void EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, QualType FnType); + void EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, + QualType FnType, llvm::Function *Fn = nullptr); /// Constructs the debug code for exiting a function. void EmitFunctionEnd(CGBuilderTy &Builder, llvm::Function *Fn); Index: lib/CodeGen/CGDebugInfo.cpp =================================================================== --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -3544,7 +3544,7 @@ } void CGDebugInfo::EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, - QualType FnType) { + QualType FnType, llvm::Function *Fn) { StringRef Name; StringRef LinkageName; @@ -3554,7 +3554,8 @@ 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(D)) { // If there is a DISubprogram for this function available then use it. @@ -3581,10 +3582,20 @@ if (CGM.getLangOpts().Optimize) SPFlags |= llvm::DISubprogram::SPFlagOptimized; - DBuilder.retainType(DBuilder.createFunction( - FDContext, Name, LinkageName, Unit, LineNo, - getOrCreateFunctionType(D, FnType, Unit), ScopeLine, Flags, SPFlags, - TParamsArray.get(), getFunctionDeclaration(D))); + if (IsDeclForCallSite) + SPFlags |= llvm::DISubprogram::SPFlagDeclForCallSite; + llvm::DISubroutineType *SubroutineType = + IsDeclForCallSite ? nullptr : getOrCreateFunctionType(D, FnType, Unit); + + llvm::DISubprogram *SP = DBuilder.createFunction( + FDContext, Name, LinkageName, Unit, LineNo, SubroutineType, ScopeLine, + Flags, SPFlags, TParamsArray.get(), getFunctionDeclaration(D), + nullptr, IsDeclForCallSite); + + if (IsDeclForCallSite) + Fn->setSubprogram(SP); + + DBuilder.retainType(SP); } void CGDebugInfo::EmitInlineFunctionStart(CGBuilderTy &Builder, GlobalDecl GD) { Index: lib/CodeGen/CGExpr.cpp =================================================================== --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -4783,7 +4783,33 @@ 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. + auto &CGOpts = CGM.getCodeGenOpts(); + if (CGOpts.EnableParamEntryValues && CGM.getLangOpts().Optimize && + callOrInvoke) { + if (CGDebugInfo *DI = getDebugInfo()) { + if (CGOpts.getDebugInfo() >= codegenoptions::LimitedDebugInfo && + CGOpts.getDebuggerTuning() == llvm::DebuggerKind::GDB && + CGOpts.DwarfVersion == 4) { + if (auto *Func = callOrInvoke->getCalledFunction()) + if (!Func->getSubprogram()) + if (const FunctionDecl *CalledFD = + dyn_cast_or_null(TargetDecl)) + if (!CalledFD->isStatic() && + !CalledFD->isInlined()) { + DI->EmitFunctionDecl(CalledFD, CalledFD->getLocation(), + CalleeType, Func); + } + } + } + } + + return Call; } LValue CodeGenFunction::