LLVM 20.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"
28#include "llvm/IR/LLVMContext.h"
29#include "llvm/IR/Metadata.h"
30#include "llvm/IR/Module.h"
31#include "llvm/IR/Type.h"
32#include "llvm/IR/Value.h"
36#include "llvm/Support/Path.h"
39#include <atomic>
40#include <string>
41
42using namespace llvm;
43
45 static std::atomic<int> PluginKindID(DK_FirstPluginKind);
46 return ++PluginKindID;
47}
48
50
52 const Twine &MsgStr,
53 DiagnosticSeverity Severity)
54 : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr), Instr(&I) {
55 if (const MDNode *SrcLoc = I.getMetadata("srcloc")) {
56 if (SrcLoc->getNumOperands() != 0)
57 if (const auto *CI =
58 mdconst::dyn_extract<ConstantInt>(SrcLoc->getOperand(0)))
59 LocCookie = CI->getZExtValue();
60 }
61}
62
64 DP << getMsgStr();
65 if (getLocCookie())
66 DP << " at line " << getLocCookie();
67}
68
70 const Function &Fn, const char *ResourceName, uint64_t ResourceSize,
71 uint64_t ResourceLimit, DiagnosticSeverity Severity, DiagnosticKind Kind)
72 : DiagnosticInfoWithLocationBase(Kind, Severity, Fn, Fn.getSubprogram()),
73 Fn(Fn), ResourceName(ResourceName), ResourceSize(ResourceSize),
74 ResourceLimit(ResourceLimit) {}
75
77 DP << getLocationStr() << ": " << getResourceName() << " ("
78 << getResourceSize() << ") exceeds limit (" << getResourceLimit()
79 << ") in function '" << getFunction() << '\'';
80}
81
83 DP << "ignoring debug info with an invalid version (" << getMetadataVersion()
84 << ") in " << getModule();
85}
86
88 DiagnosticPrinter &DP) const {
89 DP << "ignoring invalid debug info in " << getModule().getModuleIdentifier();
90}
91
93 if (!FileName.empty()) {
94 DP << getFileName();
95 if (LineNum > 0)
96 DP << ":" << getLineNum();
97 DP << ": ";
98 }
99 DP << getMsg();
100}
101
103 if (getFileName())
104 DP << getFileName() << ": ";
105 DP << getMsg();
106}
107
108void DiagnosticInfo::anchor() {}
109void DiagnosticInfoStackSize::anchor() {}
110void DiagnosticInfoWithLocationBase::anchor() {}
111void DiagnosticInfoIROptimization::anchor() {}
112
114 if (!DL)
115 return;
116 File = DL->getFile();
117 Line = DL->getLine();
118 Column = DL->getColumn();
119}
120
122 if (!SP)
123 return;
124
125 File = SP->getFile();
126 Line = SP->getScopeLine();
127 Column = 0;
128}
129
131 return File->getFilename();
132}
133
135 StringRef Name = File->getFilename();
137 return std::string(Name);
138
139 SmallString<128> Path;
140 sys::path::append(Path, File->getDirectory(), Name);
142}
143
145 return Loc.getAbsolutePath();
146}
147
149 unsigned &Line,
150 unsigned &Column) const {
151 RelativePath = Loc.getRelativePath();
152 Line = Loc.getLine();
153 Column = Loc.getColumn();
154}
155
157 StringRef Filename("<unknown>");
158 unsigned Line = 0;
159 unsigned Column = 0;
161 getLocation(Filename, Line, Column);
162 return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
163}
164
166 const Value *V)
167 : Key(std::string(Key)) {
168 if (auto *F = dyn_cast<Function>(V)) {
169 if (DISubprogram *SP = F->getSubprogram())
170 Loc = SP;
171 }
172 else if (auto *I = dyn_cast<Instruction>(V))
173 Loc = I->getDebugLoc();
174
175 // Only include names that correspond to user variables. FIXME: We should use
176 // debug info if available to get the name of the user variable.
177 if (isa<llvm::Argument>(V) || isa<GlobalValue>(V))
178 Val = std::string(GlobalValue::dropLLVMManglingEscape(V->getName()));
179 else if (isa<Constant>(V)) {
181 V->printAsOperand(OS, /*PrintType=*/false);
182 } else if (auto *I = dyn_cast<Instruction>(V)) {
183 Val = I->getOpcodeName();
184 } else if (auto *MD = dyn_cast<MetadataAsValue>(V)) {
185 if (auto *S = dyn_cast<MDString>(MD->getMetadata()))
186 Val = S->getString();
187 }
188}
189
191 : Key(std::string(Key)) {
193 OS << *T;
194}
195
197 : Key(std::string(Key)), Val(S.str()) {}
198
200 : Key(std::string(Key)), Val(itostr(N)) {}
201
203 : Key(std::string(Key)), Val(llvm::to_string(N)) {}
204
206 : Key(std::string(Key)), Val(itostr(N)) {}
207
209 : Key(std::string(Key)), Val(itostr(N)) {}
210
212 : Key(std::string(Key)), Val(utostr(N)) {}
213
215 unsigned long N)
216 : Key(std::string(Key)), Val(utostr(N)) {}
217
219 unsigned long long N)
220 : Key(std::string(Key)), Val(utostr(N)) {}
221
223 ElementCount EC)
224 : Key(std::string(Key)) {
226 EC.print(OS);
227}
228
231 : Key(std::string(Key)) {
233 C.print(OS);
234}
235
237 : Key(std::string(Key)), Loc(Loc) {
238 if (Loc) {
239 Val = (Loc->getFilename() + ":" + Twine(Loc.getLine()) + ":" +
240 Twine(Loc.getCol())).str();
241 } else {
242 Val = "<UNKNOWN LOCATION>";
243 }
244}
245
247 DP << getLocationStr() << ": " << getMsg();
248 if (Hotness)
249 DP << " (hotness: " << *Hotness << ")";
250}
251
254 const DiagnosticLocation &Loc,
255 const Value *CodeRegion)
258 *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
259
261 StringRef RemarkName,
262 const Instruction *Inst)
264 RemarkName, *Inst->getParent()->getParent(),
265 Inst->getDebugLoc(), Inst->getParent()) {}
266
267static const BasicBlock *getFirstFunctionBlock(const Function *Func) {
268 return Func->empty() ? nullptr : &Func->front();
269}
270
272 StringRef RemarkName,
273 const Function *Func)
275 RemarkName, *Func, Func->getSubprogram(),
276 getFirstFunctionBlock(Func)) {}
277
279 const Function &Fn = getFunction();
280 LLVMContext &Ctx = Fn.getContext();
282}
283
285 const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
286 const Value *CodeRegion)
289 *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
290
292 StringRef RemarkName,
293 const Instruction *Inst)
295 PassName, RemarkName,
296 *Inst->getParent()->getParent(),
297 Inst->getDebugLoc(), Inst->getParent()) {}
298
300 StringRef RemarkName,
301 const Function *Func)
304 Func->getSubprogram(), getFirstFunctionBlock(Func)) {}
305
307 const Function &Fn = getFunction();
308 LLVMContext &Ctx = Fn.getContext();
310}
311
313 const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
314 const Value *CodeRegion)
317 *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
318
320 StringRef RemarkName,
321 const Instruction *Inst)
323 PassName, RemarkName,
324 *Inst->getParent()->getParent(),
325 Inst->getDebugLoc(), Inst->getParent()) {}
326
328 enum DiagnosticKind Kind, const char *PassName, StringRef RemarkName,
329 const DiagnosticLocation &Loc, const Value *CodeRegion)
331 *cast<BasicBlock>(CodeRegion)->getParent(),
332 Loc, CodeRegion) {}
333
335 StringRef RemarkName,
336 const Function *Func)
339 Func->getSubprogram(), getFirstFunctionBlock(Func)) {}
340
342 const Function &Fn = getFunction();
343 LLVMContext &Ctx = Fn.getContext();
346}
347
349 DP << Diagnostic;
350}
351
353 DP << Diagnostic;
354}
355
357 const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
358 const Value *CodeRegion)
361 *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
362
364 // Only print warnings.
365 return getSeverity() == DS_Warning;
366}
367
369 std::string Str;
371
372 OS << getLocationStr() << ": in function " << getFunction().getName() << ' '
373 << *getFunction().getFunctionType() << ": " << Msg << '\n';
374 OS.flush();
375 DP << Str;
376}
377
379 DP << "Instruction selection used fallback path for " << getFunction();
380}
381
383 Args.emplace_back(S);
384}
385
387 Args.push_back(std::move(A));
388}
389
391 IsVerbose = true;
392}
393
395 FirstExtraArgIndex = Args.size();
396}
397
399 std::string Str;
402 make_range(Args.begin(), FirstExtraArgIndex == -1
403 ? Args.end()
404 : Args.begin() + FirstExtraArgIndex))
405 OS << Arg.Val;
406 return Str;
407}
408
410 Twine &Msg)
412 *Inst->getParent()->getParent(),
413 Inst->getDebugLoc()),
414 Msg(Msg) {}
415
417 DP << getLocationStr() << ": " << getMsg();
418}
419
420void OptimizationRemarkAnalysisFPCommute::anchor() {}
421void OptimizationRemarkAnalysisAliasing::anchor() {}
422
424 const auto *F =
425 dyn_cast<Function>(CI.getCalledOperand()->stripPointerCasts());
426
427 if (!F)
428 return;
429
430 for (int i = 0; i != 2; ++i) {
431 auto AttrName = i == 0 ? "dontcall-error" : "dontcall-warn";
432 auto Sev = i == 0 ? DS_Error : DS_Warning;
433
434 if (F->hasFnAttribute(AttrName)) {
435 uint64_t LocCookie = 0;
436 auto A = F->getFnAttribute(AttrName);
437 if (MDNode *MD = CI.getMetadata("srcloc"))
438 LocCookie =
439 mdconst::extract<ConstantInt>(MD->getOperand(0))->getZExtValue();
440 DiagnosticInfoDontCall D(F->getName(), A.getValueAsString(), Sev,
441 LocCookie);
442 F->getContext().diagnose(D);
443 }
444 }
445}
446
448 DP << "call to " << demangle(getFunctionName()) << " marked \"dontcall-";
450 DP << "error\"";
451 else
452 DP << "warn\"";
453 if (!getNote().empty())
454 DP << ": " << getNote();
455}
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:849
static const BasicBlock * getFirstFunctionBlock(const Function *Func)
std::string Name
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.
Module.h This file contains the declarations for the Module class.
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:61
Value * getCalledOperand() const
Definition: InstrTypes.h:1458
This class represents a function call, abstracting a target machine's calling convention.
StringRef getFilename() const
DIFile * getFile() const
StringRef getDirectory() const
Subprogram description.
A debug info location.
Definition: DebugLoc.h:33
void print(DiagnosticPrinter &DP) const override
StringRef getFunctionName() const
void print(DiagnosticPrinter &DP) const override
Print using the given DP a user-friendly message.
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(const Twine &MsgStr, DiagnosticSeverity Severity=DS_Error)
MsgStr is the message to be reported to the frontend.
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.
const Twine & getMsg() const
void print(DiagnosticPrinter &DP) const override
DiagnosticInfoMisExpect(const Instruction *Inst, Twine &Msg)
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, camel-case).
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
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
std::string getAbsolutePath() const
Return the full path to the file.
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:214
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition: Function.cpp:380
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
Definition: GlobalValue.h:567
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
Definition: Instruction.h:381
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
const DiagnosticHandler * getDiagHandlerPtr() const
getDiagHandlerPtr - Returns const raw pointer of DiagnosticHandler set by setDiagnosticHandler.
Metadata node.
Definition: Metadata.h:1069
const std::string & getModuleIdentifier() const
Get the module identifier which is, essentially, the name of the module.
Definition: Module.h:265
OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc, const Value *CodeRegion)
PassName is the name of the pass emitting this diagnostic.
OptimizationRemarkMissed(const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc, const Value *CodeRegion)
PassName is the name of the pass emitting this diagnostic.
bool isEnabled() const override
bool isEnabled() const override
OptimizationRemark(const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc, const Value *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:50
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:215
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
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:74
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition: Value.cpp:694
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:309
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:661
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
bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
Definition: Path.cpp:672
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:457
StringRef remove_leading_dotslash(StringRef path, Style style=Style::native)
Remove redundant leading "./" pieces and consecutive separators.
Definition: Path.cpp:704
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
std::string to_string(const T &Value)
Definition: ScopedPrinter.h:85
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
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
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition: Casting.h:565
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:858
#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.