diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -388,7 +388,8 @@ VALUE_CODEGENOPT(SSPBufferSize, 32, 0) /// The kind of generated debug info. -ENUM_CODEGENOPT(DebugInfo, codegenoptions::DebugInfoKind, 4, codegenoptions::NoDebugInfo) +/// DO NOT COMMIT +ENUM_CODEGENOPT(DebugInfo, codegenoptions::DebugInfoKind, 4, codegenoptions::LocTrackingOnly) /// Whether to generate macro debug info. CODEGENOPT(MacroDebugInfo, 1, 0) diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -90,6 +90,8 @@ def warn_fe_backend_warning_attr : Warning<"call to '%0' declared with 'warning' attribute: %1">, BackendInfo, InGroup; +def note_fe_backend_inlined : Note<"In '%0' which inlined '%1'">; +def note_fe_backend_inlined2 : Note<"In '%0' which called '%1'">; def err_fe_invalid_code_complete_file : Error< "cannot locate code-completion file %0">, DefaultFatal; diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp --- a/clang/lib/CodeGen/CodeGenAction.cpp +++ b/clang/lib/CodeGen/CodeGenAction.cpp @@ -841,19 +841,47 @@ EmitOptimizationMessage(D, diag::warn_fe_backend_optimization_failure); } +static StringRef getName(DILocation *L) { + if (L) + if (DILocalScope *S = L->getScope()) + if (DISubprogram *P = S->getSubprogram()) + return P->getName(); + return ""; +} + void BackendConsumer::DontCallDiagHandler(const DiagnosticInfoDontCall &D) { - SourceLocation LocCookie = - SourceLocation::getFromRawEncoding(D.getLocCookie()); + SourceManager &SourceMgr = Context->getSourceManager(); + FileManager &FileMgr = SourceMgr.getFileManager(); + const DebugLoc &DL = D.getDebugLoc(); + // TODO: getFilename should be added to DebugLoc interface. + llvm::ErrorOr FE = FileMgr.getFile(DL->getFilename()); + SourceLocation Loc = + SourceMgr.translateFileLineCol(*FE, DL.getLine(), DL.getCol()); + + auto DiagType = D.getSeverity() == DiagnosticSeverity::DS_Error + ? diag::err_fe_backend_error_attr + : diag::warn_fe_backend_warning_attr; + Diags.Report(Loc, DiagType) + << llvm::demangle(D.getFunctionName().str()) << D.getNote(); - // FIXME: we can't yet diagnose indirect calls. When/if we can, we - // should instead assert that LocCookie.isValid(). - if (!LocCookie.isValid()) - return; + llvm::SmallVector DS = D.getInliningDecisions(); - Diags.Report(LocCookie, D.getSeverity() == DiagnosticSeverity::DS_Error - ? diag::err_fe_backend_error_attr - : diag::warn_fe_backend_warning_attr) - << llvm::demangle(D.getFunctionName().str()) << D.getNote(); + for (unsigned i = DS.size() - 1; i; --i) { + DebugLoc &DL = DS[i]; + StringRef Caller = getName(DS[i].get()); + StringRef Callee = getName(DS[i - 1].get()); + Loc = SourceMgr.translateFileLineCol(*FE, DL.getLine(), DL.getCol()); + Diags.Report(Loc, diag::note_fe_backend_inlined) + << llvm::demangle(Caller.str()) << llvm::demangle(Callee.str()); + } + { + DebugLoc &DL = DS[0]; + Loc = SourceMgr.translateFileLineCol(*FE, DL.getLine(), DL.getCol()); + StringRef Caller = getName(DL.get()); + StringRef Callee = D.getFunctionName(); + Diags.Report(Loc, diag::note_fe_backend_inlined2) + << llvm::demangle(Caller.str()) << llvm::demangle(Callee.str()); + } } void BackendConsumer::MisExpectDiagHandler( diff --git a/llvm/include/llvm/IR/DiagnosticInfo.h b/llvm/include/llvm/IR/DiagnosticInfo.h --- a/llvm/include/llvm/IR/DiagnosticInfo.h +++ b/llvm/include/llvm/IR/DiagnosticInfo.h @@ -1101,20 +1101,21 @@ class DiagnosticInfoDontCall : public DiagnosticInfo { StringRef CalleeName; StringRef Note; - unsigned LocCookie; + const DebugLoc &DL; public: DiagnosticInfoDontCall(StringRef CalleeName, StringRef Note, - DiagnosticSeverity DS, unsigned LocCookie) + DiagnosticSeverity DS, const DebugLoc &Loc) : DiagnosticInfo(DK_DontCall, DS), CalleeName(CalleeName), Note(Note), - LocCookie(LocCookie) {} + DL(Loc) {} StringRef getFunctionName() const { return CalleeName; } StringRef getNote() const { return Note; } - unsigned getLocCookie() const { return LocCookie; } + const DebugLoc &getDebugLoc() const { return DL; } void print(DiagnosticPrinter &DP) const override; static bool classof(const DiagnosticInfo *DI) { return DI->getKind() == DK_DontCall; } + SmallVector getInliningDecisions() const; }; } // end namespace llvm diff --git a/llvm/lib/IR/DiagnosticInfo.cpp b/llvm/lib/IR/DiagnosticInfo.cpp --- a/llvm/lib/IR/DiagnosticInfo.cpp +++ b/llvm/lib/IR/DiagnosticInfo.cpp @@ -417,25 +417,21 @@ void OptimizationRemarkAnalysisAliasing::anchor() {} void llvm::diagnoseDontCall(const CallInst &CI) { - const auto *F = + const auto *Callee = dyn_cast(CI.getCalledOperand()->stripPointerCasts()); - if (!F) + if (!Callee) return; for (int i = 0; i != 2; ++i) { auto AttrName = i == 0 ? "dontcall-error" : "dontcall-warn"; auto Sev = i == 0 ? DS_Error : DS_Warning; - if (F->hasFnAttribute(AttrName)) { - unsigned LocCookie = 0; - auto A = F->getFnAttribute(AttrName); - if (MDNode *MD = CI.getMetadata("srcloc")) - LocCookie = - mdconst::extract(MD->getOperand(0))->getZExtValue(); - DiagnosticInfoDontCall D(F->getName(), A.getValueAsString(), Sev, - LocCookie); - F->getContext().diagnose(D); + if (Callee->hasFnAttribute(AttrName)) { + auto A = Callee->getFnAttribute(AttrName); + DiagnosticInfoDontCall D(Callee->getName(), A.getValueAsString(), Sev, + CI.getDebugLoc()); + Callee->getContext().diagnose(D); } } } @@ -450,3 +446,12 @@ if (!getNote().empty()) DP << ": " << getNote(); } + +SmallVector DiagnosticInfoDontCall::getInliningDecisions() const { + SmallVector Locs; + DILocation *DIL = getDebugLoc().get(); + do { + Locs.emplace_back(DIL); + } while ((DIL = DIL->getInlinedAt())); + return Locs; +}