DiagnosticInfo.cpp revision 360784
1234353Sdim//===- llvm/Support/DiagnosticInfo.cpp - Diagnostic Definitions -*- C++ -*-===// 2193323Sed// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6193323Sed// 7193323Sed//===----------------------------------------------------------------------===// 8193323Sed// 9193323Sed// This file defines the different classes involved in low level diagnostics. 10193323Sed// 11193323Sed// Diagnostics reporting is still done as part of the LLVMContext. 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14249423Sdim#include "llvm/IR/DiagnosticInfo.h" 15224145Sdim#include "LLVMContextImpl.h" 16249423Sdim#include "llvm/ADT/StringExtras.h" 17193323Sed#include "llvm/ADT/Twine.h" 18193323Sed#include "llvm/ADT/iterator_range.h" 19193323Sed#include "llvm/IR/BasicBlock.h" 20276479Sdim#include "llvm/IR/Constants.h" 21251662Sdim#include "llvm/IR/DebugInfoMetadata.h" 22327952Sdim#include "llvm/IR/DerivedTypes.h" 23212904Sdim#include "llvm/IR/DiagnosticPrinter.h" 24251662Sdim#include "llvm/IR/Function.h" 25193323Sed#include "llvm/IR/GlobalValue.h" 26212904Sdim#include "llvm/IR/Instruction.h" 27204642Srdivacky#include "llvm/IR/LLVMContext.h" 28212904Sdim#include "llvm/IR/Metadata.h" 29276479Sdim#include "llvm/IR/Module.h" 30276479Sdim#include "llvm/IR/Type.h" 31280031Sdim#include "llvm/IR/Value.h" 32224145Sdim#include "llvm/Support/Casting.h" 33288943Sdim#include "llvm/Support/CommandLine.h" 34193323Sed#include "llvm/Support/ErrorHandling.h" 35276479Sdim#include "llvm/Support/Path.h" 36198090Srdivacky#include "llvm/Support/Regex.h" 37226633Sdim#include "llvm/Support/ScopedPrinter.h" 38198090Srdivacky#include "llvm/Support/raw_ostream.h" 39193323Sed#include <atomic> 40276479Sdim#include <cassert> 41276479Sdim#include <memory> 42276479Sdim#include <string> 43276479Sdim 44251662Sdimusing namespace llvm; 45261991Sdim 46224145Sdimint llvm::getNextAvailablePluginDiagnosticKind() { 47224145Sdim static std::atomic<int> PluginKindID(DK_FirstPluginKind); 48327952Sdim return ++PluginKindID; 49327952Sdim} 50327952Sdim 51327952Sdimconst char *OptimizationRemarkAnalysis::AlwaysPrint = ""; 52327952Sdim 53327952SdimDiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I, 54327952Sdim const Twine &MsgStr, 55327952Sdim DiagnosticSeverity Severity) 56327952Sdim : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr), Instr(&I) { 57341825Sdim if (const MDNode *SrcLoc = I.getMetadata("srcloc")) { 58341825Sdim if (SrcLoc->getNumOperands() != 0) 59327952Sdim if (const auto *CI = 60239462Sdim mdconst::dyn_extract<ConstantInt>(SrcLoc->getOperand(0))) 61239462Sdim LocCookie = CI->getZExtValue(); 62239462Sdim } 63239462Sdim} 64251662Sdim 65251662Sdimvoid DiagnosticInfoInlineAsm::print(DiagnosticPrinter &DP) const { 66251662Sdim DP << getMsgStr(); 67276479Sdim if (getLocCookie()) 68276479Sdim DP << " at line " << getLocCookie(); 69276479Sdim} 70276479Sdim 71288943Sdimvoid DiagnosticInfoResourceLimit::print(DiagnosticPrinter &DP) const { 72288943Sdim DP << getResourceName() << " limit"; 73288943Sdim 74288943Sdim if (getResourceLimit() != 0) 75341825Sdim DP << " of " << getResourceLimit(); 76341825Sdim 77341825Sdim DP << " exceeded (" << getResourceSize() << ") in " << getFunction(); 78341825Sdim} 79341825Sdim 80341825Sdimvoid DiagnosticInfoDebugMetadataVersion::print(DiagnosticPrinter &DP) const { 81341825Sdim DP << "ignoring debug info with an invalid version (" << getMetadataVersion() 82341825Sdim << ") in " << getModule(); 83341825Sdim} 84341825Sdim 85341825Sdimvoid DiagnosticInfoIgnoringInvalidDebugMetadata::print( 86341825Sdim DiagnosticPrinter &DP) const { 87341825Sdim DP << "ignoring invalid debug info in " << getModule().getModuleIdentifier(); 88341825Sdim} 89341825Sdim 90341825Sdimvoid DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const { 91341825Sdim if (!FileName.empty()) { 92341825Sdim DP << getFileName(); 93341825Sdim if (LineNum > 0) 94341825Sdim DP << ":" << getLineNum(); 95341825Sdim DP << ": "; 96261991Sdim } 97261991Sdim DP << getMsg(); 98261991Sdim} 99276479Sdim 100321369Sdimvoid DiagnosticInfoPGOProfile::print(DiagnosticPrinter &DP) const { 101321369Sdim if (getFileName()) 102321369Sdim DP << getFileName() << ": "; 103288943Sdim DP << getMsg(); 104193323Sed} 105218893Sdim 106218893Sdimvoid DiagnosticInfo::anchor() {} 107276479Sdimvoid DiagnosticInfoStackSize::anchor() {} 108276479Sdimvoid DiagnosticInfoWithLocationBase::anchor() {} 109276479Sdimvoid DiagnosticInfoIROptimization::anchor() {} 110276479Sdim 111360784SdimDiagnosticLocation::DiagnosticLocation(const DebugLoc &DL) { 112243830Sdim if (!DL) 113243830Sdim return; 114276479Sdim File = DL->getFile(); 115280031Sdim Line = DL->getLine(); 116276479Sdim Column = DL->getColumn(); 117234353Sdim} 118234353Sdim 119276479SdimDiagnosticLocation::DiagnosticLocation(const DISubprogram *SP) { 120218893Sdim if (!SP) 121218893Sdim return; 122234353Sdim 123234353Sdim File = SP->getFile(); 124288943Sdim Line = SP->getScopeLine(); 125288943Sdim Column = 0; 126288943Sdim} 127276479Sdim 128360784SdimStringRef DiagnosticLocation::getRelativePath() const { 129234353Sdim return File->getFilename(); 130309124Sdim} 131276479Sdim 132276479Sdimstd::string DiagnosticLocation::getAbsolutePath() const { 133276479Sdim StringRef Name = File->getFilename(); 134234353Sdim if (sys::path::is_absolute(Name)) 135243830Sdim return Name; 136243830Sdim 137276479Sdim SmallString<128> Path; 138234353Sdim sys::path::append(Path, File->getDirectory(), Name); 139276479Sdim return sys::path::remove_leading_dotslash(Path).str(); 140234353Sdim} 141234353Sdim 142276479Sdimstd::string DiagnosticInfoWithLocationBase::getAbsolutePath() const { 143234353Sdim return Loc.getAbsolutePath(); 144239462Sdim} 145288943Sdim 146309124Sdimvoid DiagnosticInfoWithLocationBase::getLocation(StringRef &RelativePath, 147288943Sdim unsigned &Line, 148288943Sdim unsigned &Column) const { 149288943Sdim RelativePath = Loc.getRelativePath(); 150276479Sdim Line = Loc.getLine(); 151288943Sdim Column = Loc.getColumn(); 152288943Sdim} 153288943Sdim 154288943Sdimconst std::string DiagnosticInfoWithLocationBase::getLocationStr() const { 155288943Sdim StringRef Filename("<unknown>"); 156288943Sdim unsigned Line = 0; 157288943Sdim unsigned Column = 0; 158288943Sdim if (isLocationAvailable()) 159309124Sdim getLocation(Filename, Line, Column); 160309124Sdim return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str(); 161309124Sdim} 162288943Sdim 163288943SdimDiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, const Value *V) 164288943Sdim : Key(Key) { 165288943Sdim if (auto *F = dyn_cast<Function>(V)) { 166288943Sdim if (DISubprogram *SP = F->getSubprogram()) 167288943Sdim Loc = SP; 168288943Sdim } 169288943Sdim else if (auto *I = dyn_cast<Instruction>(V)) 170288943Sdim Loc = I->getDebugLoc(); 171288943Sdim 172288943Sdim // Only include names that correspond to user variables. FIXME: We should use 173288943Sdim // debug info if available to get the name of the user variable. 174288943Sdim if (isa<llvm::Argument>(V) || isa<GlobalValue>(V)) 175276479Sdim Val = GlobalValue::dropLLVMManglingEscape(V->getName()); 176309124Sdim else if (isa<Constant>(V)) { 177309124Sdim raw_string_ostream OS(Val); 178276479Sdim V->printAsOperand(OS, /*PrintType=*/false); 179276479Sdim } else if (auto *I = dyn_cast<Instruction>(V)) 180276479Sdim Val = I->getOpcodeName(); 181276479Sdim} 182309124Sdim 183296417SdimDiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, const Type *T) 184296417Sdim : Key(Key) { 185309124Sdim raw_string_ostream OS(Val); 186360784Sdim OS << *T; 187276479Sdim} 188276479Sdim 189360784SdimDiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, StringRef S) 190276479Sdim : Key(Key), Val(S.str()) {} 191309124Sdim 192276479SdimDiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, int N) 193276479Sdim : Key(Key), Val(itostr(N)) {} 194276479Sdim 195276479SdimDiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, float N) 196276479Sdim : Key(Key), Val(llvm::to_string(N)) {} 197276479Sdim 198276479SdimDiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, long N) 199309124Sdim : Key(Key), Val(itostr(N)) {} 200276479Sdim 201276479SdimDiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, long long N) 202276479Sdim : Key(Key), Val(itostr(N)) {} 203276479Sdim 204276479SdimDiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, unsigned N) 205360784Sdim : Key(Key), Val(utostr(N)) {} 206276479Sdim 207276479SdimDiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, 208276479Sdim unsigned long N) 209276479Sdim : Key(Key), Val(utostr(N)) {} 210276479Sdim 211276479SdimDiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, 212276479Sdim unsigned long long N) 213276479Sdim : Key(Key), Val(utostr(N)) {} 214276479Sdim 215276479SdimDiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, DebugLoc Loc) 216276479Sdim : Key(Key), Loc(Loc) { 217276479Sdim if (Loc) { 218276479Sdim Val = (Loc->getFilename() + ":" + Twine(Loc.getLine()) + ":" + 219309124Sdim Twine(Loc.getCol())).str(); 220276479Sdim } else { 221276479Sdim Val = "<UNKNOWN LOCATION>"; 222276479Sdim } 223276479Sdim} 224276479Sdim 225276479Sdimvoid DiagnosticInfoOptimizationBase::print(DiagnosticPrinter &DP) const { 226276479Sdim DP << getLocationStr() << ": " << getMsg(); 227276479Sdim if (Hotness) 228296417Sdim DP << " (hotness: " << *Hotness << ")"; 229296417Sdim} 230296417Sdim 231296417SdimOptimizationRemark::OptimizationRemark(const char *PassName, 232296417Sdim StringRef RemarkName, 233296417Sdim const DiagnosticLocation &Loc, 234296417Sdim const Value *CodeRegion) 235296417Sdim : DiagnosticInfoIROptimization( 236296417Sdim DK_OptimizationRemark, DS_Remark, PassName, RemarkName, 237296417Sdim *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {} 238296417Sdim 239296417SdimOptimizationRemark::OptimizationRemark(const char *PassName, 240296417Sdim StringRef RemarkName, 241296417Sdim const Instruction *Inst) 242296417Sdim : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName, 243296417Sdim RemarkName, *Inst->getParent()->getParent(), 244296417Sdim Inst->getDebugLoc(), Inst->getParent()) {} 245296417Sdim 246296417Sdim// Helper to allow for an assert before attempting to return an invalid 247296417Sdim// reference. 248296417Sdimstatic const BasicBlock &getFirstFunctionBlock(const Function *Func) { 249296417Sdim assert(!Func->empty() && "Function does not have a body"); 250296417Sdim return Func->front(); 251296417Sdim} 252296417Sdim 253296417SdimOptimizationRemark::OptimizationRemark(const char *PassName, 254296417Sdim StringRef RemarkName, 255296417Sdim const Function *Func) 256296417Sdim : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName, 257296417Sdim RemarkName, *Func, Func->getSubprogram(), 258296417Sdim &getFirstFunctionBlock(Func)) {} 259296417Sdim 260296417Sdimbool OptimizationRemark::isEnabled() const { 261296417Sdim const Function &Fn = getFunction(); 262296417Sdim LLVMContext &Ctx = Fn.getContext(); 263296417Sdim return Ctx.getDiagHandlerPtr()->isPassedOptRemarkEnabled(getPassName()); 264296417Sdim} 265296417Sdim 266296417SdimOptimizationRemarkMissed::OptimizationRemarkMissed( 267296417Sdim const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc, 268296417Sdim const Value *CodeRegion) 269296417Sdim : DiagnosticInfoIROptimization( 270296417Sdim DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName, 271296417Sdim *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {} 272296417Sdim 273296417SdimOptimizationRemarkMissed::OptimizationRemarkMissed(const char *PassName, 274296417Sdim StringRef RemarkName, 275296417Sdim const Instruction *Inst) 276296417Sdim : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark, 277296417Sdim PassName, RemarkName, 278296417Sdim *Inst->getParent()->getParent(), 279296417Sdim Inst->getDebugLoc(), Inst->getParent()) {} 280296417Sdim 281296417Sdimbool OptimizationRemarkMissed::isEnabled() const { 282239462Sdim const Function &Fn = getFunction(); 283239462Sdim LLVMContext &Ctx = Fn.getContext(); 284239462Sdim return Ctx.getDiagHandlerPtr()->isMissedOptRemarkEnabled(getPassName()); 285239462Sdim} 286239462Sdim 287239462SdimOptimizationRemarkAnalysis::OptimizationRemarkAnalysis( 288239462Sdim const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc, 289327952Sdim const Value *CodeRegion) 290239462Sdim : DiagnosticInfoIROptimization( 291239462Sdim DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName, 292239462Sdim *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {} 293239462Sdim 294239462SdimOptimizationRemarkAnalysis::OptimizationRemarkAnalysis(const char *PassName, 295239462Sdim StringRef RemarkName, 296239462Sdim const Instruction *Inst) 297239462Sdim : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark, 298309124Sdim PassName, RemarkName, 299193323Sed *Inst->getParent()->getParent(), 300341825Sdim Inst->getDebugLoc(), Inst->getParent()) {} 301341825Sdim 302341825SdimOptimizationRemarkAnalysis::OptimizationRemarkAnalysis( 303341825Sdim enum DiagnosticKind Kind, const char *PassName, StringRef RemarkName, 304341825Sdim const DiagnosticLocation &Loc, const Value *CodeRegion) 305249423Sdim : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, RemarkName, 306249423Sdim *cast<BasicBlock>(CodeRegion)->getParent(), 307309124Sdim Loc, CodeRegion) {} 308309124Sdim 309309124Sdimbool OptimizationRemarkAnalysis::isEnabled() const { 310309124Sdim const Function &Fn = getFunction(); 311193323Sed LLVMContext &Ctx = Fn.getContext(); 312193323Sed return Ctx.getDiagHandlerPtr()->isAnalysisRemarkEnabled(getPassName()) || 313193323Sed shouldAlwaysPrint(); 314193323Sed} 315193323Sed 316321369Sdimvoid DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const { 317341825Sdim DP << Diagnostic; 318321369Sdim} 319321369Sdim 320321369SdimDiagnosticInfoOptimizationFailure::DiagnosticInfoOptimizationFailure( 321341825Sdim const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc, 322321369Sdim const Value *CodeRegion) 323321369Sdim : DiagnosticInfoIROptimization( 324321369Sdim DK_OptimizationFailure, DS_Warning, PassName, RemarkName, 325321369Sdim *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {} 326321369Sdim 327321369Sdimbool DiagnosticInfoOptimizationFailure::isEnabled() const { 328321369Sdim // Only print warnings. 329321369Sdim return getSeverity() == DS_Warning; 330321369Sdim} 331321369Sdim 332360784Sdimvoid DiagnosticInfoUnsupported::print(DiagnosticPrinter &DP) const { 333321369Sdim std::string Str; 334321369Sdim raw_string_ostream OS(Str); 335353358Sdim 336353358Sdim OS << getLocationStr() << ": in function " << getFunction().getName() << ' ' 337353358Sdim << *getFunction().getFunctionType() << ": " << Msg << '\n'; 338360784Sdim OS.flush(); 339353358Sdim DP << Str; 340353358Sdim} 341353358Sdim 342353358Sdimvoid DiagnosticInfoISelFallback::print(DiagnosticPrinter &DP) const { 343353358Sdim DP << "Instruction selection used fallback path for " << getFunction(); 344353358Sdim} 345353358Sdim 346353358Sdimvoid DiagnosticInfoOptimizationBase::insert(StringRef S) { 347321369Sdim Args.emplace_back(S); 348321369Sdim} 349321369Sdim 350321369Sdimvoid DiagnosticInfoOptimizationBase::insert(Argument A) { 351321369Sdim Args.push_back(std::move(A)); 352309124Sdim} 353193323Sed 354341825Sdimvoid DiagnosticInfoOptimizationBase::insert(setIsVerbose V) { 355341825Sdim IsVerbose = true; 356341825Sdim} 357341825Sdim 358341825Sdimvoid DiagnosticInfoOptimizationBase::insert(setExtraArgs EA) { 359309124Sdim FirstExtraArgIndex = Args.size(); 360309124Sdim} 361309124Sdim 362309124Sdimstd::string DiagnosticInfoOptimizationBase::getMsg() const { 363193323Sed std::string Str; 364193323Sed raw_string_ostream OS(Str); 365193323Sed for (const DiagnosticInfoOptimizationBase::Argument &Arg : 366193323Sed make_range(Args.begin(), FirstExtraArgIndex == -1 367193323Sed ? Args.end() 368309124Sdim : Args.begin() + FirstExtraArgIndex)) 369296417Sdim OS << Arg.Val; 370296417Sdim return OS.str(); 371309124Sdim} 372193323Sed 373193323SedDiagnosticInfoMisExpect::DiagnosticInfoMisExpect(const Instruction *Inst, 374360784Sdim Twine &Msg) 375296417Sdim : DiagnosticInfoWithLocationBase(DK_MisExpect, DS_Warning, 376280031Sdim *Inst->getParent()->getParent(), 377280031Sdim Inst->getDebugLoc()), 378280031Sdim Msg(Msg) {} 379280031Sdim 380218893Sdimvoid DiagnosticInfoMisExpect::print(DiagnosticPrinter &DP) const { 381193323Sed DP << getLocationStr() << ": " << getMsg(); 382309124Sdim} 383276479Sdim 384218893Sdimvoid OptimizationRemarkAnalysisFPCommute::anchor() {} 385193323Sedvoid OptimizationRemarkAnalysisAliasing::anchor() {} 386193323Sed