DiagnosticInfo.h 43 KB

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