LLVM API Documentation
00001 //===- llvm/Support/DiagnosticInfo.h - Diagnostic Declaration ---*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file declares the different classes involved in low level diagnostics. 00011 // 00012 // Diagnostics reporting is still done as part of the LLVMContext. 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_IR_DIAGNOSTICINFO_H 00016 #define LLVM_IR_DIAGNOSTICINFO_H 00017 00018 #include "llvm-c/Core.h" 00019 #include "llvm/ADT/ArrayRef.h" 00020 #include "llvm/IR/DebugLoc.h" 00021 #include "llvm/IR/Module.h" 00022 #include "llvm/Support/Casting.h" 00023 00024 namespace llvm { 00025 00026 // Forward declarations. 00027 class DiagnosticPrinter; 00028 class Function; 00029 class Instruction; 00030 class LLVMContextImpl; 00031 class Twine; 00032 class Value; 00033 class DebugLoc; 00034 00035 /// \brief Defines the different supported severity of a diagnostic. 00036 enum DiagnosticSeverity { 00037 DS_Error, 00038 DS_Warning, 00039 DS_Remark, 00040 // A note attaches additional information to one of the previous diagnostic 00041 // types. 00042 DS_Note 00043 }; 00044 00045 /// \brief Defines the different supported kind of a diagnostic. 00046 /// This enum should be extended with a new ID for each added concrete subclass. 00047 enum DiagnosticKind { 00048 DK_InlineAsm, 00049 DK_StackSize, 00050 DK_DebugMetadataVersion, 00051 DK_SampleProfile, 00052 DK_OptimizationRemark, 00053 DK_OptimizationRemarkMissed, 00054 DK_OptimizationRemarkAnalysis, 00055 DK_OptimizationFailure, 00056 DK_FirstPluginKind 00057 }; 00058 00059 /// \brief Get the next available kind ID for a plugin diagnostic. 00060 /// Each time this function is called, it returns a different number. 00061 /// Therefore, a plugin that wants to "identify" its own classes 00062 /// with a dynamic identifier, just have to use this method to get a new ID 00063 /// and assign it to each of its classes. 00064 /// The returned ID will be greater than or equal to DK_FirstPluginKind. 00065 /// Thus, the plugin identifiers will not conflict with the 00066 /// DiagnosticKind values. 00067 int getNextAvailablePluginDiagnosticKind(); 00068 00069 /// \brief This is the base abstract class for diagnostic reporting in 00070 /// the backend. 00071 /// The print method must be overloaded by the subclasses to print a 00072 /// user-friendly message in the client of the backend (let us call it a 00073 /// frontend). 00074 class DiagnosticInfo { 00075 private: 00076 /// Kind defines the kind of report this is about. 00077 const /* DiagnosticKind */ int Kind; 00078 /// Severity gives the severity of the diagnostic. 00079 const DiagnosticSeverity Severity; 00080 00081 public: 00082 DiagnosticInfo(/* DiagnosticKind */ int Kind, DiagnosticSeverity Severity) 00083 : Kind(Kind), Severity(Severity) {} 00084 00085 virtual ~DiagnosticInfo() {} 00086 00087 /* DiagnosticKind */ int getKind() const { return Kind; } 00088 DiagnosticSeverity getSeverity() const { return Severity; } 00089 00090 /// Print using the given \p DP a user-friendly message. 00091 /// This is the default message that will be printed to the user. 00092 /// It is used when the frontend does not directly take advantage 00093 /// of the information contained in fields of the subclasses. 00094 /// The printed message must not end with '.' nor start with a severity 00095 /// keyword. 00096 virtual void print(DiagnosticPrinter &DP) const = 0; 00097 }; 00098 00099 /// Diagnostic information for inline asm reporting. 00100 /// This is basically a message and an optional location. 00101 class DiagnosticInfoInlineAsm : public DiagnosticInfo { 00102 private: 00103 /// Optional line information. 0 if not set. 00104 unsigned LocCookie; 00105 /// Message to be reported. 00106 const Twine &MsgStr; 00107 /// Optional origin of the problem. 00108 const Instruction *Instr; 00109 00110 public: 00111 /// \p MsgStr is the message to be reported to the frontend. 00112 /// This class does not copy \p MsgStr, therefore the reference must be valid 00113 /// for the whole life time of the Diagnostic. 00114 DiagnosticInfoInlineAsm(const Twine &MsgStr, 00115 DiagnosticSeverity Severity = DS_Error) 00116 : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(0), MsgStr(MsgStr), 00117 Instr(nullptr) {} 00118 00119 /// \p LocCookie if non-zero gives the line number for this report. 00120 /// \p MsgStr gives the message. 00121 /// This class does not copy \p MsgStr, therefore the reference must be valid 00122 /// for the whole life time of the Diagnostic. 00123 DiagnosticInfoInlineAsm(unsigned LocCookie, const Twine &MsgStr, 00124 DiagnosticSeverity Severity = DS_Error) 00125 : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie), 00126 MsgStr(MsgStr), Instr(nullptr) {} 00127 00128 /// \p Instr gives the original instruction that triggered the diagnostic. 00129 /// \p MsgStr gives the message. 00130 /// This class does not copy \p MsgStr, therefore the reference must be valid 00131 /// for the whole life time of the Diagnostic. 00132 /// Same for \p I. 00133 DiagnosticInfoInlineAsm(const Instruction &I, const Twine &MsgStr, 00134 DiagnosticSeverity Severity = DS_Error); 00135 00136 unsigned getLocCookie() const { return LocCookie; } 00137 const Twine &getMsgStr() const { return MsgStr; } 00138 const Instruction *getInstruction() const { return Instr; } 00139 00140 /// \see DiagnosticInfo::print. 00141 void print(DiagnosticPrinter &DP) const override; 00142 00143 static bool classof(const DiagnosticInfo *DI) { 00144 return DI->getKind() == DK_InlineAsm; 00145 } 00146 }; 00147 00148 /// Diagnostic information for stack size reporting. 00149 /// This is basically a function and a size. 00150 class DiagnosticInfoStackSize : public DiagnosticInfo { 00151 private: 00152 /// The function that is concerned by this stack size diagnostic. 00153 const Function &Fn; 00154 /// The computed stack size. 00155 unsigned StackSize; 00156 00157 public: 00158 /// \p The function that is concerned by this stack size diagnostic. 00159 /// \p The computed stack size. 00160 DiagnosticInfoStackSize(const Function &Fn, unsigned StackSize, 00161 DiagnosticSeverity Severity = DS_Warning) 00162 : DiagnosticInfo(DK_StackSize, Severity), Fn(Fn), StackSize(StackSize) {} 00163 00164 const Function &getFunction() const { return Fn; } 00165 unsigned getStackSize() const { return StackSize; } 00166 00167 /// \see DiagnosticInfo::print. 00168 void print(DiagnosticPrinter &DP) const override; 00169 00170 static bool classof(const DiagnosticInfo *DI) { 00171 return DI->getKind() == DK_StackSize; 00172 } 00173 }; 00174 00175 /// Diagnostic information for debug metadata version reporting. 00176 /// This is basically a module and a version. 00177 class DiagnosticInfoDebugMetadataVersion : public DiagnosticInfo { 00178 private: 00179 /// The module that is concerned by this debug metadata version diagnostic. 00180 const Module &M; 00181 /// The actual metadata version. 00182 unsigned MetadataVersion; 00183 00184 public: 00185 /// \p The module that is concerned by this debug metadata version diagnostic. 00186 /// \p The actual metadata version. 00187 DiagnosticInfoDebugMetadataVersion(const Module &M, unsigned MetadataVersion, 00188 DiagnosticSeverity Severity = DS_Warning) 00189 : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M), 00190 MetadataVersion(MetadataVersion) {} 00191 00192 const Module &getModule() const { return M; } 00193 unsigned getMetadataVersion() const { return MetadataVersion; } 00194 00195 /// \see DiagnosticInfo::print. 00196 void print(DiagnosticPrinter &DP) const override; 00197 00198 static bool classof(const DiagnosticInfo *DI) { 00199 return DI->getKind() == DK_DebugMetadataVersion; 00200 } 00201 }; 00202 00203 /// Diagnostic information for the sample profiler. 00204 class DiagnosticInfoSampleProfile : public DiagnosticInfo { 00205 public: 00206 DiagnosticInfoSampleProfile(const char *FileName, unsigned LineNum, 00207 const Twine &Msg, 00208 DiagnosticSeverity Severity = DS_Error) 00209 : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName), 00210 LineNum(LineNum), Msg(Msg) {} 00211 DiagnosticInfoSampleProfile(const char *FileName, const Twine &Msg, 00212 DiagnosticSeverity Severity = DS_Error) 00213 : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName), 00214 LineNum(0), Msg(Msg) {} 00215 DiagnosticInfoSampleProfile(const Twine &Msg, 00216 DiagnosticSeverity Severity = DS_Error) 00217 : DiagnosticInfo(DK_SampleProfile, Severity), FileName(nullptr), 00218 LineNum(0), Msg(Msg) {} 00219 00220 /// \see DiagnosticInfo::print. 00221 void print(DiagnosticPrinter &DP) const override; 00222 00223 static bool classof(const DiagnosticInfo *DI) { 00224 return DI->getKind() == DK_SampleProfile; 00225 } 00226 00227 const char *getFileName() const { return FileName; } 00228 unsigned getLineNum() const { return LineNum; } 00229 const Twine &getMsg() const { return Msg; } 00230 00231 private: 00232 /// Name of the input file associated with this diagnostic. 00233 const char *FileName; 00234 00235 /// Line number where the diagnostic occurred. If 0, no line number will 00236 /// be emitted in the message. 00237 unsigned LineNum; 00238 00239 /// Message to report. 00240 const Twine &Msg; 00241 }; 00242 00243 /// Common features for diagnostics dealing with optimization remarks. 00244 class DiagnosticInfoOptimizationBase : public DiagnosticInfo { 00245 public: 00246 /// \p PassName is the name of the pass emitting this diagnostic. 00247 /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is 00248 /// the location information to use in the diagnostic. If line table 00249 /// information is available, the diagnostic will include the source code 00250 /// location. \p Msg is the message to show. Note that this class does not 00251 /// copy this message, so this reference must be valid for the whole life time 00252 /// of the diagnostic. 00253 DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind, 00254 enum DiagnosticSeverity Severity, 00255 const char *PassName, const Function &Fn, 00256 const DebugLoc &DLoc, const Twine &Msg) 00257 : DiagnosticInfo(Kind, Severity), PassName(PassName), Fn(Fn), DLoc(DLoc), 00258 Msg(Msg) {} 00259 00260 /// \see DiagnosticInfo::print. 00261 void print(DiagnosticPrinter &DP) const override; 00262 00263 static bool classof(const DiagnosticInfo *DI) { 00264 return DI->getKind() == DK_OptimizationRemark; 00265 } 00266 00267 /// Return true if this optimization remark is enabled by one of 00268 /// of the LLVM command line flags (-pass-remarks, -pass-remarks-missed, 00269 /// or -pass-remarks-analysis). Note that this only handles the LLVM 00270 /// flags. We cannot access Clang flags from here (they are handled 00271 /// in BackendConsumer::OptimizationRemarkHandler). 00272 virtual bool isEnabled() const = 0; 00273 00274 /// Return true if location information is available for this diagnostic. 00275 bool isLocationAvailable() const; 00276 00277 /// Return a string with the location information for this diagnostic 00278 /// in the format "file:line:col". If location information is not available, 00279 /// it returns "<unknown>:0:0". 00280 const std::string getLocationStr() const; 00281 00282 /// Return location information for this diagnostic in three parts: 00283 /// the source file name, line number and column. 00284 void getLocation(StringRef *Filename, unsigned *Line, unsigned *Column) const; 00285 00286 const char *getPassName() const { return PassName; } 00287 const Function &getFunction() const { return Fn; } 00288 const DebugLoc &getDebugLoc() const { return DLoc; } 00289 const Twine &getMsg() const { return Msg; } 00290 00291 private: 00292 /// Name of the pass that triggers this report. If this matches the 00293 /// regular expression given in -Rpass=regexp, then the remark will 00294 /// be emitted. 00295 const char *PassName; 00296 00297 /// Function where this diagnostic is triggered. 00298 const Function &Fn; 00299 00300 /// Debug location where this diagnostic is triggered. 00301 DebugLoc DLoc; 00302 00303 /// Message to report. 00304 const Twine &Msg; 00305 }; 00306 00307 /// Diagnostic information for applied optimization remarks. 00308 class DiagnosticInfoOptimizationRemark : public DiagnosticInfoOptimizationBase { 00309 public: 00310 /// \p PassName is the name of the pass emitting this diagnostic. If 00311 /// this name matches the regular expression given in -Rpass=, then the 00312 /// diagnostic will be emitted. \p Fn is the function where the diagnostic 00313 /// is being emitted. \p DLoc is the location information to use in the 00314 /// diagnostic. If line table information is available, the diagnostic 00315 /// will include the source code location. \p Msg is the message to show. 00316 /// Note that this class does not copy this message, so this reference 00317 /// must be valid for the whole life time of the diagnostic. 00318 DiagnosticInfoOptimizationRemark(const char *PassName, const Function &Fn, 00319 const DebugLoc &DLoc, const Twine &Msg) 00320 : DiagnosticInfoOptimizationBase(DK_OptimizationRemark, DS_Remark, 00321 PassName, Fn, DLoc, Msg) {} 00322 00323 static bool classof(const DiagnosticInfo *DI) { 00324 return DI->getKind() == DK_OptimizationRemark; 00325 } 00326 00327 /// \see DiagnosticInfoOptimizationBase::isEnabled. 00328 bool isEnabled() const override; 00329 }; 00330 00331 /// Diagnostic information for missed-optimization remarks. 00332 class DiagnosticInfoOptimizationRemarkMissed 00333 : public DiagnosticInfoOptimizationBase { 00334 public: 00335 /// \p PassName is the name of the pass emitting this diagnostic. If 00336 /// this name matches the regular expression given in -Rpass-missed=, then the 00337 /// diagnostic will be emitted. \p Fn is the function where the diagnostic 00338 /// is being emitted. \p DLoc is the location information to use in the 00339 /// diagnostic. If line table information is available, the diagnostic 00340 /// will include the source code location. \p Msg is the message to show. 00341 /// Note that this class does not copy this message, so this reference 00342 /// must be valid for the whole life time of the diagnostic. 00343 DiagnosticInfoOptimizationRemarkMissed(const char *PassName, 00344 const Function &Fn, 00345 const DebugLoc &DLoc, const Twine &Msg) 00346 : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkMissed, DS_Remark, 00347 PassName, Fn, DLoc, Msg) {} 00348 00349 static bool classof(const DiagnosticInfo *DI) { 00350 return DI->getKind() == DK_OptimizationRemarkMissed; 00351 } 00352 00353 /// \see DiagnosticInfoOptimizationBase::isEnabled. 00354 bool isEnabled() const override; 00355 }; 00356 00357 /// Diagnostic information for optimization analysis remarks. 00358 class DiagnosticInfoOptimizationRemarkAnalysis 00359 : public DiagnosticInfoOptimizationBase { 00360 public: 00361 /// \p PassName is the name of the pass emitting this diagnostic. If 00362 /// this name matches the regular expression given in -Rpass-analysis=, then 00363 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic 00364 /// is being emitted. \p DLoc is the location information to use in the 00365 /// diagnostic. If line table information is available, the diagnostic will 00366 /// include the source code location. \p Msg is the message to show. Note that 00367 /// this class does not copy this message, so this reference must be valid for 00368 /// the whole life time of the diagnostic. 00369 DiagnosticInfoOptimizationRemarkAnalysis(const char *PassName, 00370 const Function &Fn, 00371 const DebugLoc &DLoc, 00372 const Twine &Msg) 00373 : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkAnalysis, DS_Remark, 00374 PassName, Fn, DLoc, Msg) {} 00375 00376 static bool classof(const DiagnosticInfo *DI) { 00377 return DI->getKind() == DK_OptimizationRemarkAnalysis; 00378 } 00379 00380 /// \see DiagnosticInfoOptimizationBase::isEnabled. 00381 bool isEnabled() const override; 00382 }; 00383 00384 // Create wrappers for C Binding types (see CBindingWrapping.h). 00385 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef) 00386 00387 /// Emit an optimization-applied message. \p PassName is the name of the pass 00388 /// emitting the message. If -Rpass= is given and \p PassName matches the 00389 /// regular expression in -Rpass, then the remark will be emitted. \p Fn is 00390 /// the function triggering the remark, \p DLoc is the debug location where 00391 /// the diagnostic is generated. \p Msg is the message string to use. 00392 void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName, 00393 const Function &Fn, const DebugLoc &DLoc, 00394 const Twine &Msg); 00395 00396 /// Emit an optimization-missed message. \p PassName is the name of the 00397 /// pass emitting the message. If -Rpass-missed= is given and \p PassName 00398 /// matches the regular expression in -Rpass, then the remark will be 00399 /// emitted. \p Fn is the function triggering the remark, \p DLoc is the 00400 /// debug location where the diagnostic is generated. \p Msg is the 00401 /// message string to use. 00402 void emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName, 00403 const Function &Fn, const DebugLoc &DLoc, 00404 const Twine &Msg); 00405 00406 /// Emit an optimization analysis remark message. \p PassName is the name of 00407 /// the pass emitting the message. If -Rpass-analysis= is given and \p 00408 /// PassName matches the regular expression in -Rpass, then the remark will be 00409 /// emitted. \p Fn is the function triggering the remark, \p DLoc is the debug 00410 /// location where the diagnostic is generated. \p Msg is the message string 00411 /// to use. 00412 void emitOptimizationRemarkAnalysis(LLVMContext &Ctx, const char *PassName, 00413 const Function &Fn, const DebugLoc &DLoc, 00414 const Twine &Msg); 00415 00416 /// Diagnostic information for optimization failures. 00417 class DiagnosticInfoOptimizationFailure 00418 : public DiagnosticInfoOptimizationBase { 00419 public: 00420 /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is 00421 /// the location information to use in the diagnostic. If line table 00422 /// information is available, the diagnostic will include the source code 00423 /// location. \p Msg is the message to show. Note that this class does not 00424 /// copy this message, so this reference must be valid for the whole life time 00425 /// of the diagnostic. 00426 DiagnosticInfoOptimizationFailure(const Function &Fn, const DebugLoc &DLoc, 00427 const Twine &Msg) 00428 : DiagnosticInfoOptimizationBase(DK_OptimizationFailure, DS_Warning, 00429 nullptr, Fn, DLoc, Msg) {} 00430 00431 static bool classof(const DiagnosticInfo *DI) { 00432 return DI->getKind() == DK_OptimizationFailure; 00433 } 00434 00435 /// \see DiagnosticInfoOptimizationBase::isEnabled. 00436 bool isEnabled() const override; 00437 }; 00438 00439 /// Emit a warning when loop vectorization is specified but fails. \p Fn is the 00440 /// function triggering the warning, \p DLoc is the debug location where the 00441 /// diagnostic is generated. \p Msg is the message string to use. 00442 void emitLoopVectorizeWarning(LLVMContext &Ctx, const Function &Fn, 00443 const DebugLoc &DLoc, const Twine &Msg); 00444 00445 /// Emit a warning when loop interleaving is specified but fails. \p Fn is the 00446 /// function triggering the warning, \p DLoc is the debug location where the 00447 /// diagnostic is generated. \p Msg is the message string to use. 00448 void emitLoopInterleaveWarning(LLVMContext &Ctx, const Function &Fn, 00449 const DebugLoc &DLoc, const Twine &Msg); 00450 00451 } // End namespace llvm 00452 00453 #endif