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