xref: /freebsd/contrib/llvm-project/llvm/lib/IR/DiagnosticInfo.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1349cc55cSDimitry Andric //===- llvm/IR/DiagnosticInfo.cpp - Diagnostic Definitions ------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines the different classes involved in low level diagnostics.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric // Diagnostics reporting is still done as part of the LLVMContext.
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "llvm/IR/DiagnosticInfo.h"
150b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h"
160b57cec5SDimitry Andric #include "llvm/ADT/Twine.h"
170b57cec5SDimitry Andric #include "llvm/ADT/iterator_range.h"
1806c3fb27SDimitry Andric #include "llvm/Demangle/Demangle.h"
190b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h"
200b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
210b57cec5SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
220b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h"
230b57cec5SDimitry Andric #include "llvm/IR/DiagnosticPrinter.h"
240b57cec5SDimitry Andric #include "llvm/IR/Function.h"
250b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h"
260b57cec5SDimitry Andric #include "llvm/IR/Instruction.h"
271fd87a68SDimitry Andric #include "llvm/IR/Instructions.h"
280b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h"
290b57cec5SDimitry Andric #include "llvm/IR/Metadata.h"
300b57cec5SDimitry Andric #include "llvm/IR/Module.h"
310b57cec5SDimitry Andric #include "llvm/IR/Type.h"
320b57cec5SDimitry Andric #include "llvm/IR/Value.h"
330b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
340b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
35e8d8bef9SDimitry Andric #include "llvm/Support/InstructionCost.h"
360b57cec5SDimitry Andric #include "llvm/Support/Path.h"
370b57cec5SDimitry Andric #include "llvm/Support/ScopedPrinter.h"
380b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
390b57cec5SDimitry Andric #include <atomic>
400b57cec5SDimitry Andric #include <string>
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric using namespace llvm;
430b57cec5SDimitry Andric 
getNextAvailablePluginDiagnosticKind()440b57cec5SDimitry Andric int llvm::getNextAvailablePluginDiagnosticKind() {
450b57cec5SDimitry Andric   static std::atomic<int> PluginKindID(DK_FirstPluginKind);
460b57cec5SDimitry Andric   return ++PluginKindID;
470b57cec5SDimitry Andric }
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric const char *OptimizationRemarkAnalysis::AlwaysPrint = "";
500b57cec5SDimitry Andric 
DiagnosticInfoInlineAsm(const Instruction & I,const Twine & MsgStr,DiagnosticSeverity Severity)510b57cec5SDimitry Andric DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I,
520b57cec5SDimitry Andric                                                  const Twine &MsgStr,
530b57cec5SDimitry Andric                                                  DiagnosticSeverity Severity)
540b57cec5SDimitry Andric     : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr), Instr(&I) {
550b57cec5SDimitry Andric   if (const MDNode *SrcLoc = I.getMetadata("srcloc")) {
560b57cec5SDimitry Andric     if (SrcLoc->getNumOperands() != 0)
570b57cec5SDimitry Andric       if (const auto *CI =
580b57cec5SDimitry Andric               mdconst::dyn_extract<ConstantInt>(SrcLoc->getOperand(0)))
590b57cec5SDimitry Andric         LocCookie = CI->getZExtValue();
600b57cec5SDimitry Andric   }
610b57cec5SDimitry Andric }
620b57cec5SDimitry Andric 
print(DiagnosticPrinter & DP) const630b57cec5SDimitry Andric void DiagnosticInfoInlineAsm::print(DiagnosticPrinter &DP) const {
640b57cec5SDimitry Andric   DP << getMsgStr();
650b57cec5SDimitry Andric   if (getLocCookie())
660b57cec5SDimitry Andric     DP << " at line " << getLocCookie();
670b57cec5SDimitry Andric }
680b57cec5SDimitry Andric 
DiagnosticInfoResourceLimit(const Function & Fn,const char * ResourceName,uint64_t ResourceSize,uint64_t ResourceLimit,DiagnosticSeverity Severity,DiagnosticKind Kind)69bdd1243dSDimitry Andric DiagnosticInfoResourceLimit::DiagnosticInfoResourceLimit(
70bdd1243dSDimitry Andric     const Function &Fn, const char *ResourceName, uint64_t ResourceSize,
71bdd1243dSDimitry Andric     uint64_t ResourceLimit, DiagnosticSeverity Severity, DiagnosticKind Kind)
72bdd1243dSDimitry Andric     : DiagnosticInfoWithLocationBase(Kind, Severity, Fn, Fn.getSubprogram()),
73bdd1243dSDimitry Andric       Fn(Fn), ResourceName(ResourceName), ResourceSize(ResourceSize),
74bdd1243dSDimitry Andric       ResourceLimit(ResourceLimit) {}
75bdd1243dSDimitry Andric 
print(DiagnosticPrinter & DP) const760b57cec5SDimitry Andric void DiagnosticInfoResourceLimit::print(DiagnosticPrinter &DP) const {
77bdd1243dSDimitry Andric   DP << getLocationStr() << ": " << getResourceName() << " ("
78bdd1243dSDimitry Andric      << getResourceSize() << ") exceeds limit (" << getResourceLimit()
79bdd1243dSDimitry Andric      << ") in function '" << getFunction() << '\'';
800b57cec5SDimitry Andric }
810b57cec5SDimitry Andric 
print(DiagnosticPrinter & DP) const820b57cec5SDimitry Andric void DiagnosticInfoDebugMetadataVersion::print(DiagnosticPrinter &DP) const {
830b57cec5SDimitry Andric   DP << "ignoring debug info with an invalid version (" << getMetadataVersion()
840b57cec5SDimitry Andric      << ") in " << getModule();
850b57cec5SDimitry Andric }
860b57cec5SDimitry Andric 
print(DiagnosticPrinter & DP) const870b57cec5SDimitry Andric void DiagnosticInfoIgnoringInvalidDebugMetadata::print(
880b57cec5SDimitry Andric     DiagnosticPrinter &DP) const {
890b57cec5SDimitry Andric   DP << "ignoring invalid debug info in " << getModule().getModuleIdentifier();
900b57cec5SDimitry Andric }
910b57cec5SDimitry Andric 
print(DiagnosticPrinter & DP) const920b57cec5SDimitry Andric void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const {
930b57cec5SDimitry Andric   if (!FileName.empty()) {
940b57cec5SDimitry Andric     DP << getFileName();
950b57cec5SDimitry Andric     if (LineNum > 0)
960b57cec5SDimitry Andric       DP << ":" << getLineNum();
970b57cec5SDimitry Andric     DP << ": ";
980b57cec5SDimitry Andric   }
990b57cec5SDimitry Andric   DP << getMsg();
1000b57cec5SDimitry Andric }
1010b57cec5SDimitry Andric 
print(DiagnosticPrinter & DP) const1020b57cec5SDimitry Andric void DiagnosticInfoPGOProfile::print(DiagnosticPrinter &DP) const {
1030b57cec5SDimitry Andric   if (getFileName())
1040b57cec5SDimitry Andric     DP << getFileName() << ": ";
1050b57cec5SDimitry Andric   DP << getMsg();
1060b57cec5SDimitry Andric }
1070b57cec5SDimitry Andric 
anchor()1080b57cec5SDimitry Andric void DiagnosticInfo::anchor() {}
anchor()1090b57cec5SDimitry Andric void DiagnosticInfoStackSize::anchor() {}
anchor()1100b57cec5SDimitry Andric void DiagnosticInfoWithLocationBase::anchor() {}
anchor()1110b57cec5SDimitry Andric void DiagnosticInfoIROptimization::anchor() {}
1120b57cec5SDimitry Andric 
DiagnosticLocation(const DebugLoc & DL)1130b57cec5SDimitry Andric DiagnosticLocation::DiagnosticLocation(const DebugLoc &DL) {
1140b57cec5SDimitry Andric   if (!DL)
1150b57cec5SDimitry Andric     return;
1160b57cec5SDimitry Andric   File = DL->getFile();
1170b57cec5SDimitry Andric   Line = DL->getLine();
1180b57cec5SDimitry Andric   Column = DL->getColumn();
1190b57cec5SDimitry Andric }
1200b57cec5SDimitry Andric 
DiagnosticLocation(const DISubprogram * SP)1210b57cec5SDimitry Andric DiagnosticLocation::DiagnosticLocation(const DISubprogram *SP) {
1220b57cec5SDimitry Andric   if (!SP)
1230b57cec5SDimitry Andric     return;
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric   File = SP->getFile();
1260b57cec5SDimitry Andric   Line = SP->getScopeLine();
1270b57cec5SDimitry Andric   Column = 0;
1280b57cec5SDimitry Andric }
1290b57cec5SDimitry Andric 
getRelativePath() const1300b57cec5SDimitry Andric StringRef DiagnosticLocation::getRelativePath() const {
1310b57cec5SDimitry Andric   return File->getFilename();
1320b57cec5SDimitry Andric }
1330b57cec5SDimitry Andric 
getAbsolutePath() const1340b57cec5SDimitry Andric std::string DiagnosticLocation::getAbsolutePath() const {
1350b57cec5SDimitry Andric   StringRef Name = File->getFilename();
1360b57cec5SDimitry Andric   if (sys::path::is_absolute(Name))
1375ffd83dbSDimitry Andric     return std::string(Name);
1380b57cec5SDimitry Andric 
1390b57cec5SDimitry Andric   SmallString<128> Path;
1400b57cec5SDimitry Andric   sys::path::append(Path, File->getDirectory(), Name);
1410b57cec5SDimitry Andric   return sys::path::remove_leading_dotslash(Path).str();
1420b57cec5SDimitry Andric }
1430b57cec5SDimitry Andric 
getAbsolutePath() const1440b57cec5SDimitry Andric std::string DiagnosticInfoWithLocationBase::getAbsolutePath() const {
1450b57cec5SDimitry Andric   return Loc.getAbsolutePath();
1460b57cec5SDimitry Andric }
1470b57cec5SDimitry Andric 
getLocation(StringRef & RelativePath,unsigned & Line,unsigned & Column) const1480b57cec5SDimitry Andric void DiagnosticInfoWithLocationBase::getLocation(StringRef &RelativePath,
1490b57cec5SDimitry Andric                                                  unsigned &Line,
1500b57cec5SDimitry Andric                                                  unsigned &Column) const {
1510b57cec5SDimitry Andric   RelativePath = Loc.getRelativePath();
1520b57cec5SDimitry Andric   Line = Loc.getLine();
1530b57cec5SDimitry Andric   Column = Loc.getColumn();
1540b57cec5SDimitry Andric }
1550b57cec5SDimitry Andric 
getLocationStr() const156fe6060f1SDimitry Andric std::string DiagnosticInfoWithLocationBase::getLocationStr() const {
1570b57cec5SDimitry Andric   StringRef Filename("<unknown>");
1580b57cec5SDimitry Andric   unsigned Line = 0;
1590b57cec5SDimitry Andric   unsigned Column = 0;
1600b57cec5SDimitry Andric   if (isLocationAvailable())
1610b57cec5SDimitry Andric     getLocation(Filename, Line, Column);
1620b57cec5SDimitry Andric   return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
1630b57cec5SDimitry Andric }
1640b57cec5SDimitry Andric 
Argument(StringRef Key,const Value * V)1655ffd83dbSDimitry Andric DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
1665ffd83dbSDimitry Andric                                                    const Value *V)
1675ffd83dbSDimitry Andric     : Key(std::string(Key)) {
1680b57cec5SDimitry Andric   if (auto *F = dyn_cast<Function>(V)) {
1690b57cec5SDimitry Andric     if (DISubprogram *SP = F->getSubprogram())
1700b57cec5SDimitry Andric       Loc = SP;
1710b57cec5SDimitry Andric   }
1720b57cec5SDimitry Andric   else if (auto *I = dyn_cast<Instruction>(V))
1730b57cec5SDimitry Andric     Loc = I->getDebugLoc();
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric   // Only include names that correspond to user variables.  FIXME: We should use
1760b57cec5SDimitry Andric   // debug info if available to get the name of the user variable.
1770b57cec5SDimitry Andric   if (isa<llvm::Argument>(V) || isa<GlobalValue>(V))
1785ffd83dbSDimitry Andric     Val = std::string(GlobalValue::dropLLVMManglingEscape(V->getName()));
1790b57cec5SDimitry Andric   else if (isa<Constant>(V)) {
1800b57cec5SDimitry Andric     raw_string_ostream OS(Val);
1810b57cec5SDimitry Andric     V->printAsOperand(OS, /*PrintType=*/false);
182*0fca6ea1SDimitry Andric   } else if (auto *I = dyn_cast<Instruction>(V)) {
1830b57cec5SDimitry Andric     Val = I->getOpcodeName();
184*0fca6ea1SDimitry Andric   } else if (auto *MD = dyn_cast<MetadataAsValue>(V)) {
185*0fca6ea1SDimitry Andric     if (auto *S = dyn_cast<MDString>(MD->getMetadata()))
186*0fca6ea1SDimitry Andric       Val = S->getString();
187*0fca6ea1SDimitry Andric   }
1880b57cec5SDimitry Andric }
1890b57cec5SDimitry Andric 
Argument(StringRef Key,const Type * T)1900b57cec5SDimitry Andric DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, const Type *T)
1915ffd83dbSDimitry Andric     : Key(std::string(Key)) {
1920b57cec5SDimitry Andric   raw_string_ostream OS(Val);
1930b57cec5SDimitry Andric   OS << *T;
1940b57cec5SDimitry Andric }
1950b57cec5SDimitry Andric 
Argument(StringRef Key,StringRef S)1960b57cec5SDimitry Andric DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, StringRef S)
1975ffd83dbSDimitry Andric     : Key(std::string(Key)), Val(S.str()) {}
1980b57cec5SDimitry Andric 
Argument(StringRef Key,int N)1990b57cec5SDimitry Andric DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, int N)
2005ffd83dbSDimitry Andric     : Key(std::string(Key)), Val(itostr(N)) {}
2010b57cec5SDimitry Andric 
Argument(StringRef Key,float N)2020b57cec5SDimitry Andric DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, float N)
2035ffd83dbSDimitry Andric     : Key(std::string(Key)), Val(llvm::to_string(N)) {}
2040b57cec5SDimitry Andric 
Argument(StringRef Key,long N)2050b57cec5SDimitry Andric DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, long N)
2065ffd83dbSDimitry Andric     : Key(std::string(Key)), Val(itostr(N)) {}
2070b57cec5SDimitry Andric 
Argument(StringRef Key,long long N)2080b57cec5SDimitry Andric DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, long long N)
2095ffd83dbSDimitry Andric     : Key(std::string(Key)), Val(itostr(N)) {}
2100b57cec5SDimitry Andric 
Argument(StringRef Key,unsigned N)2110b57cec5SDimitry Andric DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, unsigned N)
2125ffd83dbSDimitry Andric     : Key(std::string(Key)), Val(utostr(N)) {}
2130b57cec5SDimitry Andric 
Argument(StringRef Key,unsigned long N)2140b57cec5SDimitry Andric DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
2150b57cec5SDimitry Andric                                                    unsigned long N)
2165ffd83dbSDimitry Andric     : Key(std::string(Key)), Val(utostr(N)) {}
2170b57cec5SDimitry Andric 
Argument(StringRef Key,unsigned long long N)2180b57cec5SDimitry Andric DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
2190b57cec5SDimitry Andric                                                    unsigned long long N)
2205ffd83dbSDimitry Andric     : Key(std::string(Key)), Val(utostr(N)) {}
2210b57cec5SDimitry Andric 
Argument(StringRef Key,ElementCount EC)222e8d8bef9SDimitry Andric DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
223e8d8bef9SDimitry Andric                                                    ElementCount EC)
224e8d8bef9SDimitry Andric     : Key(std::string(Key)) {
225e8d8bef9SDimitry Andric   raw_string_ostream OS(Val);
226e8d8bef9SDimitry Andric   EC.print(OS);
227e8d8bef9SDimitry Andric }
228e8d8bef9SDimitry Andric 
Argument(StringRef Key,InstructionCost C)229e8d8bef9SDimitry Andric DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
230e8d8bef9SDimitry Andric                                                    InstructionCost C)
231e8d8bef9SDimitry Andric     : Key(std::string(Key)) {
232e8d8bef9SDimitry Andric   raw_string_ostream OS(Val);
233e8d8bef9SDimitry Andric   C.print(OS);
234e8d8bef9SDimitry Andric }
235e8d8bef9SDimitry Andric 
Argument(StringRef Key,DebugLoc Loc)2360b57cec5SDimitry Andric DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, DebugLoc Loc)
2375ffd83dbSDimitry Andric     : Key(std::string(Key)), Loc(Loc) {
2380b57cec5SDimitry Andric   if (Loc) {
2390b57cec5SDimitry Andric     Val = (Loc->getFilename() + ":" + Twine(Loc.getLine()) + ":" +
2400b57cec5SDimitry Andric            Twine(Loc.getCol())).str();
2410b57cec5SDimitry Andric   } else {
2420b57cec5SDimitry Andric     Val = "<UNKNOWN LOCATION>";
2430b57cec5SDimitry Andric   }
2440b57cec5SDimitry Andric }
2450b57cec5SDimitry Andric 
print(DiagnosticPrinter & DP) const2460b57cec5SDimitry Andric void DiagnosticInfoOptimizationBase::print(DiagnosticPrinter &DP) const {
2470b57cec5SDimitry Andric   DP << getLocationStr() << ": " << getMsg();
2480b57cec5SDimitry Andric   if (Hotness)
2490b57cec5SDimitry Andric     DP << " (hotness: " << *Hotness << ")";
2500b57cec5SDimitry Andric }
2510b57cec5SDimitry Andric 
OptimizationRemark(const char * PassName,StringRef RemarkName,const DiagnosticLocation & Loc,const Value * CodeRegion)2520b57cec5SDimitry Andric OptimizationRemark::OptimizationRemark(const char *PassName,
2530b57cec5SDimitry Andric                                        StringRef RemarkName,
2540b57cec5SDimitry Andric                                        const DiagnosticLocation &Loc,
2550b57cec5SDimitry Andric                                        const Value *CodeRegion)
2560b57cec5SDimitry Andric     : DiagnosticInfoIROptimization(
2570b57cec5SDimitry Andric           DK_OptimizationRemark, DS_Remark, PassName, RemarkName,
2580b57cec5SDimitry Andric           *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
2590b57cec5SDimitry Andric 
OptimizationRemark(const char * PassName,StringRef RemarkName,const Instruction * Inst)2600b57cec5SDimitry Andric OptimizationRemark::OptimizationRemark(const char *PassName,
2610b57cec5SDimitry Andric                                        StringRef RemarkName,
2620b57cec5SDimitry Andric                                        const Instruction *Inst)
2630b57cec5SDimitry Andric     : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
2640b57cec5SDimitry Andric                                    RemarkName, *Inst->getParent()->getParent(),
2650b57cec5SDimitry Andric                                    Inst->getDebugLoc(), Inst->getParent()) {}
2660b57cec5SDimitry Andric 
getFirstFunctionBlock(const Function * Func)2675ffd83dbSDimitry Andric static const BasicBlock *getFirstFunctionBlock(const Function *Func) {
2685ffd83dbSDimitry Andric   return Func->empty() ? nullptr : &Func->front();
2690b57cec5SDimitry Andric }
2700b57cec5SDimitry Andric 
OptimizationRemark(const char * PassName,StringRef RemarkName,const Function * Func)2710b57cec5SDimitry Andric OptimizationRemark::OptimizationRemark(const char *PassName,
2720b57cec5SDimitry Andric                                        StringRef RemarkName,
2730b57cec5SDimitry Andric                                        const Function *Func)
2740b57cec5SDimitry Andric     : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
2750b57cec5SDimitry Andric                                    RemarkName, *Func, Func->getSubprogram(),
2765ffd83dbSDimitry Andric                                    getFirstFunctionBlock(Func)) {}
2770b57cec5SDimitry Andric 
isEnabled() const2780b57cec5SDimitry Andric bool OptimizationRemark::isEnabled() const {
2790b57cec5SDimitry Andric   const Function &Fn = getFunction();
2800b57cec5SDimitry Andric   LLVMContext &Ctx = Fn.getContext();
2810b57cec5SDimitry Andric   return Ctx.getDiagHandlerPtr()->isPassedOptRemarkEnabled(getPassName());
2820b57cec5SDimitry Andric }
2830b57cec5SDimitry Andric 
OptimizationRemarkMissed(const char * PassName,StringRef RemarkName,const DiagnosticLocation & Loc,const Value * CodeRegion)2840b57cec5SDimitry Andric OptimizationRemarkMissed::OptimizationRemarkMissed(
2850b57cec5SDimitry Andric     const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
2860b57cec5SDimitry Andric     const Value *CodeRegion)
2870b57cec5SDimitry Andric     : DiagnosticInfoIROptimization(
2880b57cec5SDimitry Andric           DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName,
2890b57cec5SDimitry Andric           *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
2900b57cec5SDimitry Andric 
OptimizationRemarkMissed(const char * PassName,StringRef RemarkName,const Instruction * Inst)2910b57cec5SDimitry Andric OptimizationRemarkMissed::OptimizationRemarkMissed(const char *PassName,
2920b57cec5SDimitry Andric                                                    StringRef RemarkName,
2930b57cec5SDimitry Andric                                                    const Instruction *Inst)
2940b57cec5SDimitry Andric     : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
2950b57cec5SDimitry Andric                                    PassName, RemarkName,
2960b57cec5SDimitry Andric                                    *Inst->getParent()->getParent(),
2970b57cec5SDimitry Andric                                    Inst->getDebugLoc(), Inst->getParent()) {}
2980b57cec5SDimitry Andric 
OptimizationRemarkMissed(const char * PassName,StringRef RemarkName,const Function * Func)299fe6060f1SDimitry Andric OptimizationRemarkMissed::OptimizationRemarkMissed(const char *PassName,
300fe6060f1SDimitry Andric                                                    StringRef RemarkName,
301fe6060f1SDimitry Andric                                                    const Function *Func)
302fe6060f1SDimitry Andric     : DiagnosticInfoIROptimization(
303fe6060f1SDimitry Andric           DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName, *Func,
304fe6060f1SDimitry Andric           Func->getSubprogram(), getFirstFunctionBlock(Func)) {}
305fe6060f1SDimitry Andric 
isEnabled() const3060b57cec5SDimitry Andric bool OptimizationRemarkMissed::isEnabled() const {
3070b57cec5SDimitry Andric   const Function &Fn = getFunction();
3080b57cec5SDimitry Andric   LLVMContext &Ctx = Fn.getContext();
3090b57cec5SDimitry Andric   return Ctx.getDiagHandlerPtr()->isMissedOptRemarkEnabled(getPassName());
3100b57cec5SDimitry Andric }
3110b57cec5SDimitry Andric 
OptimizationRemarkAnalysis(const char * PassName,StringRef RemarkName,const DiagnosticLocation & Loc,const Value * CodeRegion)3120b57cec5SDimitry Andric OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(
3130b57cec5SDimitry Andric     const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
3140b57cec5SDimitry Andric     const Value *CodeRegion)
3150b57cec5SDimitry Andric     : DiagnosticInfoIROptimization(
3160b57cec5SDimitry Andric           DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName,
3170b57cec5SDimitry Andric           *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
3180b57cec5SDimitry Andric 
OptimizationRemarkAnalysis(const char * PassName,StringRef RemarkName,const Instruction * Inst)3190b57cec5SDimitry Andric OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(const char *PassName,
3200b57cec5SDimitry Andric                                                        StringRef RemarkName,
3210b57cec5SDimitry Andric                                                        const Instruction *Inst)
3220b57cec5SDimitry Andric     : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
3230b57cec5SDimitry Andric                                    PassName, RemarkName,
3240b57cec5SDimitry Andric                                    *Inst->getParent()->getParent(),
3250b57cec5SDimitry Andric                                    Inst->getDebugLoc(), Inst->getParent()) {}
3260b57cec5SDimitry Andric 
OptimizationRemarkAnalysis(enum DiagnosticKind Kind,const char * PassName,StringRef RemarkName,const DiagnosticLocation & Loc,const Value * CodeRegion)3270b57cec5SDimitry Andric OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(
3280b57cec5SDimitry Andric     enum DiagnosticKind Kind, const char *PassName, StringRef RemarkName,
3290b57cec5SDimitry Andric     const DiagnosticLocation &Loc, const Value *CodeRegion)
3300b57cec5SDimitry Andric     : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, RemarkName,
3310b57cec5SDimitry Andric                                    *cast<BasicBlock>(CodeRegion)->getParent(),
3320b57cec5SDimitry Andric                                    Loc, CodeRegion) {}
3330b57cec5SDimitry Andric 
OptimizationRemarkAnalysis(const char * PassName,StringRef RemarkName,const Function * Func)334fe6060f1SDimitry Andric OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(const char *PassName,
335fe6060f1SDimitry Andric                                                        StringRef RemarkName,
336fe6060f1SDimitry Andric                                                        const Function *Func)
337fe6060f1SDimitry Andric     : DiagnosticInfoIROptimization(
338fe6060f1SDimitry Andric           DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName, *Func,
339fe6060f1SDimitry Andric           Func->getSubprogram(), getFirstFunctionBlock(Func)) {}
340fe6060f1SDimitry Andric 
isEnabled() const3410b57cec5SDimitry Andric bool OptimizationRemarkAnalysis::isEnabled() const {
3420b57cec5SDimitry Andric   const Function &Fn = getFunction();
3430b57cec5SDimitry Andric   LLVMContext &Ctx = Fn.getContext();
3440b57cec5SDimitry Andric   return Ctx.getDiagHandlerPtr()->isAnalysisRemarkEnabled(getPassName()) ||
3450b57cec5SDimitry Andric          shouldAlwaysPrint();
3460b57cec5SDimitry Andric }
3470b57cec5SDimitry Andric 
print(DiagnosticPrinter & DP) const3480b57cec5SDimitry Andric void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const {
3490b57cec5SDimitry Andric   DP << Diagnostic;
3500b57cec5SDimitry Andric }
3510b57cec5SDimitry Andric 
print(DiagnosticPrinter & DP) const352fe6060f1SDimitry Andric void DiagnosticInfoSrcMgr::print(DiagnosticPrinter &DP) const {
353fe6060f1SDimitry Andric   DP << Diagnostic;
354fe6060f1SDimitry Andric }
355fe6060f1SDimitry Andric 
DiagnosticInfoOptimizationFailure(const char * PassName,StringRef RemarkName,const DiagnosticLocation & Loc,const Value * CodeRegion)3560b57cec5SDimitry Andric DiagnosticInfoOptimizationFailure::DiagnosticInfoOptimizationFailure(
3570b57cec5SDimitry Andric     const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
3580b57cec5SDimitry Andric     const Value *CodeRegion)
3590b57cec5SDimitry Andric     : DiagnosticInfoIROptimization(
3600b57cec5SDimitry Andric           DK_OptimizationFailure, DS_Warning, PassName, RemarkName,
3610b57cec5SDimitry Andric           *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
3620b57cec5SDimitry Andric 
isEnabled() const3630b57cec5SDimitry Andric bool DiagnosticInfoOptimizationFailure::isEnabled() const {
3640b57cec5SDimitry Andric   // Only print warnings.
3650b57cec5SDimitry Andric   return getSeverity() == DS_Warning;
3660b57cec5SDimitry Andric }
3670b57cec5SDimitry Andric 
print(DiagnosticPrinter & DP) const3680b57cec5SDimitry Andric void DiagnosticInfoUnsupported::print(DiagnosticPrinter &DP) const {
3690b57cec5SDimitry Andric   std::string Str;
3700b57cec5SDimitry Andric   raw_string_ostream OS(Str);
3710b57cec5SDimitry Andric 
3720b57cec5SDimitry Andric   OS << getLocationStr() << ": in function " << getFunction().getName() << ' '
3730b57cec5SDimitry Andric      << *getFunction().getFunctionType() << ": " << Msg << '\n';
3740b57cec5SDimitry Andric   OS.flush();
3750b57cec5SDimitry Andric   DP << Str;
3760b57cec5SDimitry Andric }
3770b57cec5SDimitry Andric 
print(DiagnosticPrinter & DP) const3780b57cec5SDimitry Andric void DiagnosticInfoISelFallback::print(DiagnosticPrinter &DP) const {
3790b57cec5SDimitry Andric   DP << "Instruction selection used fallback path for " << getFunction();
3800b57cec5SDimitry Andric }
3810b57cec5SDimitry Andric 
insert(StringRef S)3820b57cec5SDimitry Andric void DiagnosticInfoOptimizationBase::insert(StringRef S) {
3830b57cec5SDimitry Andric   Args.emplace_back(S);
3840b57cec5SDimitry Andric }
3850b57cec5SDimitry Andric 
insert(Argument A)3860b57cec5SDimitry Andric void DiagnosticInfoOptimizationBase::insert(Argument A) {
3870b57cec5SDimitry Andric   Args.push_back(std::move(A));
3880b57cec5SDimitry Andric }
3890b57cec5SDimitry Andric 
insert(setIsVerbose V)3900b57cec5SDimitry Andric void DiagnosticInfoOptimizationBase::insert(setIsVerbose V) {
3910b57cec5SDimitry Andric   IsVerbose = true;
3920b57cec5SDimitry Andric }
3930b57cec5SDimitry Andric 
insert(setExtraArgs EA)3940b57cec5SDimitry Andric void DiagnosticInfoOptimizationBase::insert(setExtraArgs EA) {
3950b57cec5SDimitry Andric   FirstExtraArgIndex = Args.size();
3960b57cec5SDimitry Andric }
3970b57cec5SDimitry Andric 
getMsg() const3980b57cec5SDimitry Andric std::string DiagnosticInfoOptimizationBase::getMsg() const {
3990b57cec5SDimitry Andric   std::string Str;
4000b57cec5SDimitry Andric   raw_string_ostream OS(Str);
4010b57cec5SDimitry Andric   for (const DiagnosticInfoOptimizationBase::Argument &Arg :
4020b57cec5SDimitry Andric        make_range(Args.begin(), FirstExtraArgIndex == -1
4030b57cec5SDimitry Andric                                     ? Args.end()
4040b57cec5SDimitry Andric                                     : Args.begin() + FirstExtraArgIndex))
4050b57cec5SDimitry Andric     OS << Arg.Val;
406*0fca6ea1SDimitry Andric   return Str;
4070b57cec5SDimitry Andric }
4080b57cec5SDimitry Andric 
DiagnosticInfoMisExpect(const Instruction * Inst,Twine & Msg)40981ad6265SDimitry Andric DiagnosticInfoMisExpect::DiagnosticInfoMisExpect(const Instruction *Inst,
41081ad6265SDimitry Andric                                                  Twine &Msg)
41181ad6265SDimitry Andric     : DiagnosticInfoWithLocationBase(DK_MisExpect, DS_Warning,
41281ad6265SDimitry Andric                                      *Inst->getParent()->getParent(),
41381ad6265SDimitry Andric                                      Inst->getDebugLoc()),
41481ad6265SDimitry Andric       Msg(Msg) {}
41581ad6265SDimitry Andric 
print(DiagnosticPrinter & DP) const41681ad6265SDimitry Andric void DiagnosticInfoMisExpect::print(DiagnosticPrinter &DP) const {
41781ad6265SDimitry Andric   DP << getLocationStr() << ": " << getMsg();
41881ad6265SDimitry Andric }
41981ad6265SDimitry Andric 
anchor()4200b57cec5SDimitry Andric void OptimizationRemarkAnalysisFPCommute::anchor() {}
anchor()4210b57cec5SDimitry Andric void OptimizationRemarkAnalysisAliasing::anchor() {}
422349cc55cSDimitry Andric 
diagnoseDontCall(const CallInst & CI)423349cc55cSDimitry Andric void llvm::diagnoseDontCall(const CallInst &CI) {
424bdd1243dSDimitry Andric   const auto *F =
425bdd1243dSDimitry Andric       dyn_cast<Function>(CI.getCalledOperand()->stripPointerCasts());
426bdd1243dSDimitry Andric 
427349cc55cSDimitry Andric   if (!F)
428349cc55cSDimitry Andric     return;
429349cc55cSDimitry Andric 
430349cc55cSDimitry Andric   for (int i = 0; i != 2; ++i) {
431349cc55cSDimitry Andric     auto AttrName = i == 0 ? "dontcall-error" : "dontcall-warn";
432349cc55cSDimitry Andric     auto Sev = i == 0 ? DS_Error : DS_Warning;
433349cc55cSDimitry Andric 
434349cc55cSDimitry Andric     if (F->hasFnAttribute(AttrName)) {
435*0fca6ea1SDimitry Andric       uint64_t LocCookie = 0;
436349cc55cSDimitry Andric       auto A = F->getFnAttribute(AttrName);
437349cc55cSDimitry Andric       if (MDNode *MD = CI.getMetadata("srcloc"))
438349cc55cSDimitry Andric         LocCookie =
439349cc55cSDimitry Andric             mdconst::extract<ConstantInt>(MD->getOperand(0))->getZExtValue();
440349cc55cSDimitry Andric       DiagnosticInfoDontCall D(F->getName(), A.getValueAsString(), Sev,
441349cc55cSDimitry Andric                                LocCookie);
442349cc55cSDimitry Andric       F->getContext().diagnose(D);
443349cc55cSDimitry Andric     }
444349cc55cSDimitry Andric   }
445349cc55cSDimitry Andric }
446349cc55cSDimitry Andric 
print(DiagnosticPrinter & DP) const447349cc55cSDimitry Andric void DiagnosticInfoDontCall::print(DiagnosticPrinter &DP) const {
44806c3fb27SDimitry Andric   DP << "call to " << demangle(getFunctionName()) << " marked \"dontcall-";
449349cc55cSDimitry Andric   if (getSeverity() == DiagnosticSeverity::DS_Error)
450349cc55cSDimitry Andric     DP << "error\"";
451349cc55cSDimitry Andric   else
452349cc55cSDimitry Andric     DP << "warn\"";
453349cc55cSDimitry Andric   if (!getNote().empty())
454349cc55cSDimitry Andric     DP << ": " << getNote();
455349cc55cSDimitry Andric }
456