Update the error handling of lib/Linker.
[oota-llvm.git] / include / llvm / IR / DiagnosticInfo.h
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-c/Core.h"
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/IR/DebugLoc.h"
21 #include "llvm/IR/Module.h"
22 #include "llvm/Support/Casting.h"
23
24 namespace llvm {
25
26 // Forward declarations.
27 class DiagnosticPrinter;
28 class Function;
29 class Instruction;
30 class LLVMContextImpl;
31 class Twine;
32 class Value;
33 class DebugLoc;
34
35 /// \brief Defines the different supported severity of a diagnostic.
36 enum DiagnosticSeverity {
37   DS_Error,
38   DS_Warning,
39   DS_Remark,
40   // A note attaches additional information to one of the previous diagnostic
41   // types.
42   DS_Note
43 };
44
45 /// \brief Defines the different supported kind of a diagnostic.
46 /// This enum should be extended with a new ID for each added concrete subclass.
47 enum DiagnosticKind {
48   DK_InlineAsm,
49   DK_StackSize,
50   DK_Linker,
51   DK_DebugMetadataVersion,
52   DK_SampleProfile,
53   DK_OptimizationRemark,
54   DK_OptimizationRemarkMissed,
55   DK_OptimizationRemarkAnalysis,
56   DK_OptimizationFailure,
57   DK_FirstPluginKind
58 };
59
60 /// \brief Get the next available kind ID for a plugin diagnostic.
61 /// Each time this function is called, it returns a different number.
62 /// Therefore, a plugin that wants to "identify" its own classes
63 /// with a dynamic identifier, just have to use this method to get a new ID
64 /// and assign it to each of its classes.
65 /// The returned ID will be greater than or equal to DK_FirstPluginKind.
66 /// Thus, the plugin identifiers will not conflict with the
67 /// DiagnosticKind values.
68 int getNextAvailablePluginDiagnosticKind();
69
70 /// \brief This is the base abstract class for diagnostic reporting in
71 /// the backend.
72 /// The print method must be overloaded by the subclasses to print a
73 /// user-friendly message in the client of the backend (let us call it a
74 /// frontend).
75 class DiagnosticInfo {
76 private:
77   /// Kind defines the kind of report this is about.
78   const /* DiagnosticKind */ int Kind;
79   /// Severity gives the severity of the diagnostic.
80   const DiagnosticSeverity Severity;
81
82 public:
83   DiagnosticInfo(/* DiagnosticKind */ int Kind, DiagnosticSeverity Severity)
84       : Kind(Kind), Severity(Severity) {}
85
86   virtual ~DiagnosticInfo() {}
87
88   /* DiagnosticKind */ int getKind() const { return Kind; }
89   DiagnosticSeverity getSeverity() const { return Severity; }
90
91   /// Print using the given \p DP a user-friendly message.
92   /// This is the default message that will be printed to the user.
93   /// It is used when the frontend does not directly take advantage
94   /// of the information contained in fields of the subclasses.
95   /// The printed message must not end with '.' nor start with a severity
96   /// keyword.
97   virtual void print(DiagnosticPrinter &DP) const = 0;
98 };
99
100 /// Diagnostic information for inline asm reporting.
101 /// This is basically a message and an optional location.
102 class DiagnosticInfoInlineAsm : public DiagnosticInfo {
103 private:
104   /// Optional line information. 0 if not set.
105   unsigned LocCookie;
106   /// Message to be reported.
107   const Twine &MsgStr;
108   /// Optional origin of the problem.
109   const Instruction *Instr;
110
111 public:
112   /// \p MsgStr is the message to be reported to the frontend.
113   /// This class does not copy \p MsgStr, therefore the reference must be valid
114   /// for the whole life time of the Diagnostic.
115   DiagnosticInfoInlineAsm(const Twine &MsgStr,
116                           DiagnosticSeverity Severity = DS_Error)
117       : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(0), MsgStr(MsgStr),
118         Instr(nullptr) {}
119
120   /// \p LocCookie if non-zero gives the line number for this report.
121   /// \p MsgStr gives the message.
122   /// This class does not copy \p MsgStr, therefore the reference must be valid
123   /// for the whole life time of the Diagnostic.
124   DiagnosticInfoInlineAsm(unsigned LocCookie, const Twine &MsgStr,
125                           DiagnosticSeverity Severity = DS_Error)
126       : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie),
127         MsgStr(MsgStr), Instr(nullptr) {}
128
129   /// \p Instr gives the original instruction that triggered the diagnostic.
130   /// \p MsgStr gives the message.
131   /// This class does not copy \p MsgStr, therefore the reference must be valid
132   /// for the whole life time of the Diagnostic.
133   /// Same for \p I.
134   DiagnosticInfoInlineAsm(const Instruction &I, const Twine &MsgStr,
135                           DiagnosticSeverity Severity = DS_Error);
136
137   unsigned getLocCookie() const { return LocCookie; }
138   const Twine &getMsgStr() const { return MsgStr; }
139   const Instruction *getInstruction() const { return Instr; }
140
141   /// \see DiagnosticInfo::print.
142   void print(DiagnosticPrinter &DP) const override;
143
144   static bool classof(const DiagnosticInfo *DI) {
145     return DI->getKind() == DK_InlineAsm;
146   }
147 };
148
149 /// Diagnostic information for stack size reporting.
150 /// This is basically a function and a size.
151 class DiagnosticInfoStackSize : public DiagnosticInfo {
152 private:
153   /// The function that is concerned by this stack size diagnostic.
154   const Function &Fn;
155   /// The computed stack size.
156   unsigned StackSize;
157
158 public:
159   /// \p The function that is concerned by this stack size diagnostic.
160   /// \p The computed stack size.
161   DiagnosticInfoStackSize(const Function &Fn, unsigned StackSize,
162                           DiagnosticSeverity Severity = DS_Warning)
163       : DiagnosticInfo(DK_StackSize, Severity), Fn(Fn), StackSize(StackSize) {}
164
165   const Function &getFunction() const { return Fn; }
166   unsigned getStackSize() const { return StackSize; }
167
168   /// \see DiagnosticInfo::print.
169   void print(DiagnosticPrinter &DP) const override;
170
171   static bool classof(const DiagnosticInfo *DI) {
172     return DI->getKind() == DK_StackSize;
173   }
174 };
175
176 /// Diagnostic information for debug metadata version reporting.
177 /// This is basically a module and a version.
178 class DiagnosticInfoDebugMetadataVersion : public DiagnosticInfo {
179 private:
180   /// The module that is concerned by this debug metadata version diagnostic.
181   const Module &M;
182   /// The actual metadata version.
183   unsigned MetadataVersion;
184
185 public:
186   /// \p The module that is concerned by this debug metadata version diagnostic.
187   /// \p The actual metadata version.
188   DiagnosticInfoDebugMetadataVersion(const Module &M, unsigned MetadataVersion,
189                           DiagnosticSeverity Severity = DS_Warning)
190       : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M),
191         MetadataVersion(MetadataVersion) {}
192
193   const Module &getModule() const { return M; }
194   unsigned getMetadataVersion() const { return MetadataVersion; }
195
196   /// \see DiagnosticInfo::print.
197   void print(DiagnosticPrinter &DP) const override;
198
199   static bool classof(const DiagnosticInfo *DI) {
200     return DI->getKind() == DK_DebugMetadataVersion;
201   }
202 };
203
204 /// Diagnostic information for the sample profiler.
205 class DiagnosticInfoSampleProfile : public DiagnosticInfo {
206 public:
207   DiagnosticInfoSampleProfile(const char *FileName, unsigned LineNum,
208                               const Twine &Msg,
209                               DiagnosticSeverity Severity = DS_Error)
210       : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
211         LineNum(LineNum), Msg(Msg) {}
212   DiagnosticInfoSampleProfile(const char *FileName, const Twine &Msg,
213                               DiagnosticSeverity Severity = DS_Error)
214       : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
215         LineNum(0), Msg(Msg) {}
216   DiagnosticInfoSampleProfile(const Twine &Msg,
217                               DiagnosticSeverity Severity = DS_Error)
218       : DiagnosticInfo(DK_SampleProfile, Severity), FileName(nullptr),
219         LineNum(0), Msg(Msg) {}
220
221   /// \see DiagnosticInfo::print.
222   void print(DiagnosticPrinter &DP) const override;
223
224   static bool classof(const DiagnosticInfo *DI) {
225     return DI->getKind() == DK_SampleProfile;
226   }
227
228   const char *getFileName() const { return FileName; }
229   unsigned getLineNum() const { return LineNum; }
230   const Twine &getMsg() const { return Msg; }
231
232 private:
233   /// Name of the input file associated with this diagnostic.
234   const char *FileName;
235
236   /// Line number where the diagnostic occurred. If 0, no line number will
237   /// be emitted in the message.
238   unsigned LineNum;
239
240   /// Message to report.
241   const Twine &Msg;
242 };
243
244 /// Common features for diagnostics dealing with optimization remarks.
245 class DiagnosticInfoOptimizationBase : public DiagnosticInfo {
246 public:
247   /// \p PassName is the name of the pass emitting this diagnostic.
248   /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is
249   /// the location information to use in the diagnostic. If line table
250   /// information is available, the diagnostic will include the source code
251   /// location. \p Msg is the message to show. Note that this class does not
252   /// copy this message, so this reference must be valid for the whole life time
253   /// of the diagnostic.
254   DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind,
255                                  enum DiagnosticSeverity Severity,
256                                  const char *PassName, const Function &Fn,
257                                  const DebugLoc &DLoc, const Twine &Msg)
258       : DiagnosticInfo(Kind, Severity), PassName(PassName), Fn(Fn), DLoc(DLoc),
259         Msg(Msg) {}
260
261   /// \see DiagnosticInfo::print.
262   void print(DiagnosticPrinter &DP) const override;
263
264   static bool classof(const DiagnosticInfo *DI) {
265     return DI->getKind() == DK_OptimizationRemark;
266   }
267
268   /// Return true if this optimization remark is enabled by one of
269   /// of the LLVM command line flags (-pass-remarks, -pass-remarks-missed,
270   /// or -pass-remarks-analysis). Note that this only handles the LLVM
271   /// flags. We cannot access Clang flags from here (they are handled
272   /// in BackendConsumer::OptimizationRemarkHandler).
273   virtual bool isEnabled() const = 0;
274
275   /// Return true if location information is available for this diagnostic.
276   bool isLocationAvailable() const;
277
278   /// Return a string with the location information for this diagnostic
279   /// in the format "file:line:col". If location information is not available,
280   /// it returns "<unknown>:0:0".
281   const std::string getLocationStr() const;
282
283   /// Return location information for this diagnostic in three parts:
284   /// the source file name, line number and column.
285   void getLocation(StringRef *Filename, unsigned *Line, unsigned *Column) const;
286
287   const char *getPassName() const { return PassName; }
288   const Function &getFunction() const { return Fn; }
289   const DebugLoc &getDebugLoc() const { return DLoc; }
290   const Twine &getMsg() const { return Msg; }
291
292 private:
293   /// Name of the pass that triggers this report. If this matches the
294   /// regular expression given in -Rpass=regexp, then the remark will
295   /// be emitted.
296   const char *PassName;
297
298   /// Function where this diagnostic is triggered.
299   const Function &Fn;
300
301   /// Debug location where this diagnostic is triggered.
302   DebugLoc DLoc;
303
304   /// Message to report.
305   const Twine &Msg;
306 };
307
308 /// Diagnostic information for applied optimization remarks.
309 class DiagnosticInfoOptimizationRemark : public DiagnosticInfoOptimizationBase {
310 public:
311   /// \p PassName is the name of the pass emitting this diagnostic. If
312   /// this name matches the regular expression given in -Rpass=, then the
313   /// diagnostic will be emitted. \p Fn is the function where the diagnostic
314   /// is being emitted. \p DLoc is the location information to use in the
315   /// diagnostic. If line table information is available, the diagnostic
316   /// will include the source code location. \p Msg is the message to show.
317   /// Note that this class does not copy this message, so this reference
318   /// must be valid for the whole life time of the diagnostic.
319   DiagnosticInfoOptimizationRemark(const char *PassName, const Function &Fn,
320                                    const DebugLoc &DLoc, const Twine &Msg)
321       : DiagnosticInfoOptimizationBase(DK_OptimizationRemark, DS_Remark,
322                                        PassName, Fn, DLoc, Msg) {}
323
324   static bool classof(const DiagnosticInfo *DI) {
325     return DI->getKind() == DK_OptimizationRemark;
326   }
327
328   /// \see DiagnosticInfoOptimizationBase::isEnabled.
329   bool isEnabled() const override;
330 };
331
332 /// Diagnostic information for missed-optimization remarks.
333 class DiagnosticInfoOptimizationRemarkMissed
334     : public DiagnosticInfoOptimizationBase {
335 public:
336   /// \p PassName is the name of the pass emitting this diagnostic. If
337   /// this name matches the regular expression given in -Rpass-missed=, then the
338   /// diagnostic will be emitted. \p Fn is the function where the diagnostic
339   /// is being emitted. \p DLoc is the location information to use in the
340   /// diagnostic. If line table information is available, the diagnostic
341   /// will include the source code location. \p Msg is the message to show.
342   /// Note that this class does not copy this message, so this reference
343   /// must be valid for the whole life time of the diagnostic.
344   DiagnosticInfoOptimizationRemarkMissed(const char *PassName,
345                                          const Function &Fn,
346                                          const DebugLoc &DLoc, const Twine &Msg)
347       : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkMissed, DS_Remark,
348                                        PassName, Fn, DLoc, Msg) {}
349
350   static bool classof(const DiagnosticInfo *DI) {
351     return DI->getKind() == DK_OptimizationRemarkMissed;
352   }
353
354   /// \see DiagnosticInfoOptimizationBase::isEnabled.
355   bool isEnabled() const override;
356 };
357
358 /// Diagnostic information for optimization analysis remarks.
359 class DiagnosticInfoOptimizationRemarkAnalysis
360     : public DiagnosticInfoOptimizationBase {
361 public:
362   /// \p PassName is the name of the pass emitting this diagnostic. If
363   /// this name matches the regular expression given in -Rpass-analysis=, then
364   /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
365   /// is being emitted. \p DLoc is the location information to use in the
366   /// diagnostic. If line table information is available, the diagnostic will
367   /// include the source code location. \p Msg is the message to show. Note that
368   /// this class does not copy this message, so this reference must be valid for
369   /// the whole life time of the diagnostic.
370   DiagnosticInfoOptimizationRemarkAnalysis(const char *PassName,
371                                            const Function &Fn,
372                                            const DebugLoc &DLoc,
373                                            const Twine &Msg)
374       : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkAnalysis, DS_Remark,
375                                        PassName, Fn, DLoc, Msg) {}
376
377   static bool classof(const DiagnosticInfo *DI) {
378     return DI->getKind() == DK_OptimizationRemarkAnalysis;
379   }
380
381   /// \see DiagnosticInfoOptimizationBase::isEnabled.
382   bool isEnabled() const override;
383 };
384
385 // Create wrappers for C Binding types (see CBindingWrapping.h).
386 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef)
387
388 /// Emit an optimization-applied message. \p PassName is the name of the pass
389 /// emitting the message. If -Rpass= is given and \p PassName matches the
390 /// regular expression in -Rpass, then the remark will be emitted. \p Fn is
391 /// the function triggering the remark, \p DLoc is the debug location where
392 /// the diagnostic is generated. \p Msg is the message string to use.
393 void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
394                             const Function &Fn, const DebugLoc &DLoc,
395                             const Twine &Msg);
396
397 /// Emit an optimization-missed message. \p PassName is the name of the
398 /// pass emitting the message. If -Rpass-missed= is given and \p PassName
399 /// matches the regular expression in -Rpass, then the remark will be
400 /// emitted. \p Fn is the function triggering the remark, \p DLoc is the
401 /// debug location where the diagnostic is generated. \p Msg is the
402 /// message string to use.
403 void emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName,
404                                   const Function &Fn, const DebugLoc &DLoc,
405                                   const Twine &Msg);
406
407 /// Emit an optimization analysis remark message. \p PassName is the name of
408 /// the pass emitting the message. If -Rpass-analysis= is given and \p
409 /// PassName matches the regular expression in -Rpass, then the remark will be
410 /// emitted. \p Fn is the function triggering the remark, \p DLoc is the debug
411 /// location where the diagnostic is generated. \p Msg is the message string
412 /// to use.
413 void emitOptimizationRemarkAnalysis(LLVMContext &Ctx, const char *PassName,
414                                     const Function &Fn, const DebugLoc &DLoc,
415                                     const Twine &Msg);
416
417 /// Diagnostic information for optimization failures.
418 class DiagnosticInfoOptimizationFailure
419     : public DiagnosticInfoOptimizationBase {
420 public:
421   /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is
422   /// the location information to use in the diagnostic. If line table
423   /// information is available, the diagnostic will include the source code
424   /// location. \p Msg is the message to show. Note that this class does not
425   /// copy this message, so this reference must be valid for the whole life time
426   /// of the diagnostic.
427   DiagnosticInfoOptimizationFailure(const Function &Fn, const DebugLoc &DLoc,
428                                     const Twine &Msg)
429       : DiagnosticInfoOptimizationBase(DK_OptimizationFailure, DS_Warning,
430                                        nullptr, Fn, DLoc, Msg) {}
431
432   static bool classof(const DiagnosticInfo *DI) {
433     return DI->getKind() == DK_OptimizationFailure;
434   }
435
436   /// \see DiagnosticInfoOptimizationBase::isEnabled.
437   bool isEnabled() const override;
438 };
439
440 /// Emit a warning when loop vectorization is specified but fails. \p Fn is the
441 /// function triggering the warning, \p DLoc is the debug location where the
442 /// diagnostic is generated. \p Msg is the message string to use.
443 void emitLoopVectorizeWarning(LLVMContext &Ctx, const Function &Fn,
444                               const DebugLoc &DLoc, const Twine &Msg);
445
446 /// Emit a warning when loop interleaving is specified but fails. \p Fn is the
447 /// function triggering the warning, \p DLoc is the debug location where the
448 /// diagnostic is generated. \p Msg is the message string to use.
449 void emitLoopInterleaveWarning(LLVMContext &Ctx, const Function &Fn,
450                                const DebugLoc &DLoc, const Twine &Msg);
451
452 } // End namespace llvm
453
454 #endif