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