OSDN Git Service

[OptDiag,LV] Add hotness attribute to analysis remarks
[android-x86/external-llvm.git] / include / llvm / IR / DiagnosticInfo.h
1 //===- llvm/IR/DiagnosticInfo.h - Diagnostic Declaration --------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file declares the different classes involved in low level diagnostics.
11 //
12 // Diagnostics reporting is still done as part of the LLVMContext.
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_IR_DIAGNOSTICINFO_H
16 #define LLVM_IR_DIAGNOSTICINFO_H
17
18 #include "llvm/ADT/Optional.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ADT/Twine.h"
21 #include "llvm/IR/DebugLoc.h"
22 #include "llvm/Support/CBindingWrapping.h"
23 #include "llvm-c/Types.h"
24 #include <functional>
25 #include <string>
26
27 namespace llvm {
28
29 // Forward declarations.
30 class DiagnosticPrinter;
31 class Function;
32 class Instruction;
33 class LLVMContext;
34 class Module;
35 class SMDiagnostic;
36
37 /// \brief Defines the different supported severity of a diagnostic.
38 enum DiagnosticSeverity : char {
39   DS_Error,
40   DS_Warning,
41   DS_Remark,
42   // A note attaches additional information to one of the previous diagnostic
43   // types.
44   DS_Note
45 };
46
47 /// \brief Defines the different supported kind of a diagnostic.
48 /// This enum should be extended with a new ID for each added concrete subclass.
49 enum DiagnosticKind {
50   DK_Bitcode,
51   DK_InlineAsm,
52   DK_ResourceLimit,
53   DK_StackSize,
54   DK_Linker,
55   DK_DebugMetadataVersion,
56   DK_DebugMetadataInvalid,
57   DK_SampleProfile,
58   DK_OptimizationRemark,
59   DK_OptimizationRemarkMissed,
60   DK_OptimizationRemarkAnalysis,
61   DK_OptimizationRemarkAnalysisFPCommute,
62   DK_OptimizationRemarkAnalysisAliasing,
63   DK_OptimizationFailure,
64   DK_FirstRemark = DK_OptimizationRemark,
65   DK_LastRemark = DK_OptimizationFailure,
66   DK_MIRParser,
67   DK_PGOProfile,
68   DK_Unsupported,
69   DK_FirstPluginKind
70 };
71
72 /// \brief Get the next available kind ID for a plugin diagnostic.
73 /// Each time this function is called, it returns a different number.
74 /// Therefore, a plugin that wants to "identify" its own classes
75 /// with a dynamic identifier, just have to use this method to get a new ID
76 /// and assign it to each of its classes.
77 /// The returned ID will be greater than or equal to DK_FirstPluginKind.
78 /// Thus, the plugin identifiers will not conflict with the
79 /// DiagnosticKind values.
80 int getNextAvailablePluginDiagnosticKind();
81
82 /// \brief This is the base abstract class for diagnostic reporting in
83 /// the backend.
84 /// The print method must be overloaded by the subclasses to print a
85 /// user-friendly message in the client of the backend (let us call it a
86 /// frontend).
87 class DiagnosticInfo {
88 private:
89   /// Kind defines the kind of report this is about.
90   const /* DiagnosticKind */ int Kind;
91   /// Severity gives the severity of the diagnostic.
92   const DiagnosticSeverity Severity;
93
94 public:
95   DiagnosticInfo(/* DiagnosticKind */ int Kind, DiagnosticSeverity Severity)
96       : Kind(Kind), Severity(Severity) {}
97
98   virtual ~DiagnosticInfo() {}
99
100   /* DiagnosticKind */ int getKind() const { return Kind; }
101   DiagnosticSeverity getSeverity() const { return Severity; }
102
103   /// Print using the given \p DP a user-friendly message.
104   /// This is the default message that will be printed to the user.
105   /// It is used when the frontend does not directly take advantage
106   /// of the information contained in fields of the subclasses.
107   /// The printed message must not end with '.' nor start with a severity
108   /// keyword.
109   virtual void print(DiagnosticPrinter &DP) const = 0;
110 };
111
112 typedef std::function<void(const DiagnosticInfo &)> DiagnosticHandlerFunction;
113
114 /// Diagnostic information for inline asm reporting.
115 /// This is basically a message and an optional location.
116 class DiagnosticInfoInlineAsm : public DiagnosticInfo {
117 private:
118   /// Optional line information. 0 if not set.
119   unsigned LocCookie;
120   /// Message to be reported.
121   const Twine &MsgStr;
122   /// Optional origin of the problem.
123   const Instruction *Instr;
124
125 public:
126   /// \p MsgStr is the message to be reported to the frontend.
127   /// This class does not copy \p MsgStr, therefore the reference must be valid
128   /// for the whole life time of the Diagnostic.
129   DiagnosticInfoInlineAsm(const Twine &MsgStr,
130                           DiagnosticSeverity Severity = DS_Error)
131       : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(0), MsgStr(MsgStr),
132         Instr(nullptr) {}
133
134   /// \p LocCookie if non-zero gives the line number for this report.
135   /// \p MsgStr gives the message.
136   /// This class does not copy \p MsgStr, therefore the reference must be valid
137   /// for the whole life time of the Diagnostic.
138   DiagnosticInfoInlineAsm(unsigned LocCookie, const Twine &MsgStr,
139                           DiagnosticSeverity Severity = DS_Error)
140       : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie),
141         MsgStr(MsgStr), Instr(nullptr) {}
142
143   /// \p Instr gives the original instruction that triggered the diagnostic.
144   /// \p MsgStr gives the message.
145   /// This class does not copy \p MsgStr, therefore the reference must be valid
146   /// for the whole life time of the Diagnostic.
147   /// Same for \p I.
148   DiagnosticInfoInlineAsm(const Instruction &I, const Twine &MsgStr,
149                           DiagnosticSeverity Severity = DS_Error);
150
151   unsigned getLocCookie() const { return LocCookie; }
152   const Twine &getMsgStr() const { return MsgStr; }
153   const Instruction *getInstruction() const { return Instr; }
154
155   /// \see DiagnosticInfo::print.
156   void print(DiagnosticPrinter &DP) const override;
157
158   static bool classof(const DiagnosticInfo *DI) {
159     return DI->getKind() == DK_InlineAsm;
160   }
161 };
162
163 /// Diagnostic information for stack size etc. reporting.
164 /// This is basically a function and a size.
165 class DiagnosticInfoResourceLimit : public DiagnosticInfo {
166 private:
167   /// The function that is concerned by this resource limit diagnostic.
168   const Function &Fn;
169
170   /// Description of the resource type (e.g. stack size)
171   const char *ResourceName;
172
173   /// The computed size usage
174   uint64_t ResourceSize;
175
176   // Threshould passed
177   uint64_t ResourceLimit;
178
179 public:
180   /// \p The function that is concerned by this stack size diagnostic.
181   /// \p The computed stack size.
182   DiagnosticInfoResourceLimit(const Function &Fn,
183                               const char *ResourceName,
184                               uint64_t ResourceSize,
185                               DiagnosticSeverity Severity = DS_Warning,
186                               DiagnosticKind Kind = DK_ResourceLimit,
187                               uint64_t ResourceLimit = 0)
188       : DiagnosticInfo(Kind, Severity),
189         Fn(Fn),
190         ResourceName(ResourceName),
191         ResourceSize(ResourceSize),
192         ResourceLimit(ResourceLimit) {}
193
194   const Function &getFunction() const { return Fn; }
195   const char *getResourceName() const { return ResourceName; }
196   uint64_t getResourceSize() const { return ResourceSize; }
197   uint64_t getResourceLimit() const { return ResourceLimit; }
198
199   /// \see DiagnosticInfo::print.
200   void print(DiagnosticPrinter &DP) const override;
201
202   static bool classof(const DiagnosticInfo *DI) {
203     return DI->getKind() == DK_ResourceLimit ||
204            DI->getKind() == DK_StackSize;
205   }
206 };
207
208 class DiagnosticInfoStackSize : public DiagnosticInfoResourceLimit {
209 public:
210   DiagnosticInfoStackSize(const Function &Fn,
211                           uint64_t StackSize,
212                           DiagnosticSeverity Severity = DS_Warning,
213                           uint64_t StackLimit = 0)
214     : DiagnosticInfoResourceLimit(Fn, "stack size", StackSize,
215                                   Severity, DK_StackSize, StackLimit) {}
216
217   uint64_t getStackSize() const { return getResourceSize(); }
218   uint64_t getStackLimit() const { return getResourceLimit(); }
219
220   static bool classof(const DiagnosticInfo *DI) {
221     return DI->getKind() == DK_StackSize;
222   }
223 };
224
225 /// Diagnostic information for debug metadata version reporting.
226 /// This is basically a module and a version.
227 class DiagnosticInfoDebugMetadataVersion : public DiagnosticInfo {
228 private:
229   /// The module that is concerned by this debug metadata version diagnostic.
230   const Module &M;
231   /// The actual metadata version.
232   unsigned MetadataVersion;
233
234 public:
235   /// \p The module that is concerned by this debug metadata version diagnostic.
236   /// \p The actual metadata version.
237   DiagnosticInfoDebugMetadataVersion(const Module &M, unsigned MetadataVersion,
238                           DiagnosticSeverity Severity = DS_Warning)
239       : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M),
240         MetadataVersion(MetadataVersion) {}
241
242   const Module &getModule() const { return M; }
243   unsigned getMetadataVersion() const { return MetadataVersion; }
244
245   /// \see DiagnosticInfo::print.
246   void print(DiagnosticPrinter &DP) const override;
247
248   static bool classof(const DiagnosticInfo *DI) {
249     return DI->getKind() == DK_DebugMetadataVersion;
250   }
251 };
252
253 /// Diagnostic information for stripping invalid debug metadata.
254 class DiagnosticInfoIgnoringInvalidDebugMetadata : public DiagnosticInfo {
255 private:
256   /// The module that is concerned by this debug metadata version diagnostic.
257   const Module &M;
258
259 public:
260   /// \p The module that is concerned by this debug metadata version diagnostic.
261   DiagnosticInfoIgnoringInvalidDebugMetadata(
262       const Module &M, DiagnosticSeverity Severity = DS_Warning)
263       : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M) {}
264
265   const Module &getModule() const { return M; }
266
267   /// \see DiagnosticInfo::print.
268   void print(DiagnosticPrinter &DP) const override;
269
270   static bool classof(const DiagnosticInfo *DI) {
271     return DI->getKind() == DK_DebugMetadataInvalid;
272   }
273 };
274
275
276 /// Diagnostic information for the sample profiler.
277 class DiagnosticInfoSampleProfile : public DiagnosticInfo {
278 public:
279   DiagnosticInfoSampleProfile(StringRef FileName, unsigned LineNum,
280                               const Twine &Msg,
281                               DiagnosticSeverity Severity = DS_Error)
282       : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
283         LineNum(LineNum), Msg(Msg) {}
284   DiagnosticInfoSampleProfile(StringRef FileName, const Twine &Msg,
285                               DiagnosticSeverity Severity = DS_Error)
286       : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
287         LineNum(0), Msg(Msg) {}
288   DiagnosticInfoSampleProfile(const Twine &Msg,
289                               DiagnosticSeverity Severity = DS_Error)
290       : DiagnosticInfo(DK_SampleProfile, Severity), LineNum(0), Msg(Msg) {}
291
292   /// \see DiagnosticInfo::print.
293   void print(DiagnosticPrinter &DP) const override;
294
295   static bool classof(const DiagnosticInfo *DI) {
296     return DI->getKind() == DK_SampleProfile;
297   }
298
299   StringRef getFileName() const { return FileName; }
300   unsigned getLineNum() const { return LineNum; }
301   const Twine &getMsg() const { return Msg; }
302
303 private:
304   /// Name of the input file associated with this diagnostic.
305   StringRef FileName;
306
307   /// Line number where the diagnostic occurred. If 0, no line number will
308   /// be emitted in the message.
309   unsigned LineNum;
310
311   /// Message to report.
312   const Twine &Msg;
313 };
314
315 /// Diagnostic information for the PGO profiler.
316 class DiagnosticInfoPGOProfile : public DiagnosticInfo {
317 public:
318   DiagnosticInfoPGOProfile(const char *FileName, const Twine &Msg,
319                            DiagnosticSeverity Severity = DS_Error)
320       : DiagnosticInfo(DK_PGOProfile, Severity), FileName(FileName), Msg(Msg) {}
321
322   /// \see DiagnosticInfo::print.
323   void print(DiagnosticPrinter &DP) const override;
324
325   static bool classof(const DiagnosticInfo *DI) {
326     return DI->getKind() == DK_PGOProfile;
327   }
328
329   const char *getFileName() const { return FileName; }
330   const Twine &getMsg() const { return Msg; }
331
332 private:
333   /// Name of the input file associated with this diagnostic.
334   const char *FileName;
335
336   /// Message to report.
337   const Twine &Msg;
338 };
339
340 /// Common features for diagnostics with an associated DebugLoc
341 class DiagnosticInfoWithDebugLocBase : public DiagnosticInfo {
342 public:
343   /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is
344   /// the location information to use in the diagnostic.
345   DiagnosticInfoWithDebugLocBase(enum DiagnosticKind Kind,
346                                  enum DiagnosticSeverity Severity,
347                                  const Function &Fn,
348                                  const DebugLoc &DLoc)
349       : DiagnosticInfo(Kind, Severity), Fn(Fn), DLoc(DLoc) {}
350
351   /// Return true if location information is available for this diagnostic.
352   bool isLocationAvailable() const;
353
354   /// Return a string with the location information for this diagnostic
355   /// in the format "file:line:col". If location information is not available,
356   /// it returns "<unknown>:0:0".
357   const std::string getLocationStr() const;
358
359   /// Return location information for this diagnostic in three parts:
360   /// the source file name, line number and column.
361   void getLocation(StringRef *Filename, unsigned *Line, unsigned *Column) const;
362
363   const Function &getFunction() const { return Fn; }
364   const DebugLoc &getDebugLoc() const { return DLoc; }
365
366 private:
367   /// Function where this diagnostic is triggered.
368   const Function &Fn;
369
370   /// Debug location where this diagnostic is triggered.
371   DebugLoc DLoc;
372 };
373
374 /// Common features for diagnostics dealing with optimization remarks.
375 class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithDebugLocBase {
376 public:
377   /// \p PassName is the name of the pass emitting this diagnostic.
378   /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is
379   /// the location information to use in the diagnostic. If line table
380   /// information is available, the diagnostic will include the source code
381   /// location. \p Msg is the message to show. Note that this class does not
382   /// copy this message, so this reference must be valid for the whole life time
383   /// of the diagnostic.
384   DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind,
385                                  enum DiagnosticSeverity Severity,
386                                  const char *PassName, const Function &Fn,
387                                  const DebugLoc &DLoc, const Twine &Msg,
388                                  Optional<uint64_t> Hotness = None)
389       : DiagnosticInfoWithDebugLocBase(Kind, Severity, Fn, DLoc),
390         PassName(PassName), Msg(Msg), Hotness(Hotness) {}
391
392   /// \see DiagnosticInfo::print.
393   void print(DiagnosticPrinter &DP) const override;
394
395   /// Return true if this optimization remark is enabled by one of
396   /// of the LLVM command line flags (-pass-remarks, -pass-remarks-missed,
397   /// or -pass-remarks-analysis). Note that this only handles the LLVM
398   /// flags. We cannot access Clang flags from here (they are handled
399   /// in BackendConsumer::OptimizationRemarkHandler).
400   virtual bool isEnabled() const = 0;
401
402   const char *getPassName() const { return PassName; }
403   const Twine &getMsg() const { return Msg; }
404
405   static bool classof(const DiagnosticInfo *DI) {
406     return DI->getKind() >= DK_FirstRemark &&
407            DI->getKind() <= DK_LastRemark;
408   }
409
410 private:
411   /// Name of the pass that triggers this report. If this matches the
412   /// regular expression given in -Rpass=regexp, then the remark will
413   /// be emitted.
414   const char *PassName;
415
416   /// Message to report.
417   const Twine &Msg;
418
419   /// If profile information is available, this is the number of times the
420   /// corresponding code was executed in a profile instrumentation run.
421   Optional<uint64_t> Hotness;
422 };
423
424 /// Diagnostic information for applied optimization remarks.
425 class DiagnosticInfoOptimizationRemark : public DiagnosticInfoOptimizationBase {
426 public:
427   /// \p PassName is the name of the pass emitting this diagnostic. If
428   /// this name matches the regular expression given in -Rpass=, then the
429   /// diagnostic will be emitted. \p Fn is the function where the diagnostic
430   /// is being emitted. \p DLoc is the location information to use in the
431   /// diagnostic. If line table information is available, the diagnostic
432   /// will include the source code location. \p Msg is the message to show.
433   /// Note that this class does not copy this message, so this reference
434   /// must be valid for the whole life time of the diagnostic.
435   DiagnosticInfoOptimizationRemark(const char *PassName, const Function &Fn,
436                                    const DebugLoc &DLoc, const Twine &Msg)
437       : DiagnosticInfoOptimizationBase(DK_OptimizationRemark, DS_Remark,
438                                        PassName, Fn, DLoc, Msg) {}
439
440   static bool classof(const DiagnosticInfo *DI) {
441     return DI->getKind() == DK_OptimizationRemark;
442   }
443
444   /// \see DiagnosticInfoOptimizationBase::isEnabled.
445   bool isEnabled() const override;
446 };
447
448 /// Diagnostic information for missed-optimization remarks.
449 class DiagnosticInfoOptimizationRemarkMissed
450     : public DiagnosticInfoOptimizationBase {
451 public:
452   /// \p PassName is the name of the pass emitting this diagnostic. If
453   /// this name matches the regular expression given in -Rpass-missed=, then the
454   /// diagnostic will be emitted. \p Fn is the function where the diagnostic
455   /// is being emitted. \p DLoc is the location information to use in the
456   /// diagnostic. If line table information is available, the diagnostic
457   /// will include the source code location. \p Msg is the message to show.
458   /// Note that this class does not copy this message, so this reference
459   /// must be valid for the whole life time of the diagnostic.
460   DiagnosticInfoOptimizationRemarkMissed(const char *PassName,
461                                          const Function &Fn,
462                                          const DebugLoc &DLoc, const Twine &Msg,
463                                          Optional<uint64_t> Hotness = None)
464       : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkMissed, DS_Remark,
465                                        PassName, Fn, DLoc, Msg, Hotness) {}
466
467   static bool classof(const DiagnosticInfo *DI) {
468     return DI->getKind() == DK_OptimizationRemarkMissed;
469   }
470
471   /// \see DiagnosticInfoOptimizationBase::isEnabled.
472   bool isEnabled() const override;
473 };
474
475 /// Diagnostic information for optimization analysis remarks.
476 class DiagnosticInfoOptimizationRemarkAnalysis
477     : public DiagnosticInfoOptimizationBase {
478 public:
479   /// \p PassName is the name of the pass emitting this diagnostic. If
480   /// this name matches the regular expression given in -Rpass-analysis=, then
481   /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
482   /// is being emitted. \p DLoc is the location information to use in the
483   /// diagnostic. If line table information is available, the diagnostic will
484   /// include the source code location. \p Msg is the message to show. Note that
485   /// this class does not copy this message, so this reference must be valid for
486   /// the whole life time of the diagnostic.
487   DiagnosticInfoOptimizationRemarkAnalysis(const char *PassName,
488                                            const Function &Fn,
489                                            const DebugLoc &DLoc,
490                                            const Twine &Msg,
491                                            Optional<uint64_t> Hotness = None)
492       : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkAnalysis, DS_Remark,
493                                        PassName, Fn, DLoc, Msg, Hotness) {}
494
495   static bool classof(const DiagnosticInfo *DI) {
496     return DI->getKind() == DK_OptimizationRemarkAnalysis;
497   }
498
499   /// \see DiagnosticInfoOptimizationBase::isEnabled.
500   bool isEnabled() const override;
501
502   static const char *AlwaysPrint;
503
504   bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint; }
505
506 protected:
507   DiagnosticInfoOptimizationRemarkAnalysis(enum DiagnosticKind Kind,
508                                            const char *PassName,
509                                            const Function &Fn,
510                                            const DebugLoc &DLoc,
511                                            const Twine &Msg)
512       : DiagnosticInfoOptimizationBase(Kind, DS_Remark, PassName, Fn, DLoc,
513                                        Msg) {}
514 };
515
516 /// Diagnostic information for optimization analysis remarks related to
517 /// floating-point non-commutativity.
518 class DiagnosticInfoOptimizationRemarkAnalysisFPCommute
519     : public DiagnosticInfoOptimizationRemarkAnalysis {
520 public:
521   /// \p PassName is the name of the pass emitting this diagnostic. If
522   /// this name matches the regular expression given in -Rpass-analysis=, then
523   /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
524   /// is being emitted. \p DLoc is the location information to use in the
525   /// diagnostic. If line table information is available, the diagnostic will
526   /// include the source code location. \p Msg is the message to show. The
527   /// front-end will append its own message related to options that address
528   /// floating-point non-commutativity. Note that this class does not copy this
529   /// message, so this reference must be valid for the whole life time of the
530   /// diagnostic.
531   DiagnosticInfoOptimizationRemarkAnalysisFPCommute(const char *PassName,
532                                                     const Function &Fn,
533                                                     const DebugLoc &DLoc,
534                                                     const Twine &Msg)
535       : DiagnosticInfoOptimizationRemarkAnalysis(
536             DK_OptimizationRemarkAnalysisFPCommute, PassName, Fn, DLoc, Msg) {}
537
538   static bool classof(const DiagnosticInfo *DI) {
539     return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute;
540   }
541 };
542
543 /// Diagnostic information for optimization analysis remarks related to
544 /// pointer aliasing.
545 class DiagnosticInfoOptimizationRemarkAnalysisAliasing
546     : public DiagnosticInfoOptimizationRemarkAnalysis {
547 public:
548   /// \p PassName is the name of the pass emitting this diagnostic. If
549   /// this name matches the regular expression given in -Rpass-analysis=, then
550   /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
551   /// is being emitted. \p DLoc is the location information to use in the
552   /// diagnostic. If line table information is available, the diagnostic will
553   /// include the source code location. \p Msg is the message to show. The
554   /// front-end will append its own message related to options that address
555   /// pointer aliasing legality. Note that this class does not copy this
556   /// message, so this reference must be valid for the whole life time of the
557   /// diagnostic.
558   DiagnosticInfoOptimizationRemarkAnalysisAliasing(const char *PassName,
559                                                    const Function &Fn,
560                                                    const DebugLoc &DLoc,
561                                                    const Twine &Msg)
562       : DiagnosticInfoOptimizationRemarkAnalysis(
563             DK_OptimizationRemarkAnalysisAliasing, PassName, Fn, DLoc, Msg) {}
564
565   static bool classof(const DiagnosticInfo *DI) {
566     return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing;
567   }
568 };
569
570 /// Diagnostic information for machine IR parser.
571 class DiagnosticInfoMIRParser : public DiagnosticInfo {
572   const SMDiagnostic &Diagnostic;
573
574 public:
575   DiagnosticInfoMIRParser(DiagnosticSeverity Severity,
576                           const SMDiagnostic &Diagnostic)
577       : DiagnosticInfo(DK_MIRParser, Severity), Diagnostic(Diagnostic) {}
578
579   const SMDiagnostic &getDiagnostic() const { return Diagnostic; }
580
581   void print(DiagnosticPrinter &DP) const override;
582
583   static bool classof(const DiagnosticInfo *DI) {
584     return DI->getKind() == DK_MIRParser;
585   }
586 };
587
588 // Create wrappers for C Binding types (see CBindingWrapping.h).
589 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef)
590
591 /// Emit an optimization-applied message. \p PassName is the name of the pass
592 /// emitting the message. If -Rpass= is given and \p PassName matches the
593 /// regular expression in -Rpass, then the remark will be emitted. \p Fn is
594 /// the function triggering the remark, \p DLoc is the debug location where
595 /// the diagnostic is generated. \p Msg is the message string to use.
596 void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
597                             const Function &Fn, const DebugLoc &DLoc,
598                             const Twine &Msg);
599
600 /// Emit an optimization-missed message. \p PassName is the name of the
601 /// pass emitting the message. If -Rpass-missed= is given and \p PassName
602 /// matches the regular expression in -Rpass, then the remark will be
603 /// emitted. \p Fn is the function triggering the remark, \p DLoc is the
604 /// debug location where the diagnostic is generated. \p Msg is the
605 /// message string to use.
606 void emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName,
607                                   const Function &Fn, const DebugLoc &DLoc,
608                                   const Twine &Msg);
609
610 /// Emit an optimization analysis remark message. \p PassName is the name of
611 /// the pass emitting the message. If -Rpass-analysis= is given and \p
612 /// PassName matches the regular expression in -Rpass, then the remark will be
613 /// emitted. \p Fn is the function triggering the remark, \p DLoc is the debug
614 /// location where the diagnostic is generated. \p Msg is the message string
615 /// to use.
616 void emitOptimizationRemarkAnalysis(LLVMContext &Ctx, const char *PassName,
617                                     const Function &Fn, const DebugLoc &DLoc,
618                                     const Twine &Msg);
619
620 /// Emit an optimization analysis remark related to messages about
621 /// floating-point non-commutativity. \p PassName is the name of the pass
622 /// emitting the message. If -Rpass-analysis= is given and \p PassName matches
623 /// the regular expression in -Rpass, then the remark will be emitted. \p Fn is
624 /// the function triggering the remark, \p DLoc is the debug location where the
625 /// diagnostic is generated. \p Msg is the message string to use.
626 void emitOptimizationRemarkAnalysisFPCommute(LLVMContext &Ctx,
627                                              const char *PassName,
628                                              const Function &Fn,
629                                              const DebugLoc &DLoc,
630                                              const Twine &Msg);
631
632 /// Emit an optimization analysis remark related to messages about
633 /// pointer aliasing. \p PassName is the name of the pass emitting the message.
634 /// If -Rpass-analysis= is given and \p PassName matches the regular expression
635 /// in -Rpass, then the remark will be emitted. \p Fn is the function triggering
636 /// the remark, \p DLoc is the debug location where the diagnostic is generated.
637 /// \p Msg is the message string to use.
638 void emitOptimizationRemarkAnalysisAliasing(LLVMContext &Ctx,
639                                             const char *PassName,
640                                             const Function &Fn,
641                                             const DebugLoc &DLoc,
642                                             const Twine &Msg);
643
644 /// Diagnostic information for optimization failures.
645 class DiagnosticInfoOptimizationFailure
646     : public DiagnosticInfoOptimizationBase {
647 public:
648   /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is
649   /// the location information to use in the diagnostic. If line table
650   /// information is available, the diagnostic will include the source code
651   /// location. \p Msg is the message to show. Note that this class does not
652   /// copy this message, so this reference must be valid for the whole life time
653   /// of the diagnostic.
654   DiagnosticInfoOptimizationFailure(const Function &Fn, const DebugLoc &DLoc,
655                                     const Twine &Msg)
656       : DiagnosticInfoOptimizationBase(DK_OptimizationFailure, DS_Warning,
657                                        nullptr, Fn, DLoc, Msg) {}
658
659   static bool classof(const DiagnosticInfo *DI) {
660     return DI->getKind() == DK_OptimizationFailure;
661   }
662
663   /// \see DiagnosticInfoOptimizationBase::isEnabled.
664   bool isEnabled() const override;
665 };
666
667 /// Diagnostic information for unsupported feature in backend.
668 class DiagnosticInfoUnsupported
669     : public DiagnosticInfoWithDebugLocBase {
670 private:
671   Twine Msg;
672
673 public:
674   /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is
675   /// the location information to use in the diagnostic. If line table
676   /// information is available, the diagnostic will include the source code
677   /// location. \p Msg is the message to show. Note that this class does not
678   /// copy this message, so this reference must be valid for the whole life time
679   /// of the diagnostic.
680   DiagnosticInfoUnsupported(const Function &Fn, const Twine &Msg,
681                             DebugLoc DLoc = DebugLoc(),
682                             DiagnosticSeverity Severity = DS_Error)
683       : DiagnosticInfoWithDebugLocBase(DK_Unsupported, Severity, Fn, DLoc),
684         Msg(Msg) {}
685
686   static bool classof(const DiagnosticInfo *DI) {
687     return DI->getKind() == DK_Unsupported;
688   }
689
690   const Twine &getMessage() const { return Msg; }
691
692   void print(DiagnosticPrinter &DP) const override;
693 };
694
695 /// Emit a warning when loop vectorization is specified but fails. \p Fn is the
696 /// function triggering the warning, \p DLoc is the debug location where the
697 /// diagnostic is generated. \p Msg is the message string to use.
698 void emitLoopVectorizeWarning(LLVMContext &Ctx, const Function &Fn,
699                               const DebugLoc &DLoc, const Twine &Msg);
700
701 /// Emit a warning when loop interleaving is specified but fails. \p Fn is the
702 /// function triggering the warning, \p DLoc is the debug location where the
703 /// diagnostic is generated. \p Msg is the message string to use.
704 void emitLoopInterleaveWarning(LLVMContext &Ctx, const Function &Fn,
705                                const DebugLoc &DLoc, const Twine &Msg);
706
707 } // end namespace llvm
708
709 #endif // LLVM_IR_DIAGNOSTICINFO_H