LLVM 23.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/Intrinsics.h"
30#include "llvm/IR/LLVMContext.h"
31#include "llvm/IR/Metadata.h"
32#include "llvm/IR/Module.h"
33#include "llvm/IR/Type.h"
34#include "llvm/IR/Value.h"
38#include "llvm/Support/Path.h"
41#include <atomic>
42#include <string>
43
44using namespace llvm;
45
47 static std::atomic<int> PluginKindID(DK_FirstPluginKind);
48 return ++PluginKindID;
49}
50
52
56
60
62 const Twine &MsgStr,
63 DiagnosticSeverity Severity)
64 : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie),
65 MsgStr(MsgStr) {}
66
68 const Twine &MsgStr,
69 DiagnosticSeverity Severity)
70 : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr), Instr(&I) {
71 if (const MDNode *SrcLoc = I.getMetadata("srcloc")) {
72 if (SrcLoc->getNumOperands() != 0)
73 if (const auto *CI =
74 mdconst::dyn_extract<ConstantInt>(SrcLoc->getOperand(0)))
75 LocCookie = CI->getZExtValue();
76 }
77}
78
80 DP << getMsgStr();
81 if (getLocCookie())
82 DP << " at line " << getLocCookie();
83}
84
88
95
101
103 DP << getLocationStr() << ": " << MsgStr << " in function '" << getFunction()
104 << '\'';
105}
106
108 const Function &Fn, const Twine &ResourceName, uint64_t ResourceSize,
109 uint64_t ResourceLimit, DiagnosticSeverity Severity, DiagnosticKind Kind)
110 : DiagnosticInfoWithLocationBase(Kind, Severity, Fn, Fn.getSubprogram()),
111 Fn(Fn), ResourceName(ResourceName), ResourceSize(ResourceSize),
112 ResourceLimit(ResourceLimit) {}
113
115 DP << getLocationStr() << ": " << getResourceName() << " ("
116 << getResourceSize() << ") exceeds limit (" << getResourceLimit()
117 << ") in function '" << getFunction() << '\'';
118}
119
121 DP << "ignoring debug info with an invalid version (" << getMetadataVersion()
122 << ") in " << getModule();
123}
124
126 DiagnosticPrinter &DP) const {
127 DP << "ignoring invalid debug info in " << getModule().getModuleIdentifier();
128}
129
131 if (!FileName.empty()) {
132 DP << getFileName();
133 if (LineNum > 0)
134 DP << ":" << getLineNum();
135 DP << ": ";
136 }
137 DP << getMsg();
138}
139
141 if (getFileName())
142 DP << getFileName() << ": ";
143 DP << getMsg();
144}
145
146void DiagnosticInfo::anchor() {}
147void DiagnosticInfoStackSize::anchor() {}
148void DiagnosticInfoWithLocationBase::anchor() {}
149void DiagnosticInfoIROptimization::anchor() {}
150
152 if (!DL)
153 return;
154 File = DL->getFile();
155 Line = DL->getLine();
156 Column = DL->getColumn();
157}
158
160 if (!SP)
161 return;
162
163 File = SP->getFile();
164 Line = SP->getScopeLine();
165 Column = 0;
166}
167
169 return File->getFilename();
170}
171
173 StringRef Name = File->getFilename();
174 if (sys::path::is_absolute(Name))
175 return std::string(Name);
176
177 SmallString<128> Path;
178 sys::path::append(Path, File->getDirectory(), Name);
180}
181
183 return Loc.getAbsolutePath();
184}
185
187 unsigned &Line,
188 unsigned &Column) const {
189 RelativePath = Loc.getRelativePath();
190 Line = Loc.getLine();
191 Column = Loc.getColumn();
192}
193
195 StringRef Filename("<unknown>");
196 unsigned Line = 0;
197 unsigned Column = 0;
199 getLocation(Filename, Line, Column);
200 return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
201}
202
204 const Value *V)
205 : Key(std::string(Key)) {
206 if (auto *F = dyn_cast<Function>(V)) {
207 if (DISubprogram *SP = F->getSubprogram())
208 Loc = SP;
209 }
210 else if (auto *I = dyn_cast<Instruction>(V))
211 Loc = I->getDebugLoc();
212
213 // Only include names that correspond to user variables. FIXME: We should use
214 // debug info if available to get the name of the user variable.
216 Val = std::string(GlobalValue::dropLLVMManglingEscape(V->getName()));
217 else if (isa<Constant>(V)) {
219 V->printAsOperand(OS, /*PrintType=*/false);
220 } else if (auto *II = dyn_cast<IntrinsicInst>(V)) {
221 raw_string_ostream(Val) << "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
234
237
240
243
246
249
252
256
260
267
274
281
283 : Key(std::string(Key)), Loc(Loc) {
284 if (Loc) {
285 Val = (Loc->getFilename() + ":" + Twine(Loc.getLine()) + ":" +
286 Twine(Loc.getCol())).str();
287 } else {
288 Val = "<UNKNOWN LOCATION>";
289 }
290}
291
293 DP << getLocationStr() << ": " << getMsg();
294 if (Hotness)
295 DP << " (hotness: " << *Hotness << ")";
296}
297
305
312
313static const BasicBlock *getFirstFunctionBlock(const Function *Func) {
314 return Func->empty() ? nullptr : &Func->front();
315}
316
323
325 const Function &Fn = getFunction();
326 LLVMContext &Ctx = Fn.getContext();
328}
329
336
344
351
353 const Function &Fn = getFunction();
354 LLVMContext &Ctx = Fn.getContext();
356}
357
364
372
378
385
387 const Function &Fn = getFunction();
388 LLVMContext &Ctx = Fn.getContext();
391}
392
394 DP << Diagnostic;
395}
396
398 DP << Diagnostic;
399}
400
407
409 // Only print warnings.
410 return getSeverity() == DS_Warning;
411}
412
414 std::string Str;
415 raw_string_ostream(Str) << getLocationStr() << ": in function "
416 << getFunction().getName() << ' '
417 << *getFunction().getFunctionType() << ": " << Msg
418 << '\n';
419 DP << Str;
420}
421
424 unsigned IntrinsicID,
425 const DiagnosticLocation &Loc)
427 Fn, Loc),
428 IntrinsicID(IntrinsicID),
429 RequiredFeatures(Intrinsic::getRequiredTargetFeatures(
430 static_cast<Intrinsic::ID>(IntrinsicID))) {
431 assert(!RequiredFeatures.empty() &&
432 "intrinsic without required features should be supported");
433}
434
436 return (Twine(
437 Intrinsic::getBaseName(static_cast<Intrinsic::ID>(IntrinsicID))) +
438 " requires target feature '" + RequiredFeatures + "'")
439 .str();
440}
441
443 DiagnosticPrinter &DP) const {
444 std::string Str;
445 raw_string_ostream OS(Str);
446 OS << getLocationStr() << ": in function ";
447 getFunction().printAsOperand(OS, /*PrintType=*/false);
448 OS << ' ' << *getFunction().getFunctionType() << ": " << getMessage() << '\n';
449 DP << Str;
450}
451
453 DP << Msg;
454}
455
457 DP << "Instruction selection used fallback path for " << getFunction();
458}
459
461 Args.emplace_back(S);
462}
463
465 Args.push_back(std::move(A));
466}
467
471
475
477 std::string Str;
478 raw_string_ostream OS(Str);
480 make_range(Args.begin(), FirstExtraArgIndex == -1
481 ? Args.end()
482 : Args.begin() + FirstExtraArgIndex))
483 OS << Arg.Val;
484 return Str;
485}
486
493
495 DP << getLocationStr() << ": " << getMsg();
496}
497
498void OptimizationRemarkAnalysisFPCommute::anchor() {}
499void OptimizationRemarkAnalysisAliasing::anchor() {}
500
502 const auto *F =
504
505 if (!F)
506 return;
507
508 for (int i = 0; i != 2; ++i) {
509 auto AttrName = i == 0 ? "dontcall-error" : "dontcall-warn";
510 auto Sev = i == 0 ? DS_Error : DS_Warning;
511
512 if (F->hasFnAttribute(AttrName)) {
513 uint64_t LocCookie = 0;
514 auto A = F->getFnAttribute(AttrName);
515 if (MDNode *MD = CI.getMetadata("srcloc"))
516 LocCookie =
517 mdconst::extract<ConstantInt>(MD->getOperand(0))->getZExtValue();
518 MDNode *InlinedFromMD = CI.getMetadata("inlined.from");
519 DiagnosticInfoDontCall D(F->getName(), A.getValueAsString(), Sev,
520 LocCookie, InlinedFromMD);
521
522 if (const DebugLoc &DL = CI.getDebugLoc()) {
524 auto AddLocation = [&](const DILocation *Loc) {
525 if (auto *Scope = Loc->getScope())
526 if (auto *SP = Scope->getSubprogram())
527 DebugChain.push_back({SP->getName(), Loc->getFilename(),
528 Loc->getLine(), Loc->getColumn()});
529 };
530 if (const DILocation *Loc = DL.get()) {
531 AddLocation(Loc);
532 for (const DILocation *InlinedAt = Loc->getInlinedAt(); InlinedAt;
533 InlinedAt = InlinedAt->getInlinedAt())
534 AddLocation(InlinedAt);
535 }
536 D.setDebugInlineChain(std::move(DebugChain));
537 }
538
539 F->getContext().diagnose(D);
540 }
541 }
542}
543
545 DP << "call to " << demangle(getFunctionName()) << " marked \"dontcall-";
547 DP << "error\"";
548 else
549 DP << "warn\"";
550 if (!getNote().empty())
551 DP << ": " << getNote();
552}
553
557 if (!InlinedFromMD)
558 return Chain;
559
560 for (unsigned I = 0, E = InlinedFromMD->getNumOperands(); I + 1 < E; I += 2) {
561 auto *NameMD = dyn_cast<MDString>(InlinedFromMD->getOperand(I));
562 auto *LocMD =
563 mdconst::dyn_extract<ConstantInt>(InlinedFromMD->getOperand(I + 1));
564 if (NameMD && !NameMD->getString().empty())
565 Chain.emplace_back(NameMD->getString(),
566 LocMD ? LocMD->getZExtValue() : 0);
567 }
568 return Chain;
569}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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)
static const BasicBlock * getFirstFunctionBlock(const Function *Func)
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:54
#define I(x, y, z)
Definition MD5.cpp:57
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first DebugLoc that has line number information, given a range of instructions.
This file contains the declarations for metadata subclasses.
#define T
uint64_t IntrinsicInst * II
static constexpr StringLiteral Filename
#define P(N)
if(PassOpts->AAPipeline)
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
This file contains some functions that are useful when dealing with strings.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
Value * getCalledOperand() const
This class represents a function call, abstracting a target machine's calling convention.
Subprogram description. Uses SubclassData1.
A debug info location.
Definition DebugLoc.h:126
void print(DiagnosticPrinter &DP) const override
StringRef getFunctionName() const
void print(DiagnosticPrinter &DP) const override
Print using the given DP a user-friendly message.
SmallVector< std::pair< StringRef, uint64_t > > getInliningDecisions() const
void print(DiagnosticPrinter &DP) const override
const Twine & getMsgStr() const
void print(DiagnosticPrinter &DP) const override
DiagnosticInfoIROptimization(enum DiagnosticKind Kind, enum DiagnosticSeverity Severity, const char *PassName, StringRef RemarkName, const Function &Fn, const DiagnosticLocation &Loc, const BasicBlock *CodeRegion=nullptr)
PassName is the name of the pass emitting this diagnostic.
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 Twine & getResourceName() const
DiagnosticInfoResourceLimit(const Function &Fn, const Twine &ResourceName LLVM_LIFETIME_BOUND, 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.
DiagnosticInfoUnsupportedTargetIntrinsic(const Function &Fn, unsigned IntrinsicID, const DiagnosticLocation &Loc=DiagnosticLocation())
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.
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
DiagnosticInfoWithLocationBase(enum DiagnosticKind Kind, enum DiagnosticSeverity Severity, const Function &Fn, const DiagnosticLocation &Loc)
Fn is the function where the diagnostic is being emitted.
This is the base abstract class for diagnostic reporting in the backend.
DiagnosticSeverity getSeverity() 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.
Interface for custom diagnostic printing.
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition Function.h:211
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
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:1069
const std::string & getModuleIdentifier() const
Get the module identifier which is, essentially, the name of the module.
Definition Module.h:254
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
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::string str() const
Get the contents as an std::string.
Definition StringRef.h:222
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:46
LLVM Value Representation.
Definition Value.h:75
LLVM_ABI void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition Value.cpp:713
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:319
A raw_ostream that writes to an std::string.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
This namespace contains an enum with a value for every intrinsic/builtin function known by LLVM.
LLVM_ABI StringRef getBaseName(ID id)
Return the LLVM name for an intrinsic, without encoded types for overloading, such as "llvm....
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract(Y &&MD)
Extract a Value from Metadata, if any.
Definition Metadata.h:696
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
Definition Metadata.h:668
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:688
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:467
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI void diagnoseDontCall(const CallInst &CI)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
std::string utostr(uint64_t X, bool isNeg=false)
DiagnosticKind
Defines the different supported kind of a diagnostic.
@ DK_OptimizationRemarkAnalysis
@ DK_UnsupportedTargetIntrinsic
@ DK_OptimizationRemarkMissed
@ DK_OptimizationRemark
@ DK_InlineAsm
@ DK_OptimizationFailure
@ DK_MisExpect
@ DK_FirstPluginKind
@ DK_RegAllocFailure
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
const char * to_string(ThinOrFullLTOPhase Phase)
Definition Pass.cpp:306
LLVM_ABI int getNextAvailablePluginDiagnosticKind()
Get the next available kind ID for a plugin diagnostic.
DiagnosticSeverity
Defines the different supported severity of a diagnostic.
DEMANGLE_ABI std::string demangle(std::string_view MangledName)
Attempt to demangle a string using different demangling schemes.
Definition Demangle.cpp:21
std::string itostr(int64_t X)
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:860
#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.