1 //===- llvm/IR/DiagnosticInfo.h - Diagnostic Declaration --------*- 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 declares the different classes involved in low level diagnostics.
10 //
11 // Diagnostics reporting is still done as part of the LLVMContext.
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_IR_DIAGNOSTICINFO_H
15 #define LLVM_IR_DIAGNOSTICINFO_H
16
17 #include "llvm-c/Types.h"
18 #include "llvm/ADT/ArrayRef.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/ADT/Twine.h"
22 #include "llvm/IR/DebugLoc.h"
23 #include "llvm/Support/CBindingWrapping.h"
24 #include "llvm/Support/Compiler.h"
25 #include "llvm/Support/ErrorHandling.h"
26 #include "llvm/Support/SourceMgr.h"
27 #include "llvm/Support/TypeSize.h"
28 #include <algorithm>
29 #include <cstdint>
30 #include <functional>
31 #include <iterator>
32 #include <optional>
33 #include <string>
34 #include <utility>
35
36 namespace llvm {
37
38 // Forward declarations.
39 class DiagnosticPrinter;
40 class DIFile;
41 class DISubprogram;
42 class CallInst;
43 class Function;
44 class Instruction;
45 class InstructionCost;
46 class Module;
47 class Type;
48 class Value;
49
50 /// Defines the different supported severity of a diagnostic.
51 enum DiagnosticSeverity : char {
52 DS_Error,
53 DS_Warning,
54 DS_Remark,
55 // A note attaches additional information to one of the previous diagnostic
56 // types.
57 DS_Note
58 };
59
60 /// Defines the different supported kind of a diagnostic.
61 /// This enum should be extended with a new ID for each added concrete subclass.
62 enum DiagnosticKind {
63 DK_Generic,
64 DK_GenericWithLoc,
65 DK_InlineAsm,
66 DK_RegAllocFailure,
67 DK_ResourceLimit,
68 DK_StackSize,
69 DK_Linker,
70 DK_Lowering,
71 DK_DebugMetadataVersion,
72 DK_DebugMetadataInvalid,
73 DK_Instrumentation,
74 DK_ISelFallback,
75 DK_SampleProfile,
76 DK_OptimizationRemark,
77 DK_OptimizationRemarkMissed,
78 DK_OptimizationRemarkAnalysis,
79 DK_OptimizationRemarkAnalysisFPCommute,
80 DK_OptimizationRemarkAnalysisAliasing,
81 DK_OptimizationFailure,
82 DK_FirstRemark = DK_OptimizationRemark,
83 DK_LastRemark = DK_OptimizationFailure,
84 DK_MachineOptimizationRemark,
85 DK_MachineOptimizationRemarkMissed,
86 DK_MachineOptimizationRemarkAnalysis,
87 DK_FirstMachineRemark = DK_MachineOptimizationRemark,
88 DK_LastMachineRemark = DK_MachineOptimizationRemarkAnalysis,
89 DK_MIRParser,
90 DK_PGOProfile,
91 DK_Unsupported,
92 DK_SrcMgr,
93 DK_DontCall,
94 DK_MisExpect,
95 DK_FirstPluginKind // Must be last value to work with
96 // getNextAvailablePluginDiagnosticKind
97 };
98
99 /// Get the next available kind ID for a plugin diagnostic.
100 /// Each time this function is called, it returns a different number.
101 /// Therefore, a plugin that wants to "identify" its own classes
102 /// with a dynamic identifier, just have to use this method to get a new ID
103 /// and assign it to each of its classes.
104 /// The returned ID will be greater than or equal to DK_FirstPluginKind.
105 /// Thus, the plugin identifiers will not conflict with the
106 /// DiagnosticKind values.
107 LLVM_ABI int getNextAvailablePluginDiagnosticKind();
108
109 /// This is the base abstract class for diagnostic reporting in
110 /// the backend.
111 /// The print method must be overloaded by the subclasses to print a
112 /// user-friendly message in the client of the backend (let us call it a
113 /// frontend).
114 class LLVM_ABI DiagnosticInfo {
115 private:
116 /// Kind defines the kind of report this is about.
117 const /* DiagnosticKind */ int Kind;
118 /// Severity gives the severity of the diagnostic.
119 const DiagnosticSeverity Severity;
120
121 virtual void anchor();
122 public:
DiagnosticInfo(int Kind,DiagnosticSeverity Severity)123 DiagnosticInfo(/* DiagnosticKind */ int Kind, DiagnosticSeverity Severity)
124 : Kind(Kind), Severity(Severity) {}
125
126 virtual ~DiagnosticInfo() = default;
127
getKind()128 /* DiagnosticKind */ int getKind() const { return Kind; }
getSeverity()129 DiagnosticSeverity getSeverity() const { return Severity; }
130
131 /// Print using the given \p DP a user-friendly message.
132 /// This is the default message that will be printed to the user.
133 /// It is used when the frontend does not directly take advantage
134 /// of the information contained in fields of the subclasses.
135 /// The printed message must not end with '.' nor start with a severity
136 /// keyword.
137 virtual void print(DiagnosticPrinter &DP) const = 0;
138 };
139
140 using DiagnosticHandlerFunction = std::function<void(const DiagnosticInfo &)>;
141
142 class LLVM_ABI DiagnosticInfoGeneric : public DiagnosticInfo {
143 const Twine &MsgStr;
144 const Instruction *Inst = nullptr;
145
146 public:
147 /// \p MsgStr is the message to be reported to the frontend.
148 /// This class does not copy \p MsgStr, therefore the reference must be valid
149 /// for the whole life time of the Diagnostic.
150 DiagnosticInfoGeneric(const Twine &MsgStr LLVM_LIFETIME_BOUND,
151 DiagnosticSeverity Severity = DS_Error)
DiagnosticInfo(DK_Generic,Severity)152 : DiagnosticInfo(DK_Generic, Severity), MsgStr(MsgStr) {}
153
154 DiagnosticInfoGeneric(const Instruction *I,
155 const Twine &ErrMsg LLVM_LIFETIME_BOUND,
156 DiagnosticSeverity Severity = DS_Error)
DiagnosticInfo(DK_Generic,Severity)157 : DiagnosticInfo(DK_Generic, Severity), MsgStr(ErrMsg), Inst(I) {}
158
getMsgStr()159 const Twine &getMsgStr() const { return MsgStr; }
getInstruction()160 const Instruction *getInstruction() const { return Inst; }
161
162 /// \see DiagnosticInfo::print.
163 void print(DiagnosticPrinter &DP) const override;
164
classof(const DiagnosticInfo * DI)165 static bool classof(const DiagnosticInfo *DI) {
166 return DI->getKind() == DK_Generic;
167 }
168 };
169
170 /// Diagnostic information for inline asm reporting.
171 /// This is basically a message and an optional location.
172 class LLVM_ABI DiagnosticInfoInlineAsm : public DiagnosticInfo {
173 private:
174 /// Optional line information. 0 if not set.
175 uint64_t LocCookie = 0;
176 /// Message to be reported.
177 const Twine &MsgStr;
178 /// Optional origin of the problem.
179 const Instruction *Instr = nullptr;
180
181 public:
182 /// \p LocCookie if non-zero gives the line number for this report.
183 /// \p MsgStr gives the message.
184 /// This class does not copy \p MsgStr, therefore the reference must be valid
185 /// for the whole life time of the Diagnostic.
186 DiagnosticInfoInlineAsm(uint64_t LocCookie,
187 const Twine &MsgStr LLVM_LIFETIME_BOUND,
188 DiagnosticSeverity Severity = DS_Error);
189
190 /// \p Instr gives the original instruction that triggered the diagnostic.
191 /// \p MsgStr gives the message.
192 /// This class does not copy \p MsgStr, therefore the reference must be valid
193 /// for the whole life time of the Diagnostic.
194 /// Same for \p I.
195 DiagnosticInfoInlineAsm(const Instruction &I,
196 const Twine &MsgStr LLVM_LIFETIME_BOUND,
197 DiagnosticSeverity Severity = DS_Error);
198
getLocCookie()199 uint64_t getLocCookie() const { return LocCookie; }
getMsgStr()200 const Twine &getMsgStr() const { return MsgStr; }
getInstruction()201 const Instruction *getInstruction() const { return Instr; }
202
203 /// \see DiagnosticInfo::print.
204 void print(DiagnosticPrinter &DP) const override;
205
classof(const DiagnosticInfo * DI)206 static bool classof(const DiagnosticInfo *DI) {
207 return DI->getKind() == DK_InlineAsm;
208 }
209 };
210
211 /// Diagnostic information for debug metadata version reporting.
212 /// This is basically a module and a version.
213 class LLVM_ABI DiagnosticInfoDebugMetadataVersion : public DiagnosticInfo {
214 private:
215 /// The module that is concerned by this debug metadata version diagnostic.
216 const Module &M;
217 /// The actual metadata version.
218 unsigned MetadataVersion;
219
220 public:
221 /// \p The module that is concerned by this debug metadata version diagnostic.
222 /// \p The actual metadata version.
223 DiagnosticInfoDebugMetadataVersion(const Module &M, unsigned MetadataVersion,
224 DiagnosticSeverity Severity = DS_Warning)
DiagnosticInfo(DK_DebugMetadataVersion,Severity)225 : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M),
226 MetadataVersion(MetadataVersion) {}
227
getModule()228 const Module &getModule() const { return M; }
getMetadataVersion()229 unsigned getMetadataVersion() const { return MetadataVersion; }
230
231 /// \see DiagnosticInfo::print.
232 void print(DiagnosticPrinter &DP) const override;
233
classof(const DiagnosticInfo * DI)234 static bool classof(const DiagnosticInfo *DI) {
235 return DI->getKind() == DK_DebugMetadataVersion;
236 }
237 };
238
239 /// Diagnostic information for stripping invalid debug metadata.
240 class LLVM_ABI DiagnosticInfoIgnoringInvalidDebugMetadata
241 : public DiagnosticInfo {
242 private:
243 /// The module that is concerned by this debug metadata version diagnostic.
244 const Module &M;
245
246 public:
247 /// \p The module that is concerned by this debug metadata version diagnostic.
248 DiagnosticInfoIgnoringInvalidDebugMetadata(
249 const Module &M, DiagnosticSeverity Severity = DS_Warning)
DiagnosticInfo(DK_DebugMetadataVersion,Severity)250 : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M) {}
251
getModule()252 const Module &getModule() const { return M; }
253
254 /// \see DiagnosticInfo::print.
255 void print(DiagnosticPrinter &DP) const override;
256
classof(const DiagnosticInfo * DI)257 static bool classof(const DiagnosticInfo *DI) {
258 return DI->getKind() == DK_DebugMetadataInvalid;
259 }
260 };
261
262 /// Diagnostic information for the sample profiler.
263 class LLVM_ABI DiagnosticInfoSampleProfile : public DiagnosticInfo {
264 public:
265 DiagnosticInfoSampleProfile(StringRef FileName, unsigned LineNum,
266 const Twine &Msg LLVM_LIFETIME_BOUND,
267 DiagnosticSeverity Severity = DS_Error)
DiagnosticInfo(DK_SampleProfile,Severity)268 : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
269 LineNum(LineNum), Msg(Msg) {}
270 DiagnosticInfoSampleProfile(StringRef FileName,
271 const Twine &Msg LLVM_LIFETIME_BOUND,
272 DiagnosticSeverity Severity = DS_Error)
DiagnosticInfo(DK_SampleProfile,Severity)273 : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
274 Msg(Msg) {}
275 DiagnosticInfoSampleProfile(const Twine &Msg LLVM_LIFETIME_BOUND,
276 DiagnosticSeverity Severity = DS_Error)
DiagnosticInfo(DK_SampleProfile,Severity)277 : DiagnosticInfo(DK_SampleProfile, Severity), Msg(Msg) {}
278
279 /// \see DiagnosticInfo::print.
280 void print(DiagnosticPrinter &DP) const override;
281
classof(const DiagnosticInfo * DI)282 static bool classof(const DiagnosticInfo *DI) {
283 return DI->getKind() == DK_SampleProfile;
284 }
285
getFileName()286 StringRef getFileName() const { return FileName; }
getLineNum()287 unsigned getLineNum() const { return LineNum; }
getMsg()288 const Twine &getMsg() const { return Msg; }
289
290 private:
291 /// Name of the input file associated with this diagnostic.
292 StringRef FileName;
293
294 /// Line number where the diagnostic occurred. If 0, no line number will
295 /// be emitted in the message.
296 unsigned LineNum = 0;
297
298 /// Message to report.
299 const Twine &Msg;
300 };
301
302 /// Diagnostic information for the PGO profiler.
303 class LLVM_ABI DiagnosticInfoPGOProfile : public DiagnosticInfo {
304 public:
305 DiagnosticInfoPGOProfile(const char *FileName,
306 const Twine &Msg LLVM_LIFETIME_BOUND,
307 DiagnosticSeverity Severity = DS_Error)
DiagnosticInfo(DK_PGOProfile,Severity)308 : DiagnosticInfo(DK_PGOProfile, Severity), FileName(FileName), Msg(Msg) {}
309
310 /// \see DiagnosticInfo::print.
311 void print(DiagnosticPrinter &DP) const override;
312
classof(const DiagnosticInfo * DI)313 static bool classof(const DiagnosticInfo *DI) {
314 return DI->getKind() == DK_PGOProfile;
315 }
316
getFileName()317 const char *getFileName() const { return FileName; }
getMsg()318 const Twine &getMsg() const { return Msg; }
319
320 private:
321 /// Name of the input file associated with this diagnostic.
322 const char *FileName;
323
324 /// Message to report.
325 const Twine &Msg;
326 };
327
328 class DiagnosticLocation {
329 DIFile *File = nullptr;
330 unsigned Line = 0;
331 unsigned Column = 0;
332
333 public:
334 DiagnosticLocation() = default;
335 LLVM_ABI DiagnosticLocation(const DebugLoc &DL);
336 LLVM_ABI DiagnosticLocation(const DISubprogram *SP);
337
isValid()338 bool isValid() const { return File; }
339 /// Return the full path to the file.
340 LLVM_ABI std::string getAbsolutePath() const;
341 /// Return the file name relative to the compilation directory.
342 LLVM_ABI StringRef getRelativePath() const;
getLine()343 unsigned getLine() const { return Line; }
getColumn()344 unsigned getColumn() const { return Column; }
345 };
346
347 /// Common features for diagnostics with an associated location.
348 class LLVM_ABI DiagnosticInfoWithLocationBase : public DiagnosticInfo {
349 void anchor() override;
350 public:
351 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
352 /// the location information to use in the diagnostic.
DiagnosticInfoWithLocationBase(enum DiagnosticKind Kind,enum DiagnosticSeverity Severity,const Function & Fn,const DiagnosticLocation & Loc)353 DiagnosticInfoWithLocationBase(enum DiagnosticKind Kind,
354 enum DiagnosticSeverity Severity,
355 const Function &Fn,
356 const DiagnosticLocation &Loc)
357 : DiagnosticInfo(Kind, Severity), Fn(Fn), Loc(Loc) {}
358
359 /// Return true if location information is available for this diagnostic.
isLocationAvailable()360 bool isLocationAvailable() const { return Loc.isValid(); }
361
362 /// Return a string with the location information for this diagnostic
363 /// in the format "file:line:col". If location information is not available,
364 /// it returns "<unknown>:0:0".
365 std::string getLocationStr() const;
366
367 /// Return location information for this diagnostic in three parts:
368 /// the relative source file path, line number and column.
369 void getLocation(StringRef &RelativePath, unsigned &Line,
370 unsigned &Column) const;
371
372 /// Return the absolute path tot the file.
373 std::string getAbsolutePath() const;
374
getFunction()375 const Function &getFunction() const { return Fn; }
getLocation()376 DiagnosticLocation getLocation() const { return Loc; }
377
378 private:
379 /// Function where this diagnostic is triggered.
380 const Function &Fn;
381
382 /// Debug location where this diagnostic is triggered.
383 DiagnosticLocation Loc;
384 };
385
386 class LLVM_ABI DiagnosticInfoGenericWithLoc
387 : public DiagnosticInfoWithLocationBase {
388 private:
389 /// Message to be reported.
390 const Twine &MsgStr;
391
392 public:
393 /// \p MsgStr is the message to be reported to the frontend.
394 /// This class does not copy \p MsgStr, therefore the reference must be valid
395 /// for the whole life time of the Diagnostic.
396 DiagnosticInfoGenericWithLoc(const Twine &MsgStr, const Function &Fn,
397 const DiagnosticLocation &Loc,
398 DiagnosticSeverity Severity = DS_Error)
DiagnosticInfoWithLocationBase(DK_GenericWithLoc,Severity,Fn,Loc)399 : DiagnosticInfoWithLocationBase(DK_GenericWithLoc, Severity, Fn, Loc),
400 MsgStr(MsgStr) {}
401
getMsgStr()402 const Twine &getMsgStr() const { return MsgStr; }
403
404 /// \see DiagnosticInfo::print.
405 void print(DiagnosticPrinter &DP) const override;
406
classof(const DiagnosticInfo * DI)407 static bool classof(const DiagnosticInfo *DI) {
408 return DI->getKind() == DK_GenericWithLoc;
409 }
410 };
411
412 class LLVM_ABI DiagnosticInfoRegAllocFailure
413 : public DiagnosticInfoWithLocationBase {
414 private:
415 /// Message to be reported.
416 const Twine &MsgStr;
417
418 public:
419 /// \p MsgStr is the message to be reported to the frontend.
420 /// This class does not copy \p MsgStr, therefore the reference must be valid
421 /// for the whole life time of the Diagnostic.
422 DiagnosticInfoRegAllocFailure(const Twine &MsgStr, const Function &Fn,
423 const DiagnosticLocation &DL,
424 DiagnosticSeverity Severity = DS_Error);
425
426 DiagnosticInfoRegAllocFailure(const Twine &MsgStr, const Function &Fn,
427 DiagnosticSeverity Severity = DS_Error);
428
getMsgStr()429 const Twine &getMsgStr() const { return MsgStr; }
430
431 /// \see DiagnosticInfo::print.
432 void print(DiagnosticPrinter &DP) const override;
433
classof(const DiagnosticInfo * DI)434 static bool classof(const DiagnosticInfo *DI) {
435 return DI->getKind() == DK_RegAllocFailure;
436 }
437 };
438
439 /// Diagnostic information for stack size etc. reporting.
440 /// This is basically a function and a size.
441 class LLVM_ABI DiagnosticInfoResourceLimit
442 : public DiagnosticInfoWithLocationBase {
443 private:
444 /// The function that is concerned by this resource limit diagnostic.
445 const Function &Fn;
446
447 /// Description of the resource type (e.g. stack size)
448 const char *ResourceName;
449
450 /// The computed size usage
451 uint64_t ResourceSize;
452
453 // Threshould passed
454 uint64_t ResourceLimit;
455
456 public:
457 /// \p The function that is concerned by this stack size diagnostic.
458 /// \p The computed stack size.
459 DiagnosticInfoResourceLimit(const Function &Fn, const char *ResourceName,
460 uint64_t ResourceSize, uint64_t ResourceLimit,
461 DiagnosticSeverity Severity = DS_Warning,
462 DiagnosticKind Kind = DK_ResourceLimit);
463
getFunction()464 const Function &getFunction() const { return Fn; }
getResourceName()465 const char *getResourceName() const { return ResourceName; }
getResourceSize()466 uint64_t getResourceSize() const { return ResourceSize; }
getResourceLimit()467 uint64_t getResourceLimit() const { return ResourceLimit; }
468
469 /// \see DiagnosticInfo::print.
470 void print(DiagnosticPrinter &DP) const override;
471
classof(const DiagnosticInfo * DI)472 static bool classof(const DiagnosticInfo *DI) {
473 return DI->getKind() == DK_ResourceLimit || DI->getKind() == DK_StackSize;
474 }
475 };
476
477 class LLVM_ABI DiagnosticInfoStackSize : public DiagnosticInfoResourceLimit {
478 void anchor() override;
479
480 public:
481 DiagnosticInfoStackSize(const Function &Fn, uint64_t StackSize,
482 uint64_t StackLimit,
483 DiagnosticSeverity Severity = DS_Warning)
484 : DiagnosticInfoResourceLimit(Fn, "stack frame size", StackSize,
485 StackLimit, Severity, DK_StackSize) {}
486
getStackSize()487 uint64_t getStackSize() const { return getResourceSize(); }
getStackLimit()488 uint64_t getStackLimit() const { return getResourceLimit(); }
489
classof(const DiagnosticInfo * DI)490 static bool classof(const DiagnosticInfo *DI) {
491 return DI->getKind() == DK_StackSize;
492 }
493 };
494
495 /// Common features for diagnostics dealing with optimization remarks
496 /// that are used by both IR and MIR passes.
497 class LLVM_ABI DiagnosticInfoOptimizationBase
498 : public DiagnosticInfoWithLocationBase {
499 public:
500 /// Used to set IsVerbose via the stream interface.
501 struct setIsVerbose {};
502
503 /// When an instance of this is inserted into the stream, the arguments
504 /// following will not appear in the remark printed in the compiler output
505 /// (-Rpass) but only in the optimization record file
506 /// (-fsave-optimization-record).
507 struct setExtraArgs {};
508
509 /// Used in the streaming interface as the general argument type. It
510 /// internally converts everything into a key-value pair.
511 struct Argument {
512 std::string Key;
513 std::string Val;
514 // If set, the debug location corresponding to the value.
515 DiagnosticLocation Loc;
516
517 explicit Argument(StringRef Str = "") : Key("String"), Val(Str) {}
518 LLVM_ABI Argument(StringRef Key, const Value *V);
519 LLVM_ABI Argument(StringRef Key, const Type *T);
520 LLVM_ABI Argument(StringRef Key, StringRef S);
ArgumentArgument521 Argument(StringRef Key, const char *S) : Argument(Key, StringRef(S)) {};
522 LLVM_ABI Argument(StringRef Key, int N);
523 LLVM_ABI Argument(StringRef Key, float N);
524 LLVM_ABI Argument(StringRef Key, long N);
525 LLVM_ABI Argument(StringRef Key, long long N);
526 LLVM_ABI Argument(StringRef Key, unsigned N);
527 LLVM_ABI Argument(StringRef Key, unsigned long N);
528 LLVM_ABI Argument(StringRef Key, unsigned long long N);
529 LLVM_ABI Argument(StringRef Key, ElementCount EC);
ArgumentArgument530 Argument(StringRef Key, bool B) : Key(Key), Val(B ? "true" : "false") {}
531 LLVM_ABI Argument(StringRef Key, DebugLoc dl);
532 LLVM_ABI Argument(StringRef Key, InstructionCost C);
533 };
534
535 /// \p PassName is the name of the pass emitting this diagnostic. \p
536 /// RemarkName is a textual identifier for the remark (single-word,
537 /// CamelCase). \p Fn is the function where the diagnostic is being emitted.
538 /// \p Loc is the location information to use in the diagnostic. If line table
539 /// information is available, the diagnostic will include the source code
540 /// location.
DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind,enum DiagnosticSeverity Severity,const char * PassName,StringRef RemarkName,const Function & Fn,const DiagnosticLocation & Loc)541 DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind,
542 enum DiagnosticSeverity Severity,
543 const char *PassName, StringRef RemarkName,
544 const Function &Fn,
545 const DiagnosticLocation &Loc)
546 : DiagnosticInfoWithLocationBase(Kind, Severity, Fn, Loc),
547 PassName(PassName), RemarkName(RemarkName) {}
548
549 void insert(StringRef S);
550 void insert(Argument A);
551 void insert(setIsVerbose V);
552 void insert(setExtraArgs EA);
553
554 /// \see DiagnosticInfo::print.
555 void print(DiagnosticPrinter &DP) const override;
556
557 /// Return true if this optimization remark is enabled by one of
558 /// of the LLVM command line flags (-pass-remarks, -pass-remarks-missed,
559 /// or -pass-remarks-analysis). Note that this only handles the LLVM
560 /// flags. We cannot access Clang flags from here (they are handled
561 /// in BackendConsumer::OptimizationRemarkHandler).
562 virtual bool isEnabled() const = 0;
563
getPassName()564 StringRef getPassName() const { return PassName; }
getRemarkName()565 StringRef getRemarkName() const { return RemarkName; }
566 std::string getMsg() const;
getHotness()567 std::optional<uint64_t> getHotness() const { return Hotness; }
setHotness(std::optional<uint64_t> H)568 void setHotness(std::optional<uint64_t> H) { Hotness = H; }
569
isVerbose()570 bool isVerbose() const { return IsVerbose; }
571
getArgs()572 ArrayRef<Argument> getArgs() const { return Args; }
573
classof(const DiagnosticInfo * DI)574 static bool classof(const DiagnosticInfo *DI) {
575 return (DI->getKind() >= DK_FirstRemark &&
576 DI->getKind() <= DK_LastRemark) ||
577 (DI->getKind() >= DK_FirstMachineRemark &&
578 DI->getKind() <= DK_LastMachineRemark);
579 }
580
isPassed()581 bool isPassed() const {
582 return (getKind() == DK_OptimizationRemark ||
583 getKind() == DK_MachineOptimizationRemark);
584 }
585
isMissed()586 bool isMissed() const {
587 return (getKind() == DK_OptimizationRemarkMissed ||
588 getKind() == DK_MachineOptimizationRemarkMissed);
589 }
590
isAnalysis()591 bool isAnalysis() const {
592 return (getKind() == DK_OptimizationRemarkAnalysis ||
593 getKind() == DK_MachineOptimizationRemarkAnalysis);
594 }
595
596 protected:
597 /// Name of the pass that triggers this report. If this matches the
598 /// regular expression given in -Rpass=regexp, then the remark will
599 /// be emitted.
600 const char *PassName;
601
602 /// Textual identifier for the remark (single-word, CamelCase). Can be used
603 /// by external tools reading the output file for optimization remarks to
604 /// identify the remark.
605 StringRef RemarkName;
606
607 /// If profile information is available, this is the number of times the
608 /// corresponding code was executed in a profile instrumentation run.
609 std::optional<uint64_t> Hotness;
610
611 /// Arguments collected via the streaming interface.
612 SmallVector<Argument, 4> Args;
613
614 /// The remark is expected to be noisy.
615 bool IsVerbose = false;
616
617 /// If positive, the index of the first argument that only appear in
618 /// the optimization records and not in the remark printed in the compiler
619 /// output.
620 int FirstExtraArgIndex = -1;
621 };
622
623 /// Allow the insertion operator to return the actual remark type rather than a
624 /// common base class. This allows returning the result of the insertion
625 /// directly by value, e.g. return OptimizationRemarkAnalysis(...) << "blah".
626 template <class RemarkT>
627 decltype(auto)
628 operator<<(RemarkT &&R,
629 std::enable_if_t<std::is_base_of_v<DiagnosticInfoOptimizationBase,
630 std::remove_reference_t<RemarkT>>,
631 StringRef>
632 S) {
633 R.insert(S);
634 return std::forward<RemarkT>(R);
635 }
636
637 template <class RemarkT>
638 decltype(auto)
639 operator<<(RemarkT &&R,
640 std::enable_if_t<std::is_base_of_v<DiagnosticInfoOptimizationBase,
641 std::remove_reference_t<RemarkT>>,
642 DiagnosticInfoOptimizationBase::Argument>
643 A) {
644 R.insert(A);
645 return std::forward<RemarkT>(R);
646 }
647
648 template <class RemarkT>
649 decltype(auto)
650 operator<<(RemarkT &&R,
651 std::enable_if_t<std::is_base_of_v<DiagnosticInfoOptimizationBase,
652 std::remove_reference_t<RemarkT>>,
653 DiagnosticInfoOptimizationBase::setIsVerbose>
654 V) {
655 R.insert(V);
656 return std::forward<RemarkT>(R);
657 }
658
659 template <class RemarkT>
660 decltype(auto)
661 operator<<(RemarkT &&R,
662 std::enable_if_t<std::is_base_of_v<DiagnosticInfoOptimizationBase,
663 std::remove_reference_t<RemarkT>>,
664 DiagnosticInfoOptimizationBase::setExtraArgs>
665 EA) {
666 R.insert(EA);
667 return std::forward<RemarkT>(R);
668 }
669
670 /// Common features for diagnostics dealing with optimization remarks
671 /// that are used by IR passes.
672 class LLVM_ABI DiagnosticInfoIROptimization
673 : public DiagnosticInfoOptimizationBase {
674 void anchor() override;
675 public:
676 /// \p PassName is the name of the pass emitting this diagnostic. \p
677 /// RemarkName is a textual identifier for the remark (single-word,
678 /// CamelCase). \p Fn is the function where the diagnostic is being emitted.
679 /// \p Loc is the location information to use in the diagnostic. If line table
680 /// information is available, the diagnostic will include the source code
681 /// location. \p CodeRegion is IR value that the optimization operates on.
682 /// This is currently used to provide run-time hotness information with PGO.
683 DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
684 enum DiagnosticSeverity Severity,
685 const char *PassName, StringRef RemarkName,
686 const Function &Fn,
687 const DiagnosticLocation &Loc,
688 const BasicBlock *CodeRegion = nullptr)
DiagnosticInfoOptimizationBase(Kind,Severity,PassName,RemarkName,Fn,Loc)689 : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, RemarkName, Fn,
690 Loc),
691 CodeRegion(CodeRegion) {}
692
693 /// This is ctor variant allows a pass to build an optimization remark
694 /// from an existing remark.
695 ///
696 /// This is useful when a transformation pass (e.g LV) wants to emit a remark
697 /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
698 /// remark. The string \p Prepend will be emitted before the original
699 /// message.
DiagnosticInfoIROptimization(const char * PassName,StringRef Prepend,const DiagnosticInfoIROptimization & Orig)700 DiagnosticInfoIROptimization(const char *PassName, StringRef Prepend,
701 const DiagnosticInfoIROptimization &Orig)
702 : DiagnosticInfoOptimizationBase(
703 (DiagnosticKind)Orig.getKind(), Orig.getSeverity(), PassName,
704 Orig.RemarkName, Orig.getFunction(), Orig.getLocation()),
705 CodeRegion(Orig.getCodeRegion()) {
706 *this << Prepend;
707 llvm::append_range(Args, Orig.Args);
708 }
709
710 /// Legacy interface.
711 /// \p PassName is the name of the pass emitting this diagnostic.
712 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
713 /// the location information to use in the diagnostic. If line table
714 /// information is available, the diagnostic will include the source code
715 /// location. \p Msg is the message to show. Note that this class does not
716 /// copy this message, so this reference must be valid for the whole life time
717 /// of the diagnostic.
DiagnosticInfoIROptimization(enum DiagnosticKind Kind,enum DiagnosticSeverity Severity,const char * PassName,const Function & Fn,const DiagnosticLocation & Loc,const Twine & Msg)718 DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
719 enum DiagnosticSeverity Severity,
720 const char *PassName, const Function &Fn,
721 const DiagnosticLocation &Loc, const Twine &Msg)
722 : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, "", Fn, Loc) {
723 *this << Msg.str();
724 }
725
getCodeRegion()726 const BasicBlock *getCodeRegion() const { return CodeRegion; }
727
classof(const DiagnosticInfo * DI)728 static bool classof(const DiagnosticInfo *DI) {
729 return DI->getKind() >= DK_FirstRemark && DI->getKind() <= DK_LastRemark;
730 }
731
732 private:
733 /// The IR region (currently basic block) that the optimization operates on.
734 /// This is currently used to provide run-time hotness information with PGO.
735 const BasicBlock *CodeRegion = nullptr;
736 };
737
738 /// Diagnostic information for applied optimization remarks.
739 class LLVM_ABI OptimizationRemark : public DiagnosticInfoIROptimization {
740 public:
741 /// \p PassName is the name of the pass emitting this diagnostic. If this name
742 /// matches the regular expression given in -Rpass=, then the diagnostic will
743 /// be emitted. \p RemarkName is a textual identifier for the remark (single-
744 /// word, CamelCase). \p Loc is the debug location and \p CodeRegion is the
745 /// region that the optimization operates on.
746 OptimizationRemark(const char *PassName, StringRef RemarkName,
747 const DiagnosticLocation &Loc,
748 const BasicBlock *CodeRegion);
749
750 /// Same as above, but the debug location and code region are derived from \p
751 /// Instr.
752 OptimizationRemark(const char *PassName, StringRef RemarkName,
753 const Instruction *Inst);
754
755 /// Same as above, but the debug location and code region are derived from \p
756 /// Func.
757 OptimizationRemark(const char *PassName, StringRef RemarkName,
758 const Function *Func);
759
classof(const DiagnosticInfo * DI)760 static bool classof(const DiagnosticInfo *DI) {
761 return DI->getKind() == DK_OptimizationRemark;
762 }
763
764 /// \see DiagnosticInfoOptimizationBase::isEnabled.
765 bool isEnabled() const override;
766
767 private:
768 /// This is deprecated now and only used by the function API below.
769 /// \p PassName is the name of the pass emitting this diagnostic. If
770 /// this name matches the regular expression given in -Rpass=, then the
771 /// diagnostic will be emitted. \p Fn is the function where the diagnostic
772 /// is being emitted. \p Loc is the location information to use in the
773 /// diagnostic. If line table information is available, the diagnostic
774 /// will include the source code location. \p Msg is the message to show.
775 /// Note that this class does not copy this message, so this reference
776 /// must be valid for the whole life time of the diagnostic.
OptimizationRemark(const char * PassName,const Function & Fn,const DiagnosticLocation & Loc,const Twine & Msg)777 OptimizationRemark(const char *PassName, const Function &Fn,
778 const DiagnosticLocation &Loc, const Twine &Msg)
779 : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
780 Fn, Loc, Msg) {}
781 };
782
783 /// Diagnostic information for missed-optimization remarks.
784 class LLVM_ABI OptimizationRemarkMissed : public DiagnosticInfoIROptimization {
785 public:
786 /// \p PassName is the name of the pass emitting this diagnostic. If this name
787 /// matches the regular expression given in -Rpass-missed=, then the
788 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
789 /// remark (single-word, CamelCase). \p Loc is the debug location and \p
790 /// CodeRegion is the region that the optimization operates on.
791 OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
792 const DiagnosticLocation &Loc,
793 const BasicBlock *CodeRegion);
794
795 /// Same as above but \p Inst is used to derive code region and debug
796 /// location.
797 OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
798 const Instruction *Inst);
799
800 /// Same as above but \p F is used to derive code region and debug
801 /// location.
802 OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
803 const Function *F);
804
classof(const DiagnosticInfo * DI)805 static bool classof(const DiagnosticInfo *DI) {
806 return DI->getKind() == DK_OptimizationRemarkMissed;
807 }
808
809 /// \see DiagnosticInfoOptimizationBase::isEnabled.
810 bool isEnabled() const override;
811
812 private:
813 /// This is deprecated now and only used by the function API below.
814 /// \p PassName is the name of the pass emitting this diagnostic. If
815 /// this name matches the regular expression given in -Rpass-missed=, then the
816 /// diagnostic will be emitted. \p Fn is the function where the diagnostic
817 /// is being emitted. \p Loc is the location information to use in the
818 /// diagnostic. If line table information is available, the diagnostic
819 /// will include the source code location. \p Msg is the message to show.
820 /// Note that this class does not copy this message, so this reference
821 /// must be valid for the whole life time of the diagnostic.
OptimizationRemarkMissed(const char * PassName,const Function & Fn,const DiagnosticLocation & Loc,const Twine & Msg)822 OptimizationRemarkMissed(const char *PassName, const Function &Fn,
823 const DiagnosticLocation &Loc, const Twine &Msg)
824 : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
825 PassName, Fn, Loc, Msg) {}
826 };
827
828 /// Diagnostic information for optimization analysis remarks.
829 class LLVM_ABI OptimizationRemarkAnalysis
830 : public DiagnosticInfoIROptimization {
831 public:
832 /// \p PassName is the name of the pass emitting this diagnostic. If this name
833 /// matches the regular expression given in -Rpass-analysis=, then the
834 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
835 /// remark (single-word, CamelCase). \p Loc is the debug location and \p
836 /// CodeRegion is the region that the optimization operates on.
837 OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
838 const DiagnosticLocation &Loc,
839 const BasicBlock *CodeRegion);
840
841 /// This is ctor variant allows a pass to build an optimization remark
842 /// from an existing remark.
843 ///
844 /// This is useful when a transformation pass (e.g LV) wants to emit a remark
845 /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
846 /// remark. The string \p Prepend will be emitted before the original
847 /// message.
OptimizationRemarkAnalysis(const char * PassName,StringRef Prepend,const OptimizationRemarkAnalysis & Orig)848 OptimizationRemarkAnalysis(const char *PassName, StringRef Prepend,
849 const OptimizationRemarkAnalysis &Orig)
850 : DiagnosticInfoIROptimization(PassName, Prepend, Orig) {}
851
852 /// Same as above but \p Inst is used to derive code region and debug
853 /// location.
854 OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
855 const Instruction *Inst);
856
857 /// Same as above but \p F is used to derive code region and debug
858 /// location.
859 OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
860 const Function *F);
861
classof(const DiagnosticInfo * DI)862 static bool classof(const DiagnosticInfo *DI) {
863 return DI->getKind() == DK_OptimizationRemarkAnalysis;
864 }
865
866 /// \see DiagnosticInfoOptimizationBase::isEnabled.
867 bool isEnabled() const override;
868
869 static const char *AlwaysPrint;
870
shouldAlwaysPrint()871 bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint; }
872
873 protected:
OptimizationRemarkAnalysis(enum DiagnosticKind Kind,const char * PassName,const Function & Fn,const DiagnosticLocation & Loc,const Twine & Msg)874 OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
875 const Function &Fn, const DiagnosticLocation &Loc,
876 const Twine &Msg)
877 : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, Fn, Loc, Msg) {}
878
879 OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
880 StringRef RemarkName,
881 const DiagnosticLocation &Loc,
882 const BasicBlock *CodeRegion);
883
884 private:
885 /// This is deprecated now and only used by the function API below.
886 /// \p PassName is the name of the pass emitting this diagnostic. If
887 /// this name matches the regular expression given in -Rpass-analysis=, then
888 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
889 /// is being emitted. \p Loc is the location information to use in the
890 /// diagnostic. If line table information is available, the diagnostic will
891 /// include the source code location. \p Msg is the message to show. Note that
892 /// this class does not copy this message, so this reference must be valid for
893 /// the whole life time of the diagnostic.
OptimizationRemarkAnalysis(const char * PassName,const Function & Fn,const DiagnosticLocation & Loc,const Twine & Msg)894 OptimizationRemarkAnalysis(const char *PassName, const Function &Fn,
895 const DiagnosticLocation &Loc, const Twine &Msg)
896 : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
897 PassName, Fn, Loc, Msg) {}
898 };
899
900 /// Diagnostic information for optimization analysis remarks related to
901 /// floating-point non-commutativity.
902 class LLVM_ABI OptimizationRemarkAnalysisFPCommute
903 : public OptimizationRemarkAnalysis {
904 void anchor() override;
905 public:
906 /// \p PassName is the name of the pass emitting this diagnostic. If this name
907 /// matches the regular expression given in -Rpass-analysis=, then the
908 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
909 /// remark (single-word, CamelCase). \p Loc is the debug location and \p
910 /// CodeRegion is the region that the optimization operates on. The front-end
911 /// will append its own message related to options that address floating-point
912 /// non-commutativity.
OptimizationRemarkAnalysisFPCommute(const char * PassName,StringRef RemarkName,const DiagnosticLocation & Loc,const BasicBlock * CodeRegion)913 OptimizationRemarkAnalysisFPCommute(const char *PassName,
914 StringRef RemarkName,
915 const DiagnosticLocation &Loc,
916 const BasicBlock *CodeRegion)
917 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
918 PassName, RemarkName, Loc, CodeRegion) {}
919
classof(const DiagnosticInfo * DI)920 static bool classof(const DiagnosticInfo *DI) {
921 return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute;
922 }
923
924 private:
925 /// This is deprecated now and only used by the function API below.
926 /// \p PassName is the name of the pass emitting this diagnostic. If
927 /// this name matches the regular expression given in -Rpass-analysis=, then
928 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
929 /// is being emitted. \p Loc is the location information to use in the
930 /// diagnostic. If line table information is available, the diagnostic will
931 /// include the source code location. \p Msg is the message to show. The
932 /// front-end will append its own message related to options that address
933 /// floating-point non-commutativity. Note that this class does not copy this
934 /// message, so this reference must be valid for the whole life time of the
935 /// diagnostic.
OptimizationRemarkAnalysisFPCommute(const char * PassName,const Function & Fn,const DiagnosticLocation & Loc,const Twine & Msg)936 OptimizationRemarkAnalysisFPCommute(const char *PassName, const Function &Fn,
937 const DiagnosticLocation &Loc,
938 const Twine &Msg)
939 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
940 PassName, Fn, Loc, Msg) {}
941 };
942
943 /// Diagnostic information for optimization analysis remarks related to
944 /// pointer aliasing.
945 class LLVM_ABI OptimizationRemarkAnalysisAliasing
946 : public OptimizationRemarkAnalysis {
947 void anchor() override;
948 public:
949 /// \p PassName is the name of the pass emitting this diagnostic. If this name
950 /// matches the regular expression given in -Rpass-analysis=, then the
951 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
952 /// remark (single-word, CamelCase). \p Loc is the debug location and \p
953 /// CodeRegion is the region that the optimization operates on. The front-end
954 /// will append its own message related to options that address pointer
955 /// aliasing legality.
OptimizationRemarkAnalysisAliasing(const char * PassName,StringRef RemarkName,const DiagnosticLocation & Loc,const BasicBlock * CodeRegion)956 OptimizationRemarkAnalysisAliasing(const char *PassName, StringRef RemarkName,
957 const DiagnosticLocation &Loc,
958 const BasicBlock *CodeRegion)
959 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
960 PassName, RemarkName, Loc, CodeRegion) {}
961
classof(const DiagnosticInfo * DI)962 static bool classof(const DiagnosticInfo *DI) {
963 return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing;
964 }
965
966 private:
967 /// This is deprecated now and only used by the function API below.
968 /// \p PassName is the name of the pass emitting this diagnostic. If
969 /// this name matches the regular expression given in -Rpass-analysis=, then
970 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
971 /// is being emitted. \p Loc is the location information to use in the
972 /// diagnostic. If line table information is available, the diagnostic will
973 /// include the source code location. \p Msg is the message to show. The
974 /// front-end will append its own message related to options that address
975 /// pointer aliasing legality. Note that this class does not copy this
976 /// message, so this reference must be valid for the whole life time of the
977 /// diagnostic.
OptimizationRemarkAnalysisAliasing(const char * PassName,const Function & Fn,const DiagnosticLocation & Loc,const Twine & Msg)978 OptimizationRemarkAnalysisAliasing(const char *PassName, const Function &Fn,
979 const DiagnosticLocation &Loc,
980 const Twine &Msg)
981 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
982 PassName, Fn, Loc, Msg) {}
983 };
984
985 /// Diagnostic information for machine IR parser.
986 // FIXME: Remove this, use DiagnosticInfoSrcMgr instead.
987 class LLVM_ABI DiagnosticInfoMIRParser : public DiagnosticInfo {
988 const SMDiagnostic &Diagnostic;
989
990 public:
DiagnosticInfoMIRParser(DiagnosticSeverity Severity,const SMDiagnostic & Diagnostic)991 DiagnosticInfoMIRParser(DiagnosticSeverity Severity,
992 const SMDiagnostic &Diagnostic)
993 : DiagnosticInfo(DK_MIRParser, Severity), Diagnostic(Diagnostic) {}
994
getDiagnostic()995 const SMDiagnostic &getDiagnostic() const { return Diagnostic; }
996
997 void print(DiagnosticPrinter &DP) const override;
998
classof(const DiagnosticInfo * DI)999 static bool classof(const DiagnosticInfo *DI) {
1000 return DI->getKind() == DK_MIRParser;
1001 }
1002 };
1003
1004 /// Diagnostic information for IR instrumentation reporting.
1005 class LLVM_ABI DiagnosticInfoInstrumentation : public DiagnosticInfo {
1006 const Twine &Msg;
1007
1008 public:
1009 DiagnosticInfoInstrumentation(const Twine &DiagMsg,
1010 DiagnosticSeverity Severity = DS_Warning)
DiagnosticInfo(DK_Instrumentation,Severity)1011 : DiagnosticInfo(DK_Instrumentation, Severity), Msg(DiagMsg) {}
1012
1013 void print(DiagnosticPrinter &DP) const override;
1014
classof(const DiagnosticInfo * DI)1015 static bool classof(const DiagnosticInfo *DI) {
1016 return DI->getKind() == DK_Instrumentation;
1017 }
1018 };
1019
1020 /// Diagnostic information for ISel fallback path.
1021 class LLVM_ABI DiagnosticInfoISelFallback : public DiagnosticInfo {
1022 /// The function that is concerned by this diagnostic.
1023 const Function &Fn;
1024
1025 public:
1026 DiagnosticInfoISelFallback(const Function &Fn,
1027 DiagnosticSeverity Severity = DS_Warning)
DiagnosticInfo(DK_ISelFallback,Severity)1028 : DiagnosticInfo(DK_ISelFallback, Severity), Fn(Fn) {}
1029
getFunction()1030 const Function &getFunction() const { return Fn; }
1031
1032 void print(DiagnosticPrinter &DP) const override;
1033
classof(const DiagnosticInfo * DI)1034 static bool classof(const DiagnosticInfo *DI) {
1035 return DI->getKind() == DK_ISelFallback;
1036 }
1037 };
1038
1039 // Create wrappers for C Binding types (see CBindingWrapping.h).
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo,LLVMDiagnosticInfoRef)1040 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef)
1041
1042 /// Diagnostic information for optimization failures.
1043 class LLVM_ABI DiagnosticInfoOptimizationFailure
1044 : public DiagnosticInfoIROptimization {
1045 public:
1046 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
1047 /// the location information to use in the diagnostic. If line table
1048 /// information is available, the diagnostic will include the source code
1049 /// location. \p Msg is the message to show. Note that this class does not
1050 /// copy this message, so this reference must be valid for the whole life time
1051 /// of the diagnostic.
1052 DiagnosticInfoOptimizationFailure(const Function &Fn,
1053 const DiagnosticLocation &Loc,
1054 const Twine &Msg)
1055 : DiagnosticInfoIROptimization(DK_OptimizationFailure, DS_Warning,
1056 nullptr, Fn, Loc, Msg) {}
1057
1058 /// \p PassName is the name of the pass emitting this diagnostic. \p
1059 /// RemarkName is a textual identifier for the remark (single-word,
1060 /// CamelCase). \p Loc is the debug location and \p CodeRegion is the
1061 /// region that the optimization operates on.
1062 DiagnosticInfoOptimizationFailure(const char *PassName, StringRef RemarkName,
1063 const DiagnosticLocation &Loc,
1064 const BasicBlock *CodeRegion);
1065
1066 static bool classof(const DiagnosticInfo *DI) {
1067 return DI->getKind() == DK_OptimizationFailure;
1068 }
1069
1070 /// \see DiagnosticInfoOptimizationBase::isEnabled.
1071 bool isEnabled() const override;
1072 };
1073
1074 /// Diagnostic information for unsupported feature in backend.
1075 class LLVM_ABI DiagnosticInfoUnsupported
1076 : public DiagnosticInfoWithLocationBase {
1077 private:
1078 const Twine &Msg;
1079
1080 public:
1081 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
1082 /// the location information to use in the diagnostic. If line table
1083 /// information is available, the diagnostic will include the source code
1084 /// location. \p Msg is the message to show. Note that this class does not
1085 /// copy this message, so this reference must be valid for the whole life time
1086 /// of the diagnostic.
1087 DiagnosticInfoUnsupported(
1088 const Function &Fn, const Twine &Msg LLVM_LIFETIME_BOUND,
1089 const DiagnosticLocation &Loc = DiagnosticLocation(),
1090 DiagnosticSeverity Severity = DS_Error)
DiagnosticInfoWithLocationBase(DK_Unsupported,Severity,Fn,Loc)1091 : DiagnosticInfoWithLocationBase(DK_Unsupported, Severity, Fn, Loc),
1092 Msg(Msg) {}
1093
classof(const DiagnosticInfo * DI)1094 static bool classof(const DiagnosticInfo *DI) {
1095 return DI->getKind() == DK_Unsupported;
1096 }
1097
getMessage()1098 const Twine &getMessage() const { return Msg; }
1099
1100 void print(DiagnosticPrinter &DP) const override;
1101 };
1102
1103 /// Diagnostic information for MisExpect analysis.
1104 class LLVM_ABI DiagnosticInfoMisExpect : public DiagnosticInfoWithLocationBase {
1105 public:
1106 DiagnosticInfoMisExpect(const Instruction *Inst,
1107 const Twine &Msg LLVM_LIFETIME_BOUND);
1108
1109 /// \see DiagnosticInfo::print.
1110 void print(DiagnosticPrinter &DP) const override;
1111
classof(const DiagnosticInfo * DI)1112 static bool classof(const DiagnosticInfo *DI) {
1113 return DI->getKind() == DK_MisExpect;
1114 }
1115
getMsg()1116 const Twine &getMsg() const { return Msg; }
1117
1118 private:
1119 /// Message to report.
1120 const Twine &Msg;
1121 };
1122
getDiagnosticSeverity(SourceMgr::DiagKind DK)1123 static DiagnosticSeverity getDiagnosticSeverity(SourceMgr::DiagKind DK) {
1124 switch (DK) {
1125 case llvm::SourceMgr::DK_Error:
1126 return DS_Error;
1127 break;
1128 case llvm::SourceMgr::DK_Warning:
1129 return DS_Warning;
1130 break;
1131 case llvm::SourceMgr::DK_Note:
1132 return DS_Note;
1133 break;
1134 case llvm::SourceMgr::DK_Remark:
1135 return DS_Remark;
1136 break;
1137 }
1138 llvm_unreachable("unknown SourceMgr::DiagKind");
1139 }
1140
1141 /// Diagnostic information for SMDiagnostic reporting.
1142 class LLVM_ABI DiagnosticInfoSrcMgr : public DiagnosticInfo {
1143 const SMDiagnostic &Diagnostic;
1144 StringRef ModName;
1145
1146 // For inlineasm !srcloc translation.
1147 bool InlineAsmDiag;
1148 uint64_t LocCookie;
1149
1150 public:
1151 DiagnosticInfoSrcMgr(const SMDiagnostic &Diagnostic, StringRef ModName,
1152 bool InlineAsmDiag = true, uint64_t LocCookie = 0)
1153 : DiagnosticInfo(DK_SrcMgr, getDiagnosticSeverity(Diagnostic.getKind())),
1154 Diagnostic(Diagnostic), ModName(ModName), InlineAsmDiag(InlineAsmDiag),
1155 LocCookie(LocCookie) {}
1156
getModuleName()1157 StringRef getModuleName() const { return ModName; }
isInlineAsmDiag()1158 bool isInlineAsmDiag() const { return InlineAsmDiag; }
getSMDiag()1159 const SMDiagnostic &getSMDiag() const { return Diagnostic; }
getLocCookie()1160 uint64_t getLocCookie() const { return LocCookie; }
1161 void print(DiagnosticPrinter &DP) const override;
1162
classof(const DiagnosticInfo * DI)1163 static bool classof(const DiagnosticInfo *DI) {
1164 return DI->getKind() == DK_SrcMgr;
1165 }
1166 };
1167
1168 LLVM_ABI void diagnoseDontCall(const CallInst &CI);
1169
1170 class LLVM_ABI DiagnosticInfoDontCall : public DiagnosticInfo {
1171 StringRef CalleeName;
1172 StringRef Note;
1173 uint64_t LocCookie;
1174
1175 public:
DiagnosticInfoDontCall(StringRef CalleeName,StringRef Note,DiagnosticSeverity DS,uint64_t LocCookie)1176 DiagnosticInfoDontCall(StringRef CalleeName, StringRef Note,
1177 DiagnosticSeverity DS, uint64_t LocCookie)
1178 : DiagnosticInfo(DK_DontCall, DS), CalleeName(CalleeName), Note(Note),
1179 LocCookie(LocCookie) {}
getFunctionName()1180 StringRef getFunctionName() const { return CalleeName; }
getNote()1181 StringRef getNote() const { return Note; }
getLocCookie()1182 uint64_t getLocCookie() const { return LocCookie; }
1183 void print(DiagnosticPrinter &DP) const override;
classof(const DiagnosticInfo * DI)1184 static bool classof(const DiagnosticInfo *DI) {
1185 return DI->getKind() == DK_DontCall;
1186 }
1187 };
1188
1189 } // end namespace llvm
1190
1191 #endif // LLVM_IR_DIAGNOSTICINFO_H
1192