Path: blob/main/contrib/llvm-project/llvm/lib/IR/DiagnosticInfo.cpp
35233 views
//===- llvm/IR/DiagnosticInfo.cpp - Diagnostic Definitions ------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file defines the different classes involved in low level diagnostics.9//10// Diagnostics reporting is still done as part of the LLVMContext.11//===----------------------------------------------------------------------===//1213#include "llvm/IR/DiagnosticInfo.h"14#include "llvm/ADT/StringExtras.h"15#include "llvm/ADT/Twine.h"16#include "llvm/ADT/iterator_range.h"17#include "llvm/Demangle/Demangle.h"18#include "llvm/IR/BasicBlock.h"19#include "llvm/IR/Constants.h"20#include "llvm/IR/DebugInfoMetadata.h"21#include "llvm/IR/DerivedTypes.h"22#include "llvm/IR/DiagnosticPrinter.h"23#include "llvm/IR/Function.h"24#include "llvm/IR/GlobalValue.h"25#include "llvm/IR/Instruction.h"26#include "llvm/IR/Instructions.h"27#include "llvm/IR/LLVMContext.h"28#include "llvm/IR/Metadata.h"29#include "llvm/IR/Module.h"30#include "llvm/IR/Type.h"31#include "llvm/IR/Value.h"32#include "llvm/Support/Casting.h"33#include "llvm/Support/ErrorHandling.h"34#include "llvm/Support/InstructionCost.h"35#include "llvm/Support/Path.h"36#include "llvm/Support/ScopedPrinter.h"37#include "llvm/Support/raw_ostream.h"38#include <atomic>39#include <string>4041using namespace llvm;4243int llvm::getNextAvailablePluginDiagnosticKind() {44static std::atomic<int> PluginKindID(DK_FirstPluginKind);45return ++PluginKindID;46}4748const char *OptimizationRemarkAnalysis::AlwaysPrint = "";4950DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I,51const Twine &MsgStr,52DiagnosticSeverity Severity)53: DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr), Instr(&I) {54if (const MDNode *SrcLoc = I.getMetadata("srcloc")) {55if (SrcLoc->getNumOperands() != 0)56if (const auto *CI =57mdconst::dyn_extract<ConstantInt>(SrcLoc->getOperand(0)))58LocCookie = CI->getZExtValue();59}60}6162void DiagnosticInfoInlineAsm::print(DiagnosticPrinter &DP) const {63DP << getMsgStr();64if (getLocCookie())65DP << " at line " << getLocCookie();66}6768DiagnosticInfoResourceLimit::DiagnosticInfoResourceLimit(69const Function &Fn, const char *ResourceName, uint64_t ResourceSize,70uint64_t ResourceLimit, DiagnosticSeverity Severity, DiagnosticKind Kind)71: DiagnosticInfoWithLocationBase(Kind, Severity, Fn, Fn.getSubprogram()),72Fn(Fn), ResourceName(ResourceName), ResourceSize(ResourceSize),73ResourceLimit(ResourceLimit) {}7475void DiagnosticInfoResourceLimit::print(DiagnosticPrinter &DP) const {76DP << getLocationStr() << ": " << getResourceName() << " ("77<< getResourceSize() << ") exceeds limit (" << getResourceLimit()78<< ") in function '" << getFunction() << '\'';79}8081void DiagnosticInfoDebugMetadataVersion::print(DiagnosticPrinter &DP) const {82DP << "ignoring debug info with an invalid version (" << getMetadataVersion()83<< ") in " << getModule();84}8586void DiagnosticInfoIgnoringInvalidDebugMetadata::print(87DiagnosticPrinter &DP) const {88DP << "ignoring invalid debug info in " << getModule().getModuleIdentifier();89}9091void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const {92if (!FileName.empty()) {93DP << getFileName();94if (LineNum > 0)95DP << ":" << getLineNum();96DP << ": ";97}98DP << getMsg();99}100101void DiagnosticInfoPGOProfile::print(DiagnosticPrinter &DP) const {102if (getFileName())103DP << getFileName() << ": ";104DP << getMsg();105}106107void DiagnosticInfo::anchor() {}108void DiagnosticInfoStackSize::anchor() {}109void DiagnosticInfoWithLocationBase::anchor() {}110void DiagnosticInfoIROptimization::anchor() {}111112DiagnosticLocation::DiagnosticLocation(const DebugLoc &DL) {113if (!DL)114return;115File = DL->getFile();116Line = DL->getLine();117Column = DL->getColumn();118}119120DiagnosticLocation::DiagnosticLocation(const DISubprogram *SP) {121if (!SP)122return;123124File = SP->getFile();125Line = SP->getScopeLine();126Column = 0;127}128129StringRef DiagnosticLocation::getRelativePath() const {130return File->getFilename();131}132133std::string DiagnosticLocation::getAbsolutePath() const {134StringRef Name = File->getFilename();135if (sys::path::is_absolute(Name))136return std::string(Name);137138SmallString<128> Path;139sys::path::append(Path, File->getDirectory(), Name);140return sys::path::remove_leading_dotslash(Path).str();141}142143std::string DiagnosticInfoWithLocationBase::getAbsolutePath() const {144return Loc.getAbsolutePath();145}146147void DiagnosticInfoWithLocationBase::getLocation(StringRef &RelativePath,148unsigned &Line,149unsigned &Column) const {150RelativePath = Loc.getRelativePath();151Line = Loc.getLine();152Column = Loc.getColumn();153}154155std::string DiagnosticInfoWithLocationBase::getLocationStr() const {156StringRef Filename("<unknown>");157unsigned Line = 0;158unsigned Column = 0;159if (isLocationAvailable())160getLocation(Filename, Line, Column);161return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();162}163164DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,165const Value *V)166: Key(std::string(Key)) {167if (auto *F = dyn_cast<Function>(V)) {168if (DISubprogram *SP = F->getSubprogram())169Loc = SP;170}171else if (auto *I = dyn_cast<Instruction>(V))172Loc = I->getDebugLoc();173174// Only include names that correspond to user variables. FIXME: We should use175// debug info if available to get the name of the user variable.176if (isa<llvm::Argument>(V) || isa<GlobalValue>(V))177Val = std::string(GlobalValue::dropLLVMManglingEscape(V->getName()));178else if (isa<Constant>(V)) {179raw_string_ostream OS(Val);180V->printAsOperand(OS, /*PrintType=*/false);181} else if (auto *I = dyn_cast<Instruction>(V)) {182Val = I->getOpcodeName();183} else if (auto *MD = dyn_cast<MetadataAsValue>(V)) {184if (auto *S = dyn_cast<MDString>(MD->getMetadata()))185Val = S->getString();186}187}188189DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, const Type *T)190: Key(std::string(Key)) {191raw_string_ostream OS(Val);192OS << *T;193}194195DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, StringRef S)196: Key(std::string(Key)), Val(S.str()) {}197198DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, int N)199: Key(std::string(Key)), Val(itostr(N)) {}200201DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, float N)202: Key(std::string(Key)), Val(llvm::to_string(N)) {}203204DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, long N)205: Key(std::string(Key)), Val(itostr(N)) {}206207DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, long long N)208: Key(std::string(Key)), Val(itostr(N)) {}209210DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, unsigned N)211: Key(std::string(Key)), Val(utostr(N)) {}212213DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,214unsigned long N)215: Key(std::string(Key)), Val(utostr(N)) {}216217DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,218unsigned long long N)219: Key(std::string(Key)), Val(utostr(N)) {}220221DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,222ElementCount EC)223: Key(std::string(Key)) {224raw_string_ostream OS(Val);225EC.print(OS);226}227228DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,229InstructionCost C)230: Key(std::string(Key)) {231raw_string_ostream OS(Val);232C.print(OS);233}234235DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, DebugLoc Loc)236: Key(std::string(Key)), Loc(Loc) {237if (Loc) {238Val = (Loc->getFilename() + ":" + Twine(Loc.getLine()) + ":" +239Twine(Loc.getCol())).str();240} else {241Val = "<UNKNOWN LOCATION>";242}243}244245void DiagnosticInfoOptimizationBase::print(DiagnosticPrinter &DP) const {246DP << getLocationStr() << ": " << getMsg();247if (Hotness)248DP << " (hotness: " << *Hotness << ")";249}250251OptimizationRemark::OptimizationRemark(const char *PassName,252StringRef RemarkName,253const DiagnosticLocation &Loc,254const Value *CodeRegion)255: DiagnosticInfoIROptimization(256DK_OptimizationRemark, DS_Remark, PassName, RemarkName,257*cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}258259OptimizationRemark::OptimizationRemark(const char *PassName,260StringRef RemarkName,261const Instruction *Inst)262: DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,263RemarkName, *Inst->getParent()->getParent(),264Inst->getDebugLoc(), Inst->getParent()) {}265266static const BasicBlock *getFirstFunctionBlock(const Function *Func) {267return Func->empty() ? nullptr : &Func->front();268}269270OptimizationRemark::OptimizationRemark(const char *PassName,271StringRef RemarkName,272const Function *Func)273: DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,274RemarkName, *Func, Func->getSubprogram(),275getFirstFunctionBlock(Func)) {}276277bool OptimizationRemark::isEnabled() const {278const Function &Fn = getFunction();279LLVMContext &Ctx = Fn.getContext();280return Ctx.getDiagHandlerPtr()->isPassedOptRemarkEnabled(getPassName());281}282283OptimizationRemarkMissed::OptimizationRemarkMissed(284const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,285const Value *CodeRegion)286: DiagnosticInfoIROptimization(287DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName,288*cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}289290OptimizationRemarkMissed::OptimizationRemarkMissed(const char *PassName,291StringRef RemarkName,292const Instruction *Inst)293: DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,294PassName, RemarkName,295*Inst->getParent()->getParent(),296Inst->getDebugLoc(), Inst->getParent()) {}297298OptimizationRemarkMissed::OptimizationRemarkMissed(const char *PassName,299StringRef RemarkName,300const Function *Func)301: DiagnosticInfoIROptimization(302DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName, *Func,303Func->getSubprogram(), getFirstFunctionBlock(Func)) {}304305bool OptimizationRemarkMissed::isEnabled() const {306const Function &Fn = getFunction();307LLVMContext &Ctx = Fn.getContext();308return Ctx.getDiagHandlerPtr()->isMissedOptRemarkEnabled(getPassName());309}310311OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(312const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,313const Value *CodeRegion)314: DiagnosticInfoIROptimization(315DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName,316*cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}317318OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(const char *PassName,319StringRef RemarkName,320const Instruction *Inst)321: DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,322PassName, RemarkName,323*Inst->getParent()->getParent(),324Inst->getDebugLoc(), Inst->getParent()) {}325326OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(327enum DiagnosticKind Kind, const char *PassName, StringRef RemarkName,328const DiagnosticLocation &Loc, const Value *CodeRegion)329: DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, RemarkName,330*cast<BasicBlock>(CodeRegion)->getParent(),331Loc, CodeRegion) {}332333OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(const char *PassName,334StringRef RemarkName,335const Function *Func)336: DiagnosticInfoIROptimization(337DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName, *Func,338Func->getSubprogram(), getFirstFunctionBlock(Func)) {}339340bool OptimizationRemarkAnalysis::isEnabled() const {341const Function &Fn = getFunction();342LLVMContext &Ctx = Fn.getContext();343return Ctx.getDiagHandlerPtr()->isAnalysisRemarkEnabled(getPassName()) ||344shouldAlwaysPrint();345}346347void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const {348DP << Diagnostic;349}350351void DiagnosticInfoSrcMgr::print(DiagnosticPrinter &DP) const {352DP << Diagnostic;353}354355DiagnosticInfoOptimizationFailure::DiagnosticInfoOptimizationFailure(356const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,357const Value *CodeRegion)358: DiagnosticInfoIROptimization(359DK_OptimizationFailure, DS_Warning, PassName, RemarkName,360*cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}361362bool DiagnosticInfoOptimizationFailure::isEnabled() const {363// Only print warnings.364return getSeverity() == DS_Warning;365}366367void DiagnosticInfoUnsupported::print(DiagnosticPrinter &DP) const {368std::string Str;369raw_string_ostream OS(Str);370371OS << getLocationStr() << ": in function " << getFunction().getName() << ' '372<< *getFunction().getFunctionType() << ": " << Msg << '\n';373OS.flush();374DP << Str;375}376377void DiagnosticInfoISelFallback::print(DiagnosticPrinter &DP) const {378DP << "Instruction selection used fallback path for " << getFunction();379}380381void DiagnosticInfoOptimizationBase::insert(StringRef S) {382Args.emplace_back(S);383}384385void DiagnosticInfoOptimizationBase::insert(Argument A) {386Args.push_back(std::move(A));387}388389void DiagnosticInfoOptimizationBase::insert(setIsVerbose V) {390IsVerbose = true;391}392393void DiagnosticInfoOptimizationBase::insert(setExtraArgs EA) {394FirstExtraArgIndex = Args.size();395}396397std::string DiagnosticInfoOptimizationBase::getMsg() const {398std::string Str;399raw_string_ostream OS(Str);400for (const DiagnosticInfoOptimizationBase::Argument &Arg :401make_range(Args.begin(), FirstExtraArgIndex == -1402? Args.end()403: Args.begin() + FirstExtraArgIndex))404OS << Arg.Val;405return Str;406}407408DiagnosticInfoMisExpect::DiagnosticInfoMisExpect(const Instruction *Inst,409Twine &Msg)410: DiagnosticInfoWithLocationBase(DK_MisExpect, DS_Warning,411*Inst->getParent()->getParent(),412Inst->getDebugLoc()),413Msg(Msg) {}414415void DiagnosticInfoMisExpect::print(DiagnosticPrinter &DP) const {416DP << getLocationStr() << ": " << getMsg();417}418419void OptimizationRemarkAnalysisFPCommute::anchor() {}420void OptimizationRemarkAnalysisAliasing::anchor() {}421422void llvm::diagnoseDontCall(const CallInst &CI) {423const auto *F =424dyn_cast<Function>(CI.getCalledOperand()->stripPointerCasts());425426if (!F)427return;428429for (int i = 0; i != 2; ++i) {430auto AttrName = i == 0 ? "dontcall-error" : "dontcall-warn";431auto Sev = i == 0 ? DS_Error : DS_Warning;432433if (F->hasFnAttribute(AttrName)) {434uint64_t LocCookie = 0;435auto A = F->getFnAttribute(AttrName);436if (MDNode *MD = CI.getMetadata("srcloc"))437LocCookie =438mdconst::extract<ConstantInt>(MD->getOperand(0))->getZExtValue();439DiagnosticInfoDontCall D(F->getName(), A.getValueAsString(), Sev,440LocCookie);441F->getContext().diagnose(D);442}443}444}445446void DiagnosticInfoDontCall::print(DiagnosticPrinter &DP) const {447DP << "call to " << demangle(getFunctionName()) << " marked \"dontcall-";448if (getSeverity() == DiagnosticSeverity::DS_Error)449DP << "error\"";450else451DP << "warn\"";452if (!getNote().empty())453DP << ": " << getNote();454}455456457