LLVM 22.0.0git
DiagnosticInfo.cpp
Go to the documentation of this file.
1//===- llvm/IR/DiagnosticInfo.cpp - Diagnostic Definitions ------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the different classes involved in low level diagnostics.
10//
11// Diagnostics reporting is still done as part of the LLVMContext.
12//===----------------------------------------------------------------------===//
13
16#include "llvm/ADT/Twine.h"
19#include "llvm/IR/BasicBlock.h"
20#include "llvm/IR/Constants.h"
24#include "llvm/IR/Function.h"
25#include "llvm/IR/GlobalValue.h"
26#include "llvm/IR/Instruction.h"
29#include "llvm/IR/LLVMContext.h"
30#include "llvm/IR/Metadata.h"
31#include "llvm/IR/Module.h"
32#include "llvm/IR/Type.h"
33#include "llvm/IR/Value.h"
37#include "llvm/Support/Path.h"
40#include <atomic>
41#include <string>
42
43using namespace llvm;
44
46 static std::atomic<int> PluginKindID(DK_FirstPluginKind);
47 return ++PluginKindID;
48}
49
51
53 DP << getMsgStr();
54}
55
57 DP << getLocationStr() << ": " << getMsgStr();
58}
59
61 const Twine &MsgStr,
62 DiagnosticSeverity Severity)
63 : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie),
64 MsgStr(MsgStr) {}
65
67 const Twine &MsgStr,
68 DiagnosticSeverity Severity)
69 : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr), Instr(&I) {
70 if (const MDNode *SrcLoc = I.getMetadata("srcloc")) {
71 if (SrcLoc->getNumOperands() != 0)
72 if (const auto *CI =
73 mdconst::dyn_extract<ConstantInt>(SrcLoc->getOperand(0)))
74 LocCookie = CI->getZExtValue();
75 }
76}
77
79 DP << getMsgStr();
80 if (getLocCookie())
81 DP << " at line " << getLocCookie();
82}
83
85 DP << getLocationStr() << ": " << getMsgStr();
86}
87
89 const Twine &MsgStr, const Function &Fn, const DiagnosticLocation &DL,
90 DiagnosticSeverity Severity)
92 DL.isValid() ? DL : Fn.getSubprogram()),
93 MsgStr(MsgStr) {}
94
96 const Twine &MsgStr, const Function &Fn, DiagnosticSeverity Severity)
98 Fn.getSubprogram()),
99 MsgStr(MsgStr) {}
100
102 DP << getLocationStr() << ": " << MsgStr << " in function '" << getFunction()
103 << '\'';
104}
105
107 const Function &Fn, const char *ResourceName, uint64_t ResourceSize,
108 uint64_t ResourceLimit, DiagnosticSeverity Severity, DiagnosticKind Kind)
109 : DiagnosticInfoWithLocationBase(Kind, Severity, Fn, Fn.getSubprogram()),
110 Fn(Fn), ResourceName(ResourceName), ResourceSize(ResourceSize),
111 ResourceLimit(ResourceLimit) {}
112
114 DP << getLocationStr() << ": " << getResourceName() << " ("
115 << getResourceSize() << ") exceeds limit (" << getResourceLimit()
116 << ") in function '" << getFunction() << '\'';
117}
118
120 DP << "ignoring debug info with an invalid version (" << getMetadataVersion()
121 << ") in " << getModule();
122}
123
125 DiagnosticPrinter &DP) const {
126 DP << "ignoring invalid debug info in " << getModule().getModuleIdentifier();
127}
128
130 if (!FileName.empty()) {
131 DP << getFileName();
132 if (LineNum > 0)
133 DP << ":" << getLineNum();
134 DP << ": ";
135 }
136 DP << getMsg();
137}
138
140 if (getFileName())
141 DP << getFileName() << ": ";
142 DP << getMsg();
143}
144
145void DiagnosticInfo::anchor() {}
146void DiagnosticInfoStackSize::anchor() {}
147void DiagnosticInfoWithLocationBase::anchor() {}
148void DiagnosticInfoIROptimization::anchor() {}
149
151 if (!DL)
152 return;
153 File = DL->getFile();
154 Line = DL->getLine();
155 Column = DL->getColumn();
156}
157
159 if (!SP)
160 return;
161
162 File = SP->getFile();
163 Line = SP->getScopeLine();
164 Column = 0;
165}
166
168 return File->getFilename();
169}
170
172 StringRef Name = File->getFilename();
174 return std::string(Name);
175
176 SmallString<128> Path;
177 sys::path::append(Path, File->getDirectory(), Name);
179}
180
182 return Loc.getAbsolutePath();
183}
184
186 unsigned &Line,
187 unsigned &Column) const {
188 RelativePath = Loc.getRelativePath();
189 Line = Loc.getLine();
190 Column = Loc.getColumn();
191}
192
194 StringRef Filename("<unknown>");
195 unsigned Line = 0;
196 unsigned Column = 0;
198 getLocation(Filename, Line, Column);
199 return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
200}
201
203 const Value *V)
204 : Key(std::string(Key)) {
205 if (auto *F = dyn_cast<Function>(V)) {
206 if (DISubprogram *SP = F->getSubprogram())
207 Loc = SP;
208 }
209 else if (auto *I = dyn_cast<Instruction>(V))
210 Loc = I->getDebugLoc();
211
212 // Only include names that correspond to user variables. FIXME: We should use
213 // debug info if available to get the name of the user variable.
214 if (isa<llvm::Argument>(V) || isa<GlobalValue>(V))
215 Val = std::string(GlobalValue::dropLLVMManglingEscape(V->getName()));
216 else if (isa<Constant>(V)) {
218 V->printAsOperand(OS, /*PrintType=*/false);
219 } else if (auto *II = dyn_cast<IntrinsicInst>(V)) {
221 OS << "call " << II->getCalledFunction()->getName();
222 } else if (auto *I = dyn_cast<Instruction>(V)) {
223 Val = I->getOpcodeName();
224 } else if (auto *MD = dyn_cast<MetadataAsValue>(V)) {
225 if (auto *S = dyn_cast<MDString>(MD->getMetadata()))
226 Val = S->getString();
227 }
228}
229
231 : Key(std::string(Key)) {
233 OS << *T;
234}
235
237 : Key(std::string(Key)), Val(S.str()) {}
238
240 : Key(std::string(Key)), Val(itostr(N)) {}
241
243 : Key(std::string(Key)), Val(llvm::to_string(N)) {}
244
246 : Key(std::string(Key)), Val(itostr(N)) {}
247
249 : Key(std::string(Key)), Val(itostr(N)) {}
250
252 : Key(std::string(Key)), Val(utostr(N)) {}
253
255 unsigned long N)
256 : Key(std::string(Key)), Val(utostr(N)) {}
257
259 unsigned long long N)
260 : Key(std::string(Key)), Val(utostr(N)) {}
261
263 ElementCount EC)
264 : Key(std::string(Key)) {
266 EC.print(OS);
267}
268
271 : Key(std::string(Key)) {
273 C.print(OS);
274}
275
277 : Key(std::string(Key)), Loc(Loc) {
278 if (Loc) {
279 Val = (Loc->getFilename() + ":" + Twine(Loc.getLine()) + ":" +
280 Twine(Loc.getCol())).str();
281 } else {
282 Val = "<UNKNOWN LOCATION>";
283 }
284}
285
287 DP << getLocationStr() << ": " << getMsg();
288 if (Hotness)
289 DP << " (hotness: " << *Hotness << ")";
290}
291
294 const DiagnosticLocation &Loc,
295 const BasicBlock *CodeRegion)
297 RemarkName, *CodeRegion->getParent(), Loc,
298 CodeRegion) {}
299
301 StringRef RemarkName,
302 const Instruction *Inst)
304 RemarkName, *Inst->getParent()->getParent(),
305 Inst->getDebugLoc(), Inst->getParent()) {}
306
307static const BasicBlock *getFirstFunctionBlock(const Function *Func) {
308 return Func->empty() ? nullptr : &Func->front();
309}
310
312 StringRef RemarkName,
313 const Function *Func)
315 RemarkName, *Func, Func->getSubprogram(),
316 getFirstFunctionBlock(Func)) {}
317
319 const Function &Fn = getFunction();
320 LLVMContext &Ctx = Fn.getContext();
322}
323
325 const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
326 const BasicBlock *CodeRegion)
328 PassName, RemarkName,
329 *CodeRegion->getParent(), Loc, CodeRegion) {}
330
332 StringRef RemarkName,
333 const Instruction *Inst)
335 PassName, RemarkName,
336 *Inst->getParent()->getParent(),
337 Inst->getDebugLoc(), Inst->getParent()) {}
338
340 StringRef RemarkName,
341 const Function *Func)
344 Func->getSubprogram(), getFirstFunctionBlock(Func)) {}
345
347 const Function &Fn = getFunction();
348 LLVMContext &Ctx = Fn.getContext();
350}
351
353 const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
354 const BasicBlock *CodeRegion)
356 PassName, RemarkName,
357 *CodeRegion->getParent(), Loc, CodeRegion) {}
358
360 StringRef RemarkName,
361 const Instruction *Inst)
363 PassName, RemarkName,
364 *Inst->getParent()->getParent(),
365 Inst->getDebugLoc(), Inst->getParent()) {}
366
368 enum DiagnosticKind Kind, const char *PassName, StringRef RemarkName,
369 const DiagnosticLocation &Loc, const BasicBlock *CodeRegion)
371 *CodeRegion->getParent(), Loc, CodeRegion) {}
372
374 StringRef RemarkName,
375 const Function *Func)
378 Func->getSubprogram(), getFirstFunctionBlock(Func)) {}
379
381 const Function &Fn = getFunction();
382 LLVMContext &Ctx = Fn.getContext();
385}
386
388 DP << Diagnostic;
389}
390
392 DP << Diagnostic;
393}
394
396 const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
397 const BasicBlock *CodeRegion)
399 RemarkName, *CodeRegion->getParent(), Loc,
400 CodeRegion) {}
401
403 // Only print warnings.
404 return getSeverity() == DS_Warning;
405}
406
408 std::string Str;
410
411 OS << getLocationStr() << ": in function " << getFunction().getName() << ' '
412 << *getFunction().getFunctionType() << ": " << Msg << '\n';
413 OS.flush();
414 DP << Str;
415}
416
418 DP << Msg;
419}
420
422 DP << "Instruction selection used fallback path for " << getFunction();
423}
424
426 Args.emplace_back(S);
427}
428
430 Args.push_back(std::move(A));
431}
432
434 IsVerbose = true;
435}
436
438 FirstExtraArgIndex = Args.size();
439}
440
442 std::string Str;
445 make_range(Args.begin(), FirstExtraArgIndex == -1
446 ? Args.end()
447 : Args.begin() + FirstExtraArgIndex))
448 OS << Arg.Val;
449 return Str;
450}
451
453 const Twine &Msg)
455 *Inst->getParent()->getParent(),
456 Inst->getDebugLoc()),
457 Msg(Msg) {}
458
460 DP << getLocationStr() << ": " << getMsg();
461}
462
463void OptimizationRemarkAnalysisFPCommute::anchor() {}
464void OptimizationRemarkAnalysisAliasing::anchor() {}
465
467 const auto *F =
468 dyn_cast<Function>(CI.getCalledOperand()->stripPointerCasts());
469
470 if (!F)
471 return;
472
473 for (int i = 0; i != 2; ++i) {
474 auto AttrName = i == 0 ? "dontcall-error" : "dontcall-warn";
475 auto Sev = i == 0 ? DS_Error : DS_Warning;
476
477 if (F->hasFnAttribute(AttrName)) {
478 uint64_t LocCookie = 0;
479 auto A = F->getFnAttribute(AttrName);
480 if (MDNode *MD = CI.getMetadata("srcloc"))
481 LocCookie =
482 mdconst::extract<ConstantInt>(MD->getOperand(0))->getZExtValue();
483 DiagnosticInfoDontCall D(F->getName(), A.getValueAsString(), Sev,
484 LocCookie);
485 F->getContext().diagnose(D);
486 }
487 }
488}
489
491 DP << "call to " << demangle(getFunctionName()) << " marked \"dontcall-";
493 DP << "error\"";
494 else
495 DP << "warn\"";
496 if (!getNote().empty())
497 DP << ": " << getNote();
498}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static const Function * getParent(const Value *V)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static DISubprogram * getSubprogram(bool IsDistinct, Ts &&...Args)
Definition: DIBuilder.cpp:971
static const BasicBlock * getFirstFunctionBlock(const Function *Func)
std::string Name
Module.h This file contains the declarations for the Module class.
This file defines an InstructionCost class that is used when calculating the cost of an instruction,...
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first found DebugLoc that has a DILocation, given a range of instructions.
This file contains the declarations for metadata subclasses.
uint64_t IntrinsicInst * II
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
raw_pwrite_stream & OS
This file contains some functions that are useful when dealing with strings.
static const char PassName[]
LLVM Basic Block Representation.
Definition: BasicBlock.h:62
Value * getCalledOperand() const
Definition: InstrTypes.h:1340
This class represents a function call, abstracting a target machine's calling convention.
StringRef getFilename() const
StringRef getDirectory() const
Subprogram description. Uses SubclassData1.
A debug info location.
Definition: DebugLoc.h:124
void print(DiagnosticPrinter &DP) const override
StringRef getFunctionName() const
void print(DiagnosticPrinter &DP) const override
Print using the given DP a user-friendly message.
void print(DiagnosticPrinter &DP) const override
const Twine & getMsgStr() const
void print(DiagnosticPrinter &DP) const override
Common features for diagnostics dealing with optimization remarks that are used by IR passes.
const Function & getFunction() const
void print(DiagnosticPrinter &DP) const override
Print using the given DP a user-friendly message.
void print(DiagnosticPrinter &DP) const override
DiagnosticInfoInlineAsm(uint64_t LocCookie, const Twine &MsgStr LLVM_LIFETIME_BOUND, DiagnosticSeverity Severity=DS_Error)
LocCookie if non-zero gives the line number for this report.
const Twine & getMsgStr() const
void print(DiagnosticPrinter &DP) const override
void print(DiagnosticPrinter &DP) const override
Print using the given DP a user-friendly message.
void print(DiagnosticPrinter &DP) const override
Print using the given DP a user-friendly message.
void print(DiagnosticPrinter &DP) const override
Print using the given DP a user-friendly message.
const Twine & getMsg() const
void print(DiagnosticPrinter &DP) const override
DiagnosticInfoMisExpect(const Instruction *Inst, const Twine &Msg LLVM_LIFETIME_BOUND)
int FirstExtraArgIndex
If positive, the index of the first argument that only appear in the optimization records and not in ...
const char * PassName
Name of the pass that triggers this report.
StringRef RemarkName
Textual identifier for the remark (single-word, CamelCase).
void print(DiagnosticPrinter &DP) const override
bool IsVerbose
The remark is expected to be noisy.
std::optional< uint64_t > Hotness
If profile information is available, this is the number of times the corresponding code was executed ...
SmallVector< Argument, 4 > Args
Arguments collected via the streaming interface.
DiagnosticInfoOptimizationFailure(const Function &Fn, const DiagnosticLocation &Loc, const Twine &Msg)
Fn is the function where the diagnostic is being emitted.
const char * getFileName() const
void print(DiagnosticPrinter &DP) const override
const Twine & getMsg() const
DiagnosticInfoRegAllocFailure(const Twine &MsgStr, const Function &Fn, const DiagnosticLocation &DL, DiagnosticSeverity Severity=DS_Error)
MsgStr is the message to be reported to the frontend.
void print(DiagnosticPrinter &DP) const override
const Function & getFunction() const
void print(DiagnosticPrinter &DP) const override
const char * getResourceName() const
DiagnosticInfoResourceLimit(const Function &Fn, const char *ResourceName, uint64_t ResourceSize, uint64_t ResourceLimit, DiagnosticSeverity Severity=DS_Warning, DiagnosticKind Kind=DK_ResourceLimit)
The function that is concerned by this stack size diagnostic.
void print(DiagnosticPrinter &DP) const override
void print(DiagnosticPrinter &DP) const override
Print using the given DP a user-friendly message.
void print(DiagnosticPrinter &DP) const override
Print using the given DP a user-friendly message.
Common features for diagnostics with an associated location.
std::string getLocationStr() const
Return a string with the location information for this diagnostic in the format "file:line:col".
std::string getAbsolutePath() const
Return the absolute path tot the file.
bool isLocationAvailable() const
Return true if location information is available for this diagnostic.
const Function & getFunction() const
DiagnosticLocation getLocation() const
This is the base abstract class for diagnostic reporting in the backend.
DiagnosticSeverity getSeverity() const
unsigned getLine() const
LLVM_ABI std::string getAbsolutePath() const
Return the full path to the file.
LLVM_ABI StringRef getRelativePath() const
Return the file name relative to the compilation directory.
unsigned getColumn() const
Interface for custom diagnostic printing.
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition: Function.h:209
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition: Function.cpp:359
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
Definition: GlobalValue.h:569
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
Definition: Instruction.h:428
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
LLVM_ABI const DiagnosticHandler * getDiagHandlerPtr() const
getDiagHandlerPtr - Returns const raw pointer of DiagnosticHandler set by setDiagnosticHandler.
Metadata node.
Definition: Metadata.h:1077
const std::string & getModuleIdentifier() const
Get the module identifier which is, essentially, the name of the module.
Definition: Module.h:252
OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc, const BasicBlock *CodeRegion)
PassName is the name of the pass emitting this diagnostic.
bool isEnabled() const override
OptimizationRemarkMissed(const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc, const BasicBlock *CodeRegion)
PassName is the name of the pass emitting this diagnostic.
bool isEnabled() const override
OptimizationRemark(const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc, const BasicBlock *CodeRegion)
PassName is the name of the pass emitting this diagnostic.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:233
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:151
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM Value Representation.
Definition: Value.h:75
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition: Value.cpp:701
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:322
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:662
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
LLVM_ABI StringRef remove_leading_dotslash(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Remove redundant leading "./" pieces and consecutive separators.
LLVM_ABI bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
Definition: Path.cpp:671
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:456
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
LLVM_ABI void diagnoseDontCall(const CallInst &CI)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
DiagnosticKind
Defines the different supported kind of a diagnostic.
@ DK_OptimizationRemarkAnalysis
@ DK_OptimizationRemarkMissed
@ DK_OptimizationRemark
@ DK_InlineAsm
@ DK_OptimizationFailure
@ DK_MisExpect
@ DK_FirstPluginKind
@ DK_RegAllocFailure
const char * to_string(ThinOrFullLTOPhase Phase)
Definition: Pass.cpp:301
LLVM_ABI int getNextAvailablePluginDiagnosticKind()
Get the next available kind ID for a plugin diagnostic.
DiagnosticSeverity
Defines the different supported severity of a diagnostic.
@ DS_Remark
@ DS_Warning
@ DS_Error
DEMANGLE_ABI std::string demangle(std::string_view MangledName)
Attempt to demangle a string using different demangling schemes.
Definition: Demangle.cpp:20
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:856
#define N
virtual bool isPassedOptRemarkEnabled(StringRef PassName) const
Return true if passed optimization remarks are enabled, override to provide different implementation.
virtual bool isAnalysisRemarkEnabled(StringRef PassName) const
Return true if analysis remarks are enabled, override to provide different implementation.
virtual bool isMissedOptRemarkEnabled(StringRef PassName) const
Return true if missed optimization remarks are enabled, override to provide different implementation.
Used in the streaming interface as the general argument type.
When an instance of this is inserted into the stream, the arguments following will not appear in the ...
Used to set IsVerbose via the stream interface.