OSDN Git Service

[OptRemark,LDist] RFC: Add hotness attribute
[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       : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkAnalysis, DS_Remark,
492                                        PassName, Fn, DLoc, Msg) {}
493
494   static bool classof(const DiagnosticInfo *DI) {
495     return DI->getKind() == DK_OptimizationRemarkAnalysis;
496   }
497
498   /// \see DiagnosticInfoOptimizationBase::isEnabled.
499   bool isEnabled() const override;
500
501   static const char *AlwaysPrint;
502
503   bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint; }
504
505 protected:
506   DiagnosticInfoOptimizationRemarkAnalysis(enum DiagnosticKind Kind,
507                                            const char *PassName,
508                                            const Function &Fn,
509                                            const DebugLoc &DLoc,
510                                            const Twine &Msg)
511       : DiagnosticInfoOptimizationBase(Kind, DS_Remark, PassName, Fn, DLoc,
512                                        Msg) {}
513 };
514
515 /// Diagnostic information for optimization analysis remarks related to
516 /// floating-point non-commutativity.
517 class DiagnosticInfoOptimizationRemarkAnalysisFPCommute
518     : public DiagnosticInfoOptimizationRemarkAnalysis {
519 public:
520   /// \p PassName is the name of the pass emitting this diagnostic. If
521   /// this name matches the regular expression given in -Rpass-analysis=, then
522   /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
523   /// is being emitted. \p DLoc is the location information to use in the
524   /// diagnostic. If line table information is available, the diagnostic will
525   /// include the source code location. \p Msg is the message to show. The
526   /// front-end will append its own message related to options that address
527   /// floating-point non-commutativity. Note that this class does not copy this
528   /// message, so this reference must be valid for the whole life time of the
529   /// diagnostic.
530   DiagnosticInfoOptimizationRemarkAnalysisFPCommute(const char *PassName,
531                                                     const Function &Fn,
532                                                     const DebugLoc &DLoc,
533                                                     const Twine &Msg)
534       : DiagnosticInfoOptimizationRemarkAnalysis(
535             DK_OptimizationRemarkAnalysisFPCommute, PassName, Fn, DLoc, Msg) {}
536
537   static bool classof(const DiagnosticInfo *DI) {
538     return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute;
539   }
540 };
541
542 /// Diagnostic information for optimization analysis remarks related to
543 /// pointer aliasing.
544 class DiagnosticInfoOptimizationRemarkAnalysisAliasing
545     : public DiagnosticInfoOptimizationRemarkAnalysis {
546 public:
547   /// \p PassName is the name of the pass emitting this diagnostic. If
548   /// this name matches the regular expression given in -Rpass-analysis=, then
549   /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
550   /// is being emitted. \p DLoc is the location information to use in the
551   /// diagnostic. If line table information is available, the diagnostic will
552   /// include the source code location. \p Msg is the message to show. The
553   /// front-end will append its own message related to options that address
554   /// pointer aliasing legality. Note that this class does not copy this
555   /// message, so this reference must be valid for the whole life time of the
556   /// diagnostic.
557   DiagnosticInfoOptimizationRemarkAnalysisAliasing(const char *PassName,
558                                                    const Function &Fn,
559                                                    const DebugLoc &DLoc,
560                                                    const Twine &Msg)
561       : DiagnosticInfoOptimizationRemarkAnalysis(
562             DK_OptimizationRemarkAnalysisAliasing, PassName, Fn, DLoc, Msg) {}
563
564   static bool classof(const DiagnosticInfo *DI) {
565     return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing;
566   }
567 };
568
569 /// Diagnostic information for machine IR parser.
570 class DiagnosticInfoMIRParser : public DiagnosticInfo {
571   const SMDiagnostic &Diagnostic;
572
573 public:
574   DiagnosticInfoMIRParser(DiagnosticSeverity Severity,
575                           const SMDiagnostic &Diagnostic)
576       : DiagnosticInfo(DK_MIRParser, Severity), Diagnostic(Diagnostic) {}
577
578   const SMDiagnostic &getDiagnostic() const { return Diagnostic; }
579
580   void print(DiagnosticPrinter &DP) const override;
581
582   static bool classof(const DiagnosticInfo *DI) {
583     return DI->getKind() == DK_MIRParser;
584   }
585 };
586
587 // Create wrappers for C Binding types (see CBindingWrapping.h).
588 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef)
589
590 /// Emit an optimization-applied message. \p PassName is the name of the pass
591 /// emitting the message. If -Rpass= is given and \p PassName matches the
592 /// regular expression in -Rpass, then the remark will be emitted. \p Fn is
593 /// the function triggering the remark, \p DLoc is the debug location where
594 /// the diagnostic is generated. \p Msg is the message string to use.
595 void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
596                             const Function &Fn, const DebugLoc &DLoc,
597                             const Twine &Msg);
598
599 /// Emit an optimization-missed message. \p PassName is the name of the
600 /// pass emitting the message. If -Rpass-missed= is given and \p PassName
601 /// matches the regular expression in -Rpass, then the remark will be
602 /// emitted. \p Fn is the function triggering the remark, \p DLoc is the
603 /// debug location where the diagnostic is generated. \p Msg is the
604 /// message string to use.
605 void emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName,
606                                   const Function &Fn, const DebugLoc &DLoc,
607                                   const Twine &Msg);
608
609 /// Emit an optimization analysis remark message. \p PassName is the name of
610 /// the pass emitting the message. If -Rpass-analysis= is given and \p
611 /// PassName matches the regular expression in -Rpass, then the remark will be
612 /// emitted. \p Fn is the function triggering the remark, \p DLoc is the debug
613 /// location where the diagnostic is generated. \p Msg is the message string
614 /// to use.
615 void emitOptimizationRemarkAnalysis(LLVMContext &Ctx, const char *PassName,
616                                     const Function &Fn, const DebugLoc &DLoc,
617                                     const Twine &Msg);
618
619 /// Emit an optimization analysis remark related to messages about
620 /// floating-point non-commutativity. \p PassName is the name of the pass
621 /// emitting the message. If -Rpass-analysis= is given and \p PassName matches
622 /// the regular expression in -Rpass, then the remark will be emitted. \p Fn is
623 /// the function triggering the remark, \p DLoc is the debug location where the
624 /// diagnostic is generated. \p Msg is the message string to use.
625 void emitOptimizationRemarkAnalysisFPCommute(LLVMContext &Ctx,
626                                              const char *PassName,
627                                              const Function &Fn,
628                                              const DebugLoc &DLoc,
629                                              const Twine &Msg);
630
631 /// Emit an optimization analysis remark related to messages about
632 /// pointer aliasing. \p PassName is the name of the pass emitting the message.
633 /// If -Rpass-analysis= is given and \p PassName matches the regular expression
634 /// in -Rpass, then the remark will be emitted. \p Fn is the function triggering
635 /// the remark, \p DLoc is the debug location where the diagnostic is generated.
636 /// \p Msg is the message string to use.
637 void emitOptimizationRemarkAnalysisAliasing(LLVMContext &Ctx,
638                                             const char *PassName,
639                                             const Function &Fn,
640                                             const DebugLoc &DLoc,
641                                             const Twine &Msg);
642
643 /// Diagnostic information for optimization failures.
644 class DiagnosticInfoOptimizationFailure
645     : public DiagnosticInfoOptimizationBase {
646 public:
647   /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is
648   /// the location information to use in the diagnostic. If line table
649   /// information is available, the diagnostic will include the source code
650   /// location. \p Msg is the message to show. Note that this class does not
651   /// copy this message, so this reference must be valid for the whole life time
652   /// of the diagnostic.
653   DiagnosticInfoOptimizationFailure(const Function &Fn, const DebugLoc &DLoc,
654                                     const Twine &Msg)
655       : DiagnosticInfoOptimizationBase(DK_OptimizationFailure, DS_Warning,
656                                        nullptr, Fn, DLoc, Msg) {}
657
658   static bool classof(const DiagnosticInfo *DI) {
659     return DI->getKind() == DK_OptimizationFailure;
660   }
661
662   /// \see DiagnosticInfoOptimizationBase::isEnabled.
663   bool isEnabled() const override;
664 };
665
666 /// Diagnostic information for unsupported feature in backend.
667 class DiagnosticInfoUnsupported
668     : public DiagnosticInfoWithDebugLocBase {
669 private:
670   Twine Msg;
671
672 public:
673   /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is
674   /// the location information to use in the diagnostic. If line table
675   /// information is available, the diagnostic will include the source code
676   /// location. \p Msg is the message to show. Note that this class does not
677   /// copy this message, so this reference must be valid for the whole life time
678   /// of the diagnostic.
679   DiagnosticInfoUnsupported(const Function &Fn, const Twine &Msg,
680                             DebugLoc DLoc = DebugLoc(),
681                             DiagnosticSeverity Severity = DS_Error)
682       : DiagnosticInfoWithDebugLocBase(DK_Unsupported, Severity, Fn, DLoc),
683         Msg(Msg) {}
684
685   static bool classof(const DiagnosticInfo *DI) {
686     return DI->getKind() == DK_Unsupported;
687   }
688
689   const Twine &getMessage() const { return Msg; }
690
691   void print(DiagnosticPrinter &DP) const override;
692 };
693
694 /// Emit a warning when loop vectorization is specified but fails. \p Fn is the
695 /// function triggering the warning, \p DLoc is the debug location where the
696 /// diagnostic is generated. \p Msg is the message string to use.
697 void emitLoopVectorizeWarning(LLVMContext &Ctx, const Function &Fn,
698                               const DebugLoc &DLoc, const Twine &Msg);
699
700 /// Emit a warning when loop interleaving is specified but fails. \p Fn is the
701 /// function triggering the warning, \p DLoc is the debug location where the
702 /// diagnostic is generated. \p Msg is the message string to use.
703 void emitLoopInterleaveWarning(LLVMContext &Ctx, const Function &Fn,
704                                const DebugLoc &DLoc, const Twine &Msg);
705
706 } // end namespace llvm
707
708 #endif // LLVM_IR_DIAGNOSTICINFO_H