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