OSDN Git Service

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