xref: /freebsd/contrib/llvm-project/llvm/include/llvm/IR/DiagnosticInfo.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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