]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/IR/DiagnosticInfo.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / 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/SmallVector.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 <algorithm>
27 #include <cstdint>
28 #include <functional>
29 #include <iterator>
30 #include <string>
31
32 namespace llvm {
33
34 // Forward declarations.
35 class DiagnosticPrinter;
36 class Function;
37 class Instruction;
38 class LLVMContext;
39 class Module;
40 class SMDiagnostic;
41
42 /// Defines the different supported severity of a diagnostic.
43 enum DiagnosticSeverity : char {
44   DS_Error,
45   DS_Warning,
46   DS_Remark,
47   // A note attaches additional information to one of the previous diagnostic
48   // types.
49   DS_Note
50 };
51
52 /// Defines the different supported kind of a diagnostic.
53 /// This enum should be extended with a new ID for each added concrete subclass.
54 enum DiagnosticKind {
55   DK_InlineAsm,
56   DK_ResourceLimit,
57   DK_StackSize,
58   DK_Linker,
59   DK_DebugMetadataVersion,
60   DK_DebugMetadataInvalid,
61   DK_ISelFallback,
62   DK_SampleProfile,
63   DK_OptimizationRemark,
64   DK_OptimizationRemarkMissed,
65   DK_OptimizationRemarkAnalysis,
66   DK_OptimizationRemarkAnalysisFPCommute,
67   DK_OptimizationRemarkAnalysisAliasing,
68   DK_OptimizationFailure,
69   DK_FirstRemark = DK_OptimizationRemark,
70   DK_LastRemark = DK_OptimizationFailure,
71   DK_MachineOptimizationRemark,
72   DK_MachineOptimizationRemarkMissed,
73   DK_MachineOptimizationRemarkAnalysis,
74   DK_FirstMachineRemark = DK_MachineOptimizationRemark,
75   DK_LastMachineRemark = DK_MachineOptimizationRemarkAnalysis,
76   DK_MIRParser,
77   DK_PGOProfile,
78   DK_Unsupported,
79   DK_FirstPluginKind
80 };
81
82 /// Get the next available kind ID for a plugin diagnostic.
83 /// Each time this function is called, it returns a different number.
84 /// Therefore, a plugin that wants to "identify" its own classes
85 /// with a dynamic identifier, just have to use this method to get a new ID
86 /// and assign it to each of its classes.
87 /// The returned ID will be greater than or equal to DK_FirstPluginKind.
88 /// Thus, the plugin identifiers will not conflict with the
89 /// DiagnosticKind values.
90 int getNextAvailablePluginDiagnosticKind();
91
92 /// This is the base abstract class for diagnostic reporting in
93 /// the backend.
94 /// The print method must be overloaded by the subclasses to print a
95 /// user-friendly message in the client of the backend (let us call it a
96 /// frontend).
97 class DiagnosticInfo {
98 private:
99   /// Kind defines the kind of report this is about.
100   const /* DiagnosticKind */ int Kind;
101   /// Severity gives the severity of the diagnostic.
102   const DiagnosticSeverity Severity;
103
104   virtual void anchor();
105 public:
106   DiagnosticInfo(/* DiagnosticKind */ int Kind, DiagnosticSeverity Severity)
107       : Kind(Kind), Severity(Severity) {}
108
109   virtual ~DiagnosticInfo() = default;
110
111   /* DiagnosticKind */ int getKind() const { return Kind; }
112   DiagnosticSeverity getSeverity() const { return Severity; }
113
114   /// Print using the given \p DP a user-friendly message.
115   /// This is the default message that will be printed to the user.
116   /// It is used when the frontend does not directly take advantage
117   /// of the information contained in fields of the subclasses.
118   /// The printed message must not end with '.' nor start with a severity
119   /// keyword.
120   virtual void print(DiagnosticPrinter &DP) const = 0;
121 };
122
123 using DiagnosticHandlerFunction = std::function<void(const DiagnosticInfo &)>;
124
125 /// Diagnostic information for inline asm reporting.
126 /// This is basically a message and an optional location.
127 class DiagnosticInfoInlineAsm : public DiagnosticInfo {
128 private:
129   /// Optional line information. 0 if not set.
130   unsigned LocCookie = 0;
131   /// Message to be reported.
132   const Twine &MsgStr;
133   /// Optional origin of the problem.
134   const Instruction *Instr = nullptr;
135
136 public:
137   /// \p MsgStr is the message to be reported to the frontend.
138   /// This class does not copy \p MsgStr, therefore the reference must be valid
139   /// for the whole life time of the Diagnostic.
140   DiagnosticInfoInlineAsm(const Twine &MsgStr,
141                           DiagnosticSeverity Severity = DS_Error)
142       : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr) {}
143
144   /// \p LocCookie if non-zero gives the line number for this report.
145   /// \p MsgStr gives the message.
146   /// This class does not copy \p MsgStr, therefore the reference must be valid
147   /// for the whole life time of the Diagnostic.
148   DiagnosticInfoInlineAsm(unsigned LocCookie, const Twine &MsgStr,
149                           DiagnosticSeverity Severity = DS_Error)
150       : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie),
151         MsgStr(MsgStr) {}
152
153   /// \p Instr gives the original instruction that triggered the diagnostic.
154   /// \p MsgStr gives the message.
155   /// This class does not copy \p MsgStr, therefore the reference must be valid
156   /// for the whole life time of the Diagnostic.
157   /// Same for \p I.
158   DiagnosticInfoInlineAsm(const Instruction &I, const Twine &MsgStr,
159                           DiagnosticSeverity Severity = DS_Error);
160
161   unsigned getLocCookie() const { return LocCookie; }
162   const Twine &getMsgStr() const { return MsgStr; }
163   const Instruction *getInstruction() const { return Instr; }
164
165   /// \see DiagnosticInfo::print.
166   void print(DiagnosticPrinter &DP) const override;
167
168   static bool classof(const DiagnosticInfo *DI) {
169     return DI->getKind() == DK_InlineAsm;
170   }
171 };
172
173 /// Diagnostic information for stack size etc. reporting.
174 /// This is basically a function and a size.
175 class DiagnosticInfoResourceLimit : public DiagnosticInfo {
176 private:
177   /// The function that is concerned by this resource limit diagnostic.
178   const Function &Fn;
179
180   /// Description of the resource type (e.g. stack size)
181   const char *ResourceName;
182
183   /// The computed size usage
184   uint64_t ResourceSize;
185
186   // Threshould passed
187   uint64_t ResourceLimit;
188
189 public:
190   /// \p The function that is concerned by this stack size diagnostic.
191   /// \p The computed stack size.
192   DiagnosticInfoResourceLimit(const Function &Fn, const char *ResourceName,
193                               uint64_t ResourceSize,
194                               DiagnosticSeverity Severity = DS_Warning,
195                               DiagnosticKind Kind = DK_ResourceLimit,
196                               uint64_t ResourceLimit = 0)
197       : DiagnosticInfo(Kind, Severity), Fn(Fn), ResourceName(ResourceName),
198         ResourceSize(ResourceSize), ResourceLimit(ResourceLimit) {}
199
200   const Function &getFunction() const { return Fn; }
201   const char *getResourceName() const { return ResourceName; }
202   uint64_t getResourceSize() const { return ResourceSize; }
203   uint64_t getResourceLimit() const { return ResourceLimit; }
204
205   /// \see DiagnosticInfo::print.
206   void print(DiagnosticPrinter &DP) const override;
207
208   static bool classof(const DiagnosticInfo *DI) {
209     return DI->getKind() == DK_ResourceLimit || DI->getKind() == DK_StackSize;
210   }
211 };
212
213 class DiagnosticInfoStackSize : public DiagnosticInfoResourceLimit {
214   virtual void anchor() override;
215 public:
216   DiagnosticInfoStackSize(const Function &Fn, uint64_t StackSize,
217                           DiagnosticSeverity Severity = DS_Warning,
218                           uint64_t StackLimit = 0)
219       : DiagnosticInfoResourceLimit(Fn, "stack size", StackSize, Severity,
220                                     DK_StackSize, StackLimit) {}
221
222   uint64_t getStackSize() const { return getResourceSize(); }
223   uint64_t getStackLimit() const { return getResourceLimit(); }
224
225   static bool classof(const DiagnosticInfo *DI) {
226     return DI->getKind() == DK_StackSize;
227   }
228 };
229
230 /// Diagnostic information for debug metadata version reporting.
231 /// This is basically a module and a version.
232 class DiagnosticInfoDebugMetadataVersion : public DiagnosticInfo {
233 private:
234   /// The module that is concerned by this debug metadata version diagnostic.
235   const Module &M;
236   /// The actual metadata version.
237   unsigned MetadataVersion;
238
239 public:
240   /// \p The module that is concerned by this debug metadata version diagnostic.
241   /// \p The actual metadata version.
242   DiagnosticInfoDebugMetadataVersion(const Module &M, unsigned MetadataVersion,
243                                      DiagnosticSeverity Severity = DS_Warning)
244       : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M),
245         MetadataVersion(MetadataVersion) {}
246
247   const Module &getModule() const { return M; }
248   unsigned getMetadataVersion() const { return MetadataVersion; }
249
250   /// \see DiagnosticInfo::print.
251   void print(DiagnosticPrinter &DP) const override;
252
253   static bool classof(const DiagnosticInfo *DI) {
254     return DI->getKind() == DK_DebugMetadataVersion;
255   }
256 };
257
258 /// Diagnostic information for stripping invalid debug metadata.
259 class DiagnosticInfoIgnoringInvalidDebugMetadata : public DiagnosticInfo {
260 private:
261   /// The module that is concerned by this debug metadata version diagnostic.
262   const Module &M;
263
264 public:
265   /// \p The module that is concerned by this debug metadata version diagnostic.
266   DiagnosticInfoIgnoringInvalidDebugMetadata(
267       const Module &M, DiagnosticSeverity Severity = DS_Warning)
268       : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M) {}
269
270   const Module &getModule() const { return M; }
271
272   /// \see DiagnosticInfo::print.
273   void print(DiagnosticPrinter &DP) const override;
274
275   static bool classof(const DiagnosticInfo *DI) {
276     return DI->getKind() == DK_DebugMetadataInvalid;
277   }
278 };
279
280 /// Diagnostic information for the sample profiler.
281 class DiagnosticInfoSampleProfile : public DiagnosticInfo {
282 public:
283   DiagnosticInfoSampleProfile(StringRef FileName, unsigned LineNum,
284                               const Twine &Msg,
285                               DiagnosticSeverity Severity = DS_Error)
286       : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
287         LineNum(LineNum), Msg(Msg) {}
288   DiagnosticInfoSampleProfile(StringRef FileName, const Twine &Msg,
289                               DiagnosticSeverity Severity = DS_Error)
290       : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
291         Msg(Msg) {}
292   DiagnosticInfoSampleProfile(const Twine &Msg,
293                               DiagnosticSeverity Severity = DS_Error)
294       : DiagnosticInfo(DK_SampleProfile, Severity), Msg(Msg) {}
295
296   /// \see DiagnosticInfo::print.
297   void print(DiagnosticPrinter &DP) const override;
298
299   static bool classof(const DiagnosticInfo *DI) {
300     return DI->getKind() == DK_SampleProfile;
301   }
302
303   StringRef getFileName() const { return FileName; }
304   unsigned getLineNum() const { return LineNum; }
305   const Twine &getMsg() const { return Msg; }
306
307 private:
308   /// Name of the input file associated with this diagnostic.
309   StringRef FileName;
310
311   /// Line number where the diagnostic occurred. If 0, no line number will
312   /// be emitted in the message.
313   unsigned LineNum = 0;
314
315   /// Message to report.
316   const Twine &Msg;
317 };
318
319 /// Diagnostic information for the PGO profiler.
320 class DiagnosticInfoPGOProfile : public DiagnosticInfo {
321 public:
322   DiagnosticInfoPGOProfile(const char *FileName, const Twine &Msg,
323                            DiagnosticSeverity Severity = DS_Error)
324       : DiagnosticInfo(DK_PGOProfile, Severity), FileName(FileName), Msg(Msg) {}
325
326   /// \see DiagnosticInfo::print.
327   void print(DiagnosticPrinter &DP) const override;
328
329   static bool classof(const DiagnosticInfo *DI) {
330     return DI->getKind() == DK_PGOProfile;
331   }
332
333   const char *getFileName() const { return FileName; }
334   const Twine &getMsg() const { return Msg; }
335
336 private:
337   /// Name of the input file associated with this diagnostic.
338   const char *FileName;
339
340   /// Message to report.
341   const Twine &Msg;
342 };
343
344 class DiagnosticLocation {
345   DIFile *File = nullptr;
346   unsigned Line = 0;
347   unsigned Column = 0;
348
349 public:
350   DiagnosticLocation() = default;
351   DiagnosticLocation(const DebugLoc &DL);
352   DiagnosticLocation(const DISubprogram *SP);
353
354   bool isValid() const { return File; }
355   /// Return the full path to the file.
356   std::string getAbsolutePath() const;
357   /// Return the file name relative to the compilation directory.
358   StringRef getRelativePath() const;
359   unsigned getLine() const { return Line; }
360   unsigned getColumn() const { return Column; }
361 };
362
363 /// Common features for diagnostics with an associated location.
364 class DiagnosticInfoWithLocationBase : public DiagnosticInfo {
365   virtual void anchor() override;
366 public:
367   /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
368   /// the location information to use in the diagnostic.
369   DiagnosticInfoWithLocationBase(enum DiagnosticKind Kind,
370                                  enum DiagnosticSeverity Severity,
371                                  const Function &Fn,
372                                  const DiagnosticLocation &Loc)
373       : DiagnosticInfo(Kind, Severity), Fn(Fn), Loc(Loc) {}
374
375   /// Return true if location information is available for this diagnostic.
376   bool isLocationAvailable() const { return Loc.isValid(); }
377
378   /// Return a string with the location information for this diagnostic
379   /// in the format "file:line:col". If location information is not available,
380   /// it returns "<unknown>:0:0".
381   const std::string getLocationStr() const;
382
383   /// Return location information for this diagnostic in three parts:
384   /// the relative source file path, line number and column.
385   void getLocation(StringRef &RelativePath, unsigned &Line,
386                    unsigned &Column) const;
387
388   /// Return the absolute path tot the file.
389   std::string getAbsolutePath() const;
390   
391   const Function &getFunction() const { return Fn; }
392   DiagnosticLocation getLocation() const { return Loc; }
393
394 private:
395   /// Function where this diagnostic is triggered.
396   const Function &Fn;
397
398   /// Debug location where this diagnostic is triggered.
399   DiagnosticLocation Loc;
400 };
401
402 /// Common features for diagnostics dealing with optimization remarks
403 /// that are used by both IR and MIR passes.
404 class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithLocationBase {
405 public:
406   /// Used to set IsVerbose via the stream interface.
407   struct setIsVerbose {};
408
409   /// When an instance of this is inserted into the stream, the arguments
410   /// following will not appear in the remark printed in the compiler output
411   /// (-Rpass) but only in the optimization record file
412   /// (-fsave-optimization-record).
413   struct setExtraArgs {};
414
415   /// Used in the streaming interface as the general argument type.  It
416   /// internally converts everything into a key-value pair.
417   struct Argument {
418     std::string Key;
419     std::string Val;
420     // If set, the debug location corresponding to the value.
421     DiagnosticLocation Loc;
422
423     explicit Argument(StringRef Str = "") : Key("String"), Val(Str) {}
424     Argument(StringRef Key, const Value *V);
425     Argument(StringRef Key, const Type *T);
426     Argument(StringRef Key, StringRef S);
427     Argument(StringRef Key, const char *S) : Argument(Key, StringRef(S)) {};
428     Argument(StringRef Key, int N);
429     Argument(StringRef Key, float N);
430     Argument(StringRef Key, long N);
431     Argument(StringRef Key, long long N);
432     Argument(StringRef Key, unsigned N);
433     Argument(StringRef Key, unsigned long N);
434     Argument(StringRef Key, unsigned long long N);
435     Argument(StringRef Key, bool B) : Key(Key), Val(B ? "true" : "false") {}
436     Argument(StringRef Key, DebugLoc dl);
437   };
438
439   /// \p PassName is the name of the pass emitting this diagnostic. \p
440   /// RemarkName is a textual identifier for the remark (single-word,
441   /// camel-case). \p Fn is the function where the diagnostic is being emitted.
442   /// \p Loc is the location information to use in the diagnostic. If line table
443   /// information is available, the diagnostic will include the source code
444   /// location.
445   DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind,
446                                  enum DiagnosticSeverity Severity,
447                                  const char *PassName, StringRef RemarkName,
448                                  const Function &Fn,
449                                  const DiagnosticLocation &Loc)
450       : DiagnosticInfoWithLocationBase(Kind, Severity, Fn, Loc),
451         PassName(PassName), RemarkName(RemarkName) {}
452
453   void insert(StringRef S);
454   void insert(Argument A);
455   void insert(setIsVerbose V);
456   void insert(setExtraArgs EA);
457
458   /// \see DiagnosticInfo::print.
459   void print(DiagnosticPrinter &DP) const override;
460
461   /// Return true if this optimization remark is enabled by one of
462   /// of the LLVM command line flags (-pass-remarks, -pass-remarks-missed,
463   /// or -pass-remarks-analysis). Note that this only handles the LLVM
464   /// flags. We cannot access Clang flags from here (they are handled
465   /// in BackendConsumer::OptimizationRemarkHandler).
466   virtual bool isEnabled() const = 0;
467
468   StringRef getPassName() const { return PassName; }
469   std::string getMsg() const;
470   Optional<uint64_t> getHotness() const { return Hotness; }
471   void setHotness(Optional<uint64_t> H) { Hotness = H; }
472
473   bool isVerbose() const { return IsVerbose; }
474
475   static bool classof(const DiagnosticInfo *DI) {
476     return (DI->getKind() >= DK_FirstRemark &&
477             DI->getKind() <= DK_LastRemark) ||
478            (DI->getKind() >= DK_FirstMachineRemark &&
479             DI->getKind() <= DK_LastMachineRemark);
480   }
481
482   bool isPassed() const {
483     return (getKind() == DK_OptimizationRemark ||
484             getKind() == DK_MachineOptimizationRemark);
485   }
486
487   bool isMissed() const {
488     return (getKind() == DK_OptimizationRemarkMissed ||
489             getKind() == DK_MachineOptimizationRemarkMissed);
490   }
491
492   bool isAnalysis() const {
493     return (getKind() == DK_OptimizationRemarkAnalysis ||
494             getKind() == DK_MachineOptimizationRemarkAnalysis);
495   }
496
497 protected:
498   /// Name of the pass that triggers this report. If this matches the
499   /// regular expression given in -Rpass=regexp, then the remark will
500   /// be emitted.
501   const char *PassName;
502
503   /// Textual identifier for the remark (single-word, camel-case). Can be used
504   /// by external tools reading the YAML output file for optimization remarks to
505   /// identify the remark.
506   StringRef RemarkName;
507
508   /// If profile information is available, this is the number of times the
509   /// corresponding code was executed in a profile instrumentation run.
510   Optional<uint64_t> Hotness;
511
512   /// Arguments collected via the streaming interface.
513   SmallVector<Argument, 4> Args;
514
515   /// The remark is expected to be noisy.
516   bool IsVerbose = false;
517
518   /// If positive, the index of the first argument that only appear in
519   /// the optimization records and not in the remark printed in the compiler
520   /// output.
521   int FirstExtraArgIndex = -1;
522
523   friend struct yaml::MappingTraits<DiagnosticInfoOptimizationBase *>;
524 };
525
526 /// Allow the insertion operator to return the actual remark type rather than a
527 /// common base class.  This allows returning the result of the insertion
528 /// directly by value, e.g. return OptimizationRemarkAnalysis(...) << "blah".
529 template <class RemarkT>
530 RemarkT &
531 operator<<(RemarkT &R,
532            typename std::enable_if<
533                std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
534                StringRef>::type S) {
535   R.insert(S);
536   return R;
537 }
538
539 /// Also allow r-value for the remark to allow insertion into a
540 /// temporarily-constructed remark.
541 template <class RemarkT>
542 RemarkT &
543 operator<<(RemarkT &&R,
544            typename std::enable_if<
545                std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
546                StringRef>::type S) {
547   R.insert(S);
548   return R;
549 }
550
551 template <class RemarkT>
552 RemarkT &
553 operator<<(RemarkT &R,
554            typename std::enable_if<
555                std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
556                DiagnosticInfoOptimizationBase::Argument>::type A) {
557   R.insert(A);
558   return R;
559 }
560
561 template <class RemarkT>
562 RemarkT &
563 operator<<(RemarkT &&R,
564            typename std::enable_if<
565                std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
566                DiagnosticInfoOptimizationBase::Argument>::type A) {
567   R.insert(A);
568   return R;
569 }
570
571 template <class RemarkT>
572 RemarkT &
573 operator<<(RemarkT &R,
574            typename std::enable_if<
575                std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
576                DiagnosticInfoOptimizationBase::setIsVerbose>::type V) {
577   R.insert(V);
578   return R;
579 }
580
581 template <class RemarkT>
582 RemarkT &
583 operator<<(RemarkT &&R,
584            typename std::enable_if<
585                std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
586                DiagnosticInfoOptimizationBase::setIsVerbose>::type V) {
587   R.insert(V);
588   return R;
589 }
590
591 template <class RemarkT>
592 RemarkT &
593 operator<<(RemarkT &R,
594            typename std::enable_if<
595                std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
596                DiagnosticInfoOptimizationBase::setExtraArgs>::type EA) {
597   R.insert(EA);
598   return R;
599 }
600
601 /// Common features for diagnostics dealing with optimization remarks
602 /// that are used by IR passes.
603 class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase {
604   virtual void anchor() override;
605 public:
606   /// \p PassName is the name of the pass emitting this diagnostic. \p
607   /// RemarkName is a textual identifier for the remark (single-word,
608   /// camel-case). \p Fn is the function where the diagnostic is being emitted.
609   /// \p Loc is the location information to use in the diagnostic. If line table
610   /// information is available, the diagnostic will include the source code
611   /// location. \p CodeRegion is IR value (currently basic block) that the
612   /// optimization operates on. This is currently used to provide run-time
613   /// hotness information with PGO.
614   DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
615                                enum DiagnosticSeverity Severity,
616                                const char *PassName, StringRef RemarkName,
617                                const Function &Fn,
618                                const DiagnosticLocation &Loc,
619                                const Value *CodeRegion = nullptr)
620       : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, RemarkName, Fn,
621                                        Loc),
622         CodeRegion(CodeRegion) {}
623
624   /// This is ctor variant allows a pass to build an optimization remark
625   /// from an existing remark.
626   ///
627   /// This is useful when a transformation pass (e.g LV) wants to emit a remark
628   /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
629   /// remark.  The string \p Prepend will be emitted before the original
630   /// message.
631   DiagnosticInfoIROptimization(const char *PassName, StringRef Prepend,
632                                const DiagnosticInfoIROptimization &Orig)
633       : DiagnosticInfoOptimizationBase(
634             (DiagnosticKind)Orig.getKind(), Orig.getSeverity(), PassName,
635             Orig.RemarkName, Orig.getFunction(), Orig.getLocation()),
636         CodeRegion(Orig.getCodeRegion()) {
637     *this << Prepend;
638     std::copy(Orig.Args.begin(), Orig.Args.end(), std::back_inserter(Args));
639   }
640
641   /// Legacy interface.
642   /// \p PassName is the name of the pass emitting this diagnostic.
643   /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
644   /// the location information to use in the diagnostic. If line table
645   /// information is available, the diagnostic will include the source code
646   /// location. \p Msg is the message to show. Note that this class does not
647   /// copy this message, so this reference must be valid for the whole life time
648   /// of the diagnostic.
649   DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
650                                enum DiagnosticSeverity Severity,
651                                const char *PassName, const Function &Fn,
652                                const DiagnosticLocation &Loc, const Twine &Msg)
653       : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, "", Fn, Loc) {
654     *this << Msg.str();
655   }
656
657   const Value *getCodeRegion() const { return CodeRegion; }
658
659   static bool classof(const DiagnosticInfo *DI) {
660     return DI->getKind() >= DK_FirstRemark && DI->getKind() <= DK_LastRemark;
661   }
662
663 private:
664   /// The IR value (currently basic block) that the optimization operates on.
665   /// This is currently used to provide run-time hotness information with PGO.
666   const Value *CodeRegion;
667 };
668
669 /// Diagnostic information for applied optimization remarks.
670 class OptimizationRemark : public DiagnosticInfoIROptimization {
671 public:
672   /// \p PassName is the name of the pass emitting this diagnostic. If this name
673   /// matches the regular expression given in -Rpass=, then the diagnostic will
674   /// be emitted. \p RemarkName is a textual identifier for the remark (single-
675   /// word, camel-case). \p Loc is the debug location and \p CodeRegion is the
676   /// region that the optimization operates on (currently only block is
677   /// supported).
678   OptimizationRemark(const char *PassName, StringRef RemarkName,
679                      const DiagnosticLocation &Loc, const Value *CodeRegion);
680
681   /// Same as above, but the debug location and code region are derived from \p
682   /// Instr.
683   OptimizationRemark(const char *PassName, StringRef RemarkName,
684                      const Instruction *Inst);
685
686   /// Same as above, but the debug location and code region are derived from \p
687   /// Func.
688   OptimizationRemark(const char *PassName, StringRef RemarkName,
689                      const Function *Func);
690
691   static bool classof(const DiagnosticInfo *DI) {
692     return DI->getKind() == DK_OptimizationRemark;
693   }
694
695   /// \see DiagnosticInfoOptimizationBase::isEnabled.
696   bool isEnabled() const override;
697
698 private:
699   /// This is deprecated now and only used by the function API below.
700   /// \p PassName is the name of the pass emitting this diagnostic. If
701   /// this name matches the regular expression given in -Rpass=, then the
702   /// diagnostic will be emitted. \p Fn is the function where the diagnostic
703   /// is being emitted. \p Loc is the location information to use in the
704   /// diagnostic. If line table information is available, the diagnostic
705   /// will include the source code location. \p Msg is the message to show.
706   /// Note that this class does not copy this message, so this reference
707   /// must be valid for the whole life time of the diagnostic.
708   OptimizationRemark(const char *PassName, const Function &Fn,
709                      const DiagnosticLocation &Loc, const Twine &Msg)
710       : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
711                                      Fn, Loc, Msg) {}
712 };
713
714 /// Diagnostic information for missed-optimization remarks.
715 class OptimizationRemarkMissed : public DiagnosticInfoIROptimization {
716 public:
717   /// \p PassName is the name of the pass emitting this diagnostic. If this name
718   /// matches the regular expression given in -Rpass-missed=, then the
719   /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
720   /// remark (single-word, camel-case). \p Loc is the debug location and \p
721   /// CodeRegion is the region that the optimization operates on (currently only
722   /// block is supported).
723   OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
724                            const DiagnosticLocation &Loc,
725                            const Value *CodeRegion);
726
727   /// Same as above but \p Inst is used to derive code region and debug
728   /// location.
729   OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
730                            const Instruction *Inst);
731
732   static bool classof(const DiagnosticInfo *DI) {
733     return DI->getKind() == DK_OptimizationRemarkMissed;
734   }
735
736   /// \see DiagnosticInfoOptimizationBase::isEnabled.
737   bool isEnabled() const override;
738
739 private:
740   /// This is deprecated now and only used by the function API below.
741   /// \p PassName is the name of the pass emitting this diagnostic. If
742   /// this name matches the regular expression given in -Rpass-missed=, then the
743   /// diagnostic will be emitted. \p Fn is the function where the diagnostic
744   /// is being emitted. \p Loc is the location information to use in the
745   /// diagnostic. If line table information is available, the diagnostic
746   /// will include the source code location. \p Msg is the message to show.
747   /// Note that this class does not copy this message, so this reference
748   /// must be valid for the whole life time of the diagnostic.
749   OptimizationRemarkMissed(const char *PassName, const Function &Fn,
750                            const DiagnosticLocation &Loc, const Twine &Msg)
751       : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
752                                      PassName, Fn, Loc, Msg) {}
753 };
754
755 /// Diagnostic information for optimization analysis remarks.
756 class OptimizationRemarkAnalysis : public DiagnosticInfoIROptimization {
757 public:
758   /// \p PassName is the name of the pass emitting this diagnostic. If this name
759   /// matches the regular expression given in -Rpass-analysis=, then the
760   /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
761   /// remark (single-word, camel-case). \p Loc is the debug location and \p
762   /// CodeRegion is the region that the optimization operates on (currently only
763   /// block is supported).
764   OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
765                              const DiagnosticLocation &Loc,
766                              const Value *CodeRegion);
767
768   /// This is ctor variant allows a pass to build an optimization remark
769   /// from an existing remark.
770   ///
771   /// This is useful when a transformation pass (e.g LV) wants to emit a remark
772   /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
773   /// remark.  The string \p Prepend will be emitted before the original
774   /// message.
775   OptimizationRemarkAnalysis(const char *PassName, StringRef Prepend,
776                              const OptimizationRemarkAnalysis &Orig)
777       : DiagnosticInfoIROptimization(PassName, Prepend, Orig) {}
778
779   /// Same as above but \p Inst is used to derive code region and debug
780   /// location.
781   OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
782                              const Instruction *Inst);
783
784   static bool classof(const DiagnosticInfo *DI) {
785     return DI->getKind() == DK_OptimizationRemarkAnalysis;
786   }
787
788   /// \see DiagnosticInfoOptimizationBase::isEnabled.
789   bool isEnabled() const override;
790
791   static const char *AlwaysPrint;
792
793   bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint; }
794
795 protected:
796   OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
797                              const Function &Fn, const DiagnosticLocation &Loc,
798                              const Twine &Msg)
799       : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, Fn, Loc, Msg) {}
800
801   OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
802                              StringRef RemarkName,
803                              const DiagnosticLocation &Loc,
804                              const Value *CodeRegion);
805
806 private:
807   /// This is deprecated now and only used by the function API below.
808   /// \p PassName is the name of the pass emitting this diagnostic. If
809   /// this name matches the regular expression given in -Rpass-analysis=, then
810   /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
811   /// is being emitted. \p Loc is the location information to use in the
812   /// diagnostic. If line table information is available, the diagnostic will
813   /// include the source code location. \p Msg is the message to show. Note that
814   /// this class does not copy this message, so this reference must be valid for
815   /// the whole life time of the diagnostic.
816   OptimizationRemarkAnalysis(const char *PassName, const Function &Fn,
817                              const DiagnosticLocation &Loc, const Twine &Msg)
818       : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
819                                      PassName, Fn, Loc, Msg) {}
820 };
821
822 /// Diagnostic information for optimization analysis remarks related to
823 /// floating-point non-commutativity.
824 class OptimizationRemarkAnalysisFPCommute : public OptimizationRemarkAnalysis {
825   virtual void anchor();
826 public:
827   /// \p PassName is the name of the pass emitting this diagnostic. If this name
828   /// matches the regular expression given in -Rpass-analysis=, then the
829   /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
830   /// remark (single-word, camel-case). \p Loc is the debug location and \p
831   /// CodeRegion is the region that the optimization operates on (currently only
832   /// block is supported). The front-end will append its own message related to
833   /// options that address floating-point non-commutativity.
834   OptimizationRemarkAnalysisFPCommute(const char *PassName,
835                                       StringRef RemarkName,
836                                       const DiagnosticLocation &Loc,
837                                       const Value *CodeRegion)
838       : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
839                                    PassName, RemarkName, Loc, CodeRegion) {}
840
841   static bool classof(const DiagnosticInfo *DI) {
842     return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute;
843   }
844
845 private:
846   /// This is deprecated now and only used by the function API below.
847   /// \p PassName is the name of the pass emitting this diagnostic. If
848   /// this name matches the regular expression given in -Rpass-analysis=, then
849   /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
850   /// is being emitted. \p Loc is the location information to use in the
851   /// diagnostic. If line table information is available, the diagnostic will
852   /// include the source code location. \p Msg is the message to show. The
853   /// front-end will append its own message related to options that address
854   /// floating-point non-commutativity. Note that this class does not copy this
855   /// message, so this reference must be valid for the whole life time of the
856   /// diagnostic.
857   OptimizationRemarkAnalysisFPCommute(const char *PassName, const Function &Fn,
858                                       const DiagnosticLocation &Loc,
859                                       const Twine &Msg)
860       : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
861                                    PassName, Fn, Loc, Msg) {}
862 };
863
864 /// Diagnostic information for optimization analysis remarks related to
865 /// pointer aliasing.
866 class OptimizationRemarkAnalysisAliasing : public OptimizationRemarkAnalysis {
867   virtual void anchor();
868 public:
869   /// \p PassName is the name of the pass emitting this diagnostic. If this name
870   /// matches the regular expression given in -Rpass-analysis=, then the
871   /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
872   /// remark (single-word, camel-case). \p Loc is the debug location and \p
873   /// CodeRegion is the region that the optimization operates on (currently only
874   /// block is supported). The front-end will append its own message related to
875   /// options that address pointer aliasing legality.
876   OptimizationRemarkAnalysisAliasing(const char *PassName, StringRef RemarkName,
877                                      const DiagnosticLocation &Loc,
878                                      const Value *CodeRegion)
879       : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
880                                    PassName, RemarkName, Loc, CodeRegion) {}
881
882   static bool classof(const DiagnosticInfo *DI) {
883     return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing;
884   }
885
886 private:
887   /// This is deprecated now and only used by the function API below.
888   /// \p PassName is the name of the pass emitting this diagnostic. If
889   /// this name matches the regular expression given in -Rpass-analysis=, then
890   /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
891   /// is being emitted. \p Loc is the location information to use in the
892   /// diagnostic. If line table information is available, the diagnostic will
893   /// include the source code location. \p Msg is the message to show. The
894   /// front-end will append its own message related to options that address
895   /// pointer aliasing legality. Note that this class does not copy this
896   /// message, so this reference must be valid for the whole life time of the
897   /// diagnostic.
898   OptimizationRemarkAnalysisAliasing(const char *PassName, const Function &Fn,
899                                      const DiagnosticLocation &Loc,
900                                      const Twine &Msg)
901       : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
902                                    PassName, Fn, Loc, Msg) {}
903 };
904
905 /// Diagnostic information for machine IR parser.
906 class DiagnosticInfoMIRParser : public DiagnosticInfo {
907   const SMDiagnostic &Diagnostic;
908
909 public:
910   DiagnosticInfoMIRParser(DiagnosticSeverity Severity,
911                           const SMDiagnostic &Diagnostic)
912       : DiagnosticInfo(DK_MIRParser, Severity), Diagnostic(Diagnostic) {}
913
914   const SMDiagnostic &getDiagnostic() const { return Diagnostic; }
915
916   void print(DiagnosticPrinter &DP) const override;
917
918   static bool classof(const DiagnosticInfo *DI) {
919     return DI->getKind() == DK_MIRParser;
920   }
921 };
922
923 /// Diagnostic information for ISel fallback path.
924 class DiagnosticInfoISelFallback : public DiagnosticInfo {
925   /// The function that is concerned by this diagnostic.
926   const Function &Fn;
927
928 public:
929   DiagnosticInfoISelFallback(const Function &Fn,
930                              DiagnosticSeverity Severity = DS_Warning)
931       : DiagnosticInfo(DK_ISelFallback, Severity), Fn(Fn) {}
932
933   const Function &getFunction() const { return Fn; }
934
935   void print(DiagnosticPrinter &DP) const override;
936
937   static bool classof(const DiagnosticInfo *DI) {
938     return DI->getKind() == DK_ISelFallback;
939   }
940 };
941
942 // Create wrappers for C Binding types (see CBindingWrapping.h).
943 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef)
944
945 /// Diagnostic information for optimization failures.
946 class DiagnosticInfoOptimizationFailure : public DiagnosticInfoIROptimization {
947 public:
948   /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
949   /// the location information to use in the diagnostic. If line table
950   /// information is available, the diagnostic will include the source code
951   /// location. \p Msg is the message to show. Note that this class does not
952   /// copy this message, so this reference must be valid for the whole life time
953   /// of the diagnostic.
954   DiagnosticInfoOptimizationFailure(const Function &Fn,
955                                     const DiagnosticLocation &Loc,
956                                     const Twine &Msg)
957       : DiagnosticInfoIROptimization(DK_OptimizationFailure, DS_Warning,
958                                      nullptr, Fn, Loc, Msg) {}
959
960   /// \p PassName is the name of the pass emitting this diagnostic.  \p
961   /// RemarkName is a textual identifier for the remark (single-word,
962   /// camel-case).  \p Loc is the debug location and \p CodeRegion is the
963   /// region that the optimization operates on (currently basic block is
964   /// supported).
965   DiagnosticInfoOptimizationFailure(const char *PassName, StringRef RemarkName,
966                                     const DiagnosticLocation &Loc,
967                                     const Value *CodeRegion);
968
969   static bool classof(const DiagnosticInfo *DI) {
970     return DI->getKind() == DK_OptimizationFailure;
971   }
972
973   /// \see DiagnosticInfoOptimizationBase::isEnabled.
974   bool isEnabled() const override;
975 };
976
977 /// Diagnostic information for unsupported feature in backend.
978 class DiagnosticInfoUnsupported : public DiagnosticInfoWithLocationBase {
979 private:
980   Twine Msg;
981
982 public:
983   /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
984   /// the location information to use in the diagnostic. If line table
985   /// information is available, the diagnostic will include the source code
986   /// location. \p Msg is the message to show. Note that this class does not
987   /// copy this message, so this reference must be valid for the whole life time
988   /// of the diagnostic.
989   DiagnosticInfoUnsupported(
990       const Function &Fn, const Twine &Msg,
991       const DiagnosticLocation &Loc = DiagnosticLocation(),
992       DiagnosticSeverity Severity = DS_Error)
993       : DiagnosticInfoWithLocationBase(DK_Unsupported, Severity, Fn, Loc),
994         Msg(Msg) {}
995
996   static bool classof(const DiagnosticInfo *DI) {
997     return DI->getKind() == DK_Unsupported;
998   }
999
1000   const Twine &getMessage() const { return Msg; }
1001
1002   void print(DiagnosticPrinter &DP) const override;
1003 };
1004
1005 namespace yaml {
1006 template <> struct MappingTraits<DiagnosticInfoOptimizationBase *> {
1007   static void mapping(IO &io, DiagnosticInfoOptimizationBase *&OptDiag);
1008 };
1009 } // namespace yaml
1010
1011 } // end namespace llvm
1012
1013 #endif // LLVM_IR_DIAGNOSTICINFO_H