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