Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/IR/DiagnosticInfo.cpp
35233 views
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
14
#include "llvm/IR/DiagnosticInfo.h"
15
#include "llvm/ADT/StringExtras.h"
16
#include "llvm/ADT/Twine.h"
17
#include "llvm/ADT/iterator_range.h"
18
#include "llvm/Demangle/Demangle.h"
19
#include "llvm/IR/BasicBlock.h"
20
#include "llvm/IR/Constants.h"
21
#include "llvm/IR/DebugInfoMetadata.h"
22
#include "llvm/IR/DerivedTypes.h"
23
#include "llvm/IR/DiagnosticPrinter.h"
24
#include "llvm/IR/Function.h"
25
#include "llvm/IR/GlobalValue.h"
26
#include "llvm/IR/Instruction.h"
27
#include "llvm/IR/Instructions.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"
33
#include "llvm/Support/Casting.h"
34
#include "llvm/Support/ErrorHandling.h"
35
#include "llvm/Support/InstructionCost.h"
36
#include "llvm/Support/Path.h"
37
#include "llvm/Support/ScopedPrinter.h"
38
#include "llvm/Support/raw_ostream.h"
39
#include <atomic>
40
#include <string>
41
42
using namespace llvm;
43
44
int llvm::getNextAvailablePluginDiagnosticKind() {
45
static std::atomic<int> PluginKindID(DK_FirstPluginKind);
46
return ++PluginKindID;
47
}
48
49
const char *OptimizationRemarkAnalysis::AlwaysPrint = "";
50
51
DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I,
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
63
void DiagnosticInfoInlineAsm::print(DiagnosticPrinter &DP) const {
64
DP << getMsgStr();
65
if (getLocCookie())
66
DP << " at line " << getLocCookie();
67
}
68
69
DiagnosticInfoResourceLimit::DiagnosticInfoResourceLimit(
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
76
void DiagnosticInfoResourceLimit::print(DiagnosticPrinter &DP) const {
77
DP << getLocationStr() << ": " << getResourceName() << " ("
78
<< getResourceSize() << ") exceeds limit (" << getResourceLimit()
79
<< ") in function '" << getFunction() << '\'';
80
}
81
82
void DiagnosticInfoDebugMetadataVersion::print(DiagnosticPrinter &DP) const {
83
DP << "ignoring debug info with an invalid version (" << getMetadataVersion()
84
<< ") in " << getModule();
85
}
86
87
void DiagnosticInfoIgnoringInvalidDebugMetadata::print(
88
DiagnosticPrinter &DP) const {
89
DP << "ignoring invalid debug info in " << getModule().getModuleIdentifier();
90
}
91
92
void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const {
93
if (!FileName.empty()) {
94
DP << getFileName();
95
if (LineNum > 0)
96
DP << ":" << getLineNum();
97
DP << ": ";
98
}
99
DP << getMsg();
100
}
101
102
void DiagnosticInfoPGOProfile::print(DiagnosticPrinter &DP) const {
103
if (getFileName())
104
DP << getFileName() << ": ";
105
DP << getMsg();
106
}
107
108
void DiagnosticInfo::anchor() {}
109
void DiagnosticInfoStackSize::anchor() {}
110
void DiagnosticInfoWithLocationBase::anchor() {}
111
void DiagnosticInfoIROptimization::anchor() {}
112
113
DiagnosticLocation::DiagnosticLocation(const DebugLoc &DL) {
114
if (!DL)
115
return;
116
File = DL->getFile();
117
Line = DL->getLine();
118
Column = DL->getColumn();
119
}
120
121
DiagnosticLocation::DiagnosticLocation(const DISubprogram *SP) {
122
if (!SP)
123
return;
124
125
File = SP->getFile();
126
Line = SP->getScopeLine();
127
Column = 0;
128
}
129
130
StringRef DiagnosticLocation::getRelativePath() const {
131
return File->getFilename();
132
}
133
134
std::string DiagnosticLocation::getAbsolutePath() const {
135
StringRef Name = File->getFilename();
136
if (sys::path::is_absolute(Name))
137
return std::string(Name);
138
139
SmallString<128> Path;
140
sys::path::append(Path, File->getDirectory(), Name);
141
return sys::path::remove_leading_dotslash(Path).str();
142
}
143
144
std::string DiagnosticInfoWithLocationBase::getAbsolutePath() const {
145
return Loc.getAbsolutePath();
146
}
147
148
void DiagnosticInfoWithLocationBase::getLocation(StringRef &RelativePath,
149
unsigned &Line,
150
unsigned &Column) const {
151
RelativePath = Loc.getRelativePath();
152
Line = Loc.getLine();
153
Column = Loc.getColumn();
154
}
155
156
std::string DiagnosticInfoWithLocationBase::getLocationStr() const {
157
StringRef Filename("<unknown>");
158
unsigned Line = 0;
159
unsigned Column = 0;
160
if (isLocationAvailable())
161
getLocation(Filename, Line, Column);
162
return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
163
}
164
165
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
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)) {
180
raw_string_ostream OS(Val);
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
190
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, const Type *T)
191
: Key(std::string(Key)) {
192
raw_string_ostream OS(Val);
193
OS << *T;
194
}
195
196
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, StringRef S)
197
: Key(std::string(Key)), Val(S.str()) {}
198
199
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, int N)
200
: Key(std::string(Key)), Val(itostr(N)) {}
201
202
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, float N)
203
: Key(std::string(Key)), Val(llvm::to_string(N)) {}
204
205
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, long N)
206
: Key(std::string(Key)), Val(itostr(N)) {}
207
208
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, long long N)
209
: Key(std::string(Key)), Val(itostr(N)) {}
210
211
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, unsigned N)
212
: Key(std::string(Key)), Val(utostr(N)) {}
213
214
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
215
unsigned long N)
216
: Key(std::string(Key)), Val(utostr(N)) {}
217
218
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
219
unsigned long long N)
220
: Key(std::string(Key)), Val(utostr(N)) {}
221
222
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
223
ElementCount EC)
224
: Key(std::string(Key)) {
225
raw_string_ostream OS(Val);
226
EC.print(OS);
227
}
228
229
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
230
InstructionCost C)
231
: Key(std::string(Key)) {
232
raw_string_ostream OS(Val);
233
C.print(OS);
234
}
235
236
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, DebugLoc Loc)
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
246
void DiagnosticInfoOptimizationBase::print(DiagnosticPrinter &DP) const {
247
DP << getLocationStr() << ": " << getMsg();
248
if (Hotness)
249
DP << " (hotness: " << *Hotness << ")";
250
}
251
252
OptimizationRemark::OptimizationRemark(const char *PassName,
253
StringRef RemarkName,
254
const DiagnosticLocation &Loc,
255
const Value *CodeRegion)
256
: DiagnosticInfoIROptimization(
257
DK_OptimizationRemark, DS_Remark, PassName, RemarkName,
258
*cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
259
260
OptimizationRemark::OptimizationRemark(const char *PassName,
261
StringRef RemarkName,
262
const Instruction *Inst)
263
: DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
264
RemarkName, *Inst->getParent()->getParent(),
265
Inst->getDebugLoc(), Inst->getParent()) {}
266
267
static const BasicBlock *getFirstFunctionBlock(const Function *Func) {
268
return Func->empty() ? nullptr : &Func->front();
269
}
270
271
OptimizationRemark::OptimizationRemark(const char *PassName,
272
StringRef RemarkName,
273
const Function *Func)
274
: DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
275
RemarkName, *Func, Func->getSubprogram(),
276
getFirstFunctionBlock(Func)) {}
277
278
bool OptimizationRemark::isEnabled() const {
279
const Function &Fn = getFunction();
280
LLVMContext &Ctx = Fn.getContext();
281
return Ctx.getDiagHandlerPtr()->isPassedOptRemarkEnabled(getPassName());
282
}
283
284
OptimizationRemarkMissed::OptimizationRemarkMissed(
285
const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
286
const Value *CodeRegion)
287
: DiagnosticInfoIROptimization(
288
DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName,
289
*cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
290
291
OptimizationRemarkMissed::OptimizationRemarkMissed(const char *PassName,
292
StringRef RemarkName,
293
const Instruction *Inst)
294
: DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
295
PassName, RemarkName,
296
*Inst->getParent()->getParent(),
297
Inst->getDebugLoc(), Inst->getParent()) {}
298
299
OptimizationRemarkMissed::OptimizationRemarkMissed(const char *PassName,
300
StringRef RemarkName,
301
const Function *Func)
302
: DiagnosticInfoIROptimization(
303
DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName, *Func,
304
Func->getSubprogram(), getFirstFunctionBlock(Func)) {}
305
306
bool OptimizationRemarkMissed::isEnabled() const {
307
const Function &Fn = getFunction();
308
LLVMContext &Ctx = Fn.getContext();
309
return Ctx.getDiagHandlerPtr()->isMissedOptRemarkEnabled(getPassName());
310
}
311
312
OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(
313
const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
314
const Value *CodeRegion)
315
: DiagnosticInfoIROptimization(
316
DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName,
317
*cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
318
319
OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(const char *PassName,
320
StringRef RemarkName,
321
const Instruction *Inst)
322
: DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
323
PassName, RemarkName,
324
*Inst->getParent()->getParent(),
325
Inst->getDebugLoc(), Inst->getParent()) {}
326
327
OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(
328
enum DiagnosticKind Kind, const char *PassName, StringRef RemarkName,
329
const DiagnosticLocation &Loc, const Value *CodeRegion)
330
: DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, RemarkName,
331
*cast<BasicBlock>(CodeRegion)->getParent(),
332
Loc, CodeRegion) {}
333
334
OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(const char *PassName,
335
StringRef RemarkName,
336
const Function *Func)
337
: DiagnosticInfoIROptimization(
338
DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName, *Func,
339
Func->getSubprogram(), getFirstFunctionBlock(Func)) {}
340
341
bool OptimizationRemarkAnalysis::isEnabled() const {
342
const Function &Fn = getFunction();
343
LLVMContext &Ctx = Fn.getContext();
344
return Ctx.getDiagHandlerPtr()->isAnalysisRemarkEnabled(getPassName()) ||
345
shouldAlwaysPrint();
346
}
347
348
void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const {
349
DP << Diagnostic;
350
}
351
352
void DiagnosticInfoSrcMgr::print(DiagnosticPrinter &DP) const {
353
DP << Diagnostic;
354
}
355
356
DiagnosticInfoOptimizationFailure::DiagnosticInfoOptimizationFailure(
357
const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
358
const Value *CodeRegion)
359
: DiagnosticInfoIROptimization(
360
DK_OptimizationFailure, DS_Warning, PassName, RemarkName,
361
*cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
362
363
bool DiagnosticInfoOptimizationFailure::isEnabled() const {
364
// Only print warnings.
365
return getSeverity() == DS_Warning;
366
}
367
368
void DiagnosticInfoUnsupported::print(DiagnosticPrinter &DP) const {
369
std::string Str;
370
raw_string_ostream OS(Str);
371
372
OS << getLocationStr() << ": in function " << getFunction().getName() << ' '
373
<< *getFunction().getFunctionType() << ": " << Msg << '\n';
374
OS.flush();
375
DP << Str;
376
}
377
378
void DiagnosticInfoISelFallback::print(DiagnosticPrinter &DP) const {
379
DP << "Instruction selection used fallback path for " << getFunction();
380
}
381
382
void DiagnosticInfoOptimizationBase::insert(StringRef S) {
383
Args.emplace_back(S);
384
}
385
386
void DiagnosticInfoOptimizationBase::insert(Argument A) {
387
Args.push_back(std::move(A));
388
}
389
390
void DiagnosticInfoOptimizationBase::insert(setIsVerbose V) {
391
IsVerbose = true;
392
}
393
394
void DiagnosticInfoOptimizationBase::insert(setExtraArgs EA) {
395
FirstExtraArgIndex = Args.size();
396
}
397
398
std::string DiagnosticInfoOptimizationBase::getMsg() const {
399
std::string Str;
400
raw_string_ostream OS(Str);
401
for (const DiagnosticInfoOptimizationBase::Argument &Arg :
402
make_range(Args.begin(), FirstExtraArgIndex == -1
403
? Args.end()
404
: Args.begin() + FirstExtraArgIndex))
405
OS << Arg.Val;
406
return Str;
407
}
408
409
DiagnosticInfoMisExpect::DiagnosticInfoMisExpect(const Instruction *Inst,
410
Twine &Msg)
411
: DiagnosticInfoWithLocationBase(DK_MisExpect, DS_Warning,
412
*Inst->getParent()->getParent(),
413
Inst->getDebugLoc()),
414
Msg(Msg) {}
415
416
void DiagnosticInfoMisExpect::print(DiagnosticPrinter &DP) const {
417
DP << getLocationStr() << ": " << getMsg();
418
}
419
420
void OptimizationRemarkAnalysisFPCommute::anchor() {}
421
void OptimizationRemarkAnalysisAliasing::anchor() {}
422
423
void llvm::diagnoseDontCall(const CallInst &CI) {
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
447
void DiagnosticInfoDontCall::print(DiagnosticPrinter &DP) const {
448
DP << "call to " << demangle(getFunctionName()) << " marked \"dontcall-";
449
if (getSeverity() == DiagnosticSeverity::DS_Error)
450
DP << "error\"";
451
else
452
DP << "warn\"";
453
if (!getNote().empty())
454
DP << ": " << getNote();
455
}
456
457