Bug Summary

File:llvm/include/llvm/IR/DiagnosticInfo.h
Warning:line 480, column 28
Undefined or garbage value returned to caller

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name LLVMContext.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/build-llvm/lib/IR -resource-dir /usr/lib/llvm-13/lib/clang/13.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/build-llvm/lib/IR -I /build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/llvm/lib/IR -I /build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/build-llvm/include -I /build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/llvm/include -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-13/lib/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/build-llvm/lib/IR -fdebug-prefix-map=/build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c=. -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2021-07-26-235520-9401-1 -x c++ /build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/llvm/lib/IR/LLVMContext.cpp

/build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/llvm/lib/IR/LLVMContext.cpp

1//===-- LLVMContext.cpp - Implement LLVMContext ---------------------------===//
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 implements LLVMContext, as a wrapper around the opaque
10// class LLVMContextImpl.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/IR/LLVMContext.h"
15#include "LLVMContextImpl.h"
16#include "llvm/ADT/SmallVector.h"
17#include "llvm/ADT/StringMap.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/ADT/Twine.h"
20#include "llvm/IR/DiagnosticInfo.h"
21#include "llvm/IR/DiagnosticPrinter.h"
22#include "llvm/IR/LLVMRemarkStreamer.h"
23#include "llvm/IR/Metadata.h"
24#include "llvm/IR/Module.h"
25#include "llvm/Remarks/RemarkStreamer.h"
26#include "llvm/Support/Casting.h"
27#include "llvm/Support/ErrorHandling.h"
28#include "llvm/Support/raw_ostream.h"
29#include <cassert>
30#include <cstdlib>
31#include <string>
32#include <utility>
33
34using namespace llvm;
35
36LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
37 // Create the fixed metadata kinds. This is done in the same order as the
38 // MD_* enum values so that they correspond.
39 std::pair<unsigned, StringRef> MDKinds[] = {
40#define LLVM_FIXED_MD_KIND(EnumID, Name, Value) {EnumID, Name},
41#include "llvm/IR/FixedMetadataKinds.def"
42#undef LLVM_FIXED_MD_KIND
43 };
44
45 for (auto &MDKind : MDKinds) {
46 unsigned ID = getMDKindID(MDKind.second);
47 assert(ID == MDKind.first && "metadata kind id drifted")(static_cast <bool> (ID == MDKind.first && "metadata kind id drifted"
) ? void (0) : __assert_fail ("ID == MDKind.first && \"metadata kind id drifted\""
, "/build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/llvm/lib/IR/LLVMContext.cpp"
, 47, __extension__ __PRETTY_FUNCTION__))
;
48 (void)ID;
49 }
50
51 auto *DeoptEntry = pImpl->getOrInsertBundleTag("deopt");
52 assert(DeoptEntry->second == LLVMContext::OB_deopt &&(static_cast <bool> (DeoptEntry->second == LLVMContext
::OB_deopt && "deopt operand bundle id drifted!") ? void
(0) : __assert_fail ("DeoptEntry->second == LLVMContext::OB_deopt && \"deopt operand bundle id drifted!\""
, "/build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/llvm/lib/IR/LLVMContext.cpp"
, 53, __extension__ __PRETTY_FUNCTION__))
53 "deopt operand bundle id drifted!")(static_cast <bool> (DeoptEntry->second == LLVMContext
::OB_deopt && "deopt operand bundle id drifted!") ? void
(0) : __assert_fail ("DeoptEntry->second == LLVMContext::OB_deopt && \"deopt operand bundle id drifted!\""
, "/build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/llvm/lib/IR/LLVMContext.cpp"
, 53, __extension__ __PRETTY_FUNCTION__))
;
54 (void)DeoptEntry;
55
56 auto *FuncletEntry = pImpl->getOrInsertBundleTag("funclet");
57 assert(FuncletEntry->second == LLVMContext::OB_funclet &&(static_cast <bool> (FuncletEntry->second == LLVMContext
::OB_funclet && "funclet operand bundle id drifted!")
? void (0) : __assert_fail ("FuncletEntry->second == LLVMContext::OB_funclet && \"funclet operand bundle id drifted!\""
, "/build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/llvm/lib/IR/LLVMContext.cpp"
, 58, __extension__ __PRETTY_FUNCTION__))
58 "funclet operand bundle id drifted!")(static_cast <bool> (FuncletEntry->second == LLVMContext
::OB_funclet && "funclet operand bundle id drifted!")
? void (0) : __assert_fail ("FuncletEntry->second == LLVMContext::OB_funclet && \"funclet operand bundle id drifted!\""
, "/build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/llvm/lib/IR/LLVMContext.cpp"
, 58, __extension__ __PRETTY_FUNCTION__))
;
59 (void)FuncletEntry;
60
61 auto *GCTransitionEntry = pImpl->getOrInsertBundleTag("gc-transition");
62 assert(GCTransitionEntry->second == LLVMContext::OB_gc_transition &&(static_cast <bool> (GCTransitionEntry->second == LLVMContext
::OB_gc_transition && "gc-transition operand bundle id drifted!"
) ? void (0) : __assert_fail ("GCTransitionEntry->second == LLVMContext::OB_gc_transition && \"gc-transition operand bundle id drifted!\""
, "/build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/llvm/lib/IR/LLVMContext.cpp"
, 63, __extension__ __PRETTY_FUNCTION__))
63 "gc-transition operand bundle id drifted!")(static_cast <bool> (GCTransitionEntry->second == LLVMContext
::OB_gc_transition && "gc-transition operand bundle id drifted!"
) ? void (0) : __assert_fail ("GCTransitionEntry->second == LLVMContext::OB_gc_transition && \"gc-transition operand bundle id drifted!\""
, "/build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/llvm/lib/IR/LLVMContext.cpp"
, 63, __extension__ __PRETTY_FUNCTION__))
;
64 (void)GCTransitionEntry;
65
66 auto *CFGuardTargetEntry = pImpl->getOrInsertBundleTag("cfguardtarget");
67 assert(CFGuardTargetEntry->second == LLVMContext::OB_cfguardtarget &&(static_cast <bool> (CFGuardTargetEntry->second == LLVMContext
::OB_cfguardtarget && "cfguardtarget operand bundle id drifted!"
) ? void (0) : __assert_fail ("CFGuardTargetEntry->second == LLVMContext::OB_cfguardtarget && \"cfguardtarget operand bundle id drifted!\""
, "/build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/llvm/lib/IR/LLVMContext.cpp"
, 68, __extension__ __PRETTY_FUNCTION__))
68 "cfguardtarget operand bundle id drifted!")(static_cast <bool> (CFGuardTargetEntry->second == LLVMContext
::OB_cfguardtarget && "cfguardtarget operand bundle id drifted!"
) ? void (0) : __assert_fail ("CFGuardTargetEntry->second == LLVMContext::OB_cfguardtarget && \"cfguardtarget operand bundle id drifted!\""
, "/build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/llvm/lib/IR/LLVMContext.cpp"
, 68, __extension__ __PRETTY_FUNCTION__))
;
69 (void)CFGuardTargetEntry;
70
71 auto *PreallocatedEntry = pImpl->getOrInsertBundleTag("preallocated");
72 assert(PreallocatedEntry->second == LLVMContext::OB_preallocated &&(static_cast <bool> (PreallocatedEntry->second == LLVMContext
::OB_preallocated && "preallocated operand bundle id drifted!"
) ? void (0) : __assert_fail ("PreallocatedEntry->second == LLVMContext::OB_preallocated && \"preallocated operand bundle id drifted!\""
, "/build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/llvm/lib/IR/LLVMContext.cpp"
, 73, __extension__ __PRETTY_FUNCTION__))
73 "preallocated operand bundle id drifted!")(static_cast <bool> (PreallocatedEntry->second == LLVMContext
::OB_preallocated && "preallocated operand bundle id drifted!"
) ? void (0) : __assert_fail ("PreallocatedEntry->second == LLVMContext::OB_preallocated && \"preallocated operand bundle id drifted!\""
, "/build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/llvm/lib/IR/LLVMContext.cpp"
, 73, __extension__ __PRETTY_FUNCTION__))
;
74 (void)PreallocatedEntry;
75
76 auto *GCLiveEntry = pImpl->getOrInsertBundleTag("gc-live");
77 assert(GCLiveEntry->second == LLVMContext::OB_gc_live &&(static_cast <bool> (GCLiveEntry->second == LLVMContext
::OB_gc_live && "gc-transition operand bundle id drifted!"
) ? void (0) : __assert_fail ("GCLiveEntry->second == LLVMContext::OB_gc_live && \"gc-transition operand bundle id drifted!\""
, "/build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/llvm/lib/IR/LLVMContext.cpp"
, 78, __extension__ __PRETTY_FUNCTION__))
78 "gc-transition operand bundle id drifted!")(static_cast <bool> (GCLiveEntry->second == LLVMContext
::OB_gc_live && "gc-transition operand bundle id drifted!"
) ? void (0) : __assert_fail ("GCLiveEntry->second == LLVMContext::OB_gc_live && \"gc-transition operand bundle id drifted!\""
, "/build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/llvm/lib/IR/LLVMContext.cpp"
, 78, __extension__ __PRETTY_FUNCTION__))
;
79 (void)GCLiveEntry;
80
81 auto *ClangAttachedCall =
82 pImpl->getOrInsertBundleTag("clang.arc.attachedcall");
83 assert(ClangAttachedCall->second == LLVMContext::OB_clang_arc_attachedcall &&(static_cast <bool> (ClangAttachedCall->second == LLVMContext
::OB_clang_arc_attachedcall && "clang.arc.attachedcall operand bundle id drifted!"
) ? void (0) : __assert_fail ("ClangAttachedCall->second == LLVMContext::OB_clang_arc_attachedcall && \"clang.arc.attachedcall operand bundle id drifted!\""
, "/build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/llvm/lib/IR/LLVMContext.cpp"
, 84, __extension__ __PRETTY_FUNCTION__))
84 "clang.arc.attachedcall operand bundle id drifted!")(static_cast <bool> (ClangAttachedCall->second == LLVMContext
::OB_clang_arc_attachedcall && "clang.arc.attachedcall operand bundle id drifted!"
) ? void (0) : __assert_fail ("ClangAttachedCall->second == LLVMContext::OB_clang_arc_attachedcall && \"clang.arc.attachedcall operand bundle id drifted!\""
, "/build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/llvm/lib/IR/LLVMContext.cpp"
, 84, __extension__ __PRETTY_FUNCTION__))
;
85 (void)ClangAttachedCall;
86
87 SyncScope::ID SingleThreadSSID =
88 pImpl->getOrInsertSyncScopeID("singlethread");
89 assert(SingleThreadSSID == SyncScope::SingleThread &&(static_cast <bool> (SingleThreadSSID == SyncScope::SingleThread
&& "singlethread synchronization scope ID drifted!")
? void (0) : __assert_fail ("SingleThreadSSID == SyncScope::SingleThread && \"singlethread synchronization scope ID drifted!\""
, "/build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/llvm/lib/IR/LLVMContext.cpp"
, 90, __extension__ __PRETTY_FUNCTION__))
90 "singlethread synchronization scope ID drifted!")(static_cast <bool> (SingleThreadSSID == SyncScope::SingleThread
&& "singlethread synchronization scope ID drifted!")
? void (0) : __assert_fail ("SingleThreadSSID == SyncScope::SingleThread && \"singlethread synchronization scope ID drifted!\""
, "/build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/llvm/lib/IR/LLVMContext.cpp"
, 90, __extension__ __PRETTY_FUNCTION__))
;
91 (void)SingleThreadSSID;
92
93 SyncScope::ID SystemSSID =
94 pImpl->getOrInsertSyncScopeID("");
95 assert(SystemSSID == SyncScope::System &&(static_cast <bool> (SystemSSID == SyncScope::System &&
"system synchronization scope ID drifted!") ? void (0) : __assert_fail
("SystemSSID == SyncScope::System && \"system synchronization scope ID drifted!\""
, "/build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/llvm/lib/IR/LLVMContext.cpp"
, 96, __extension__ __PRETTY_FUNCTION__))
96 "system synchronization scope ID drifted!")(static_cast <bool> (SystemSSID == SyncScope::System &&
"system synchronization scope ID drifted!") ? void (0) : __assert_fail
("SystemSSID == SyncScope::System && \"system synchronization scope ID drifted!\""
, "/build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/llvm/lib/IR/LLVMContext.cpp"
, 96, __extension__ __PRETTY_FUNCTION__))
;
97 (void)SystemSSID;
98}
99
100LLVMContext::~LLVMContext() { delete pImpl; }
101
102void LLVMContext::addModule(Module *M) {
103 pImpl->OwnedModules.insert(M);
104}
105
106void LLVMContext::removeModule(Module *M) {
107 pImpl->OwnedModules.erase(M);
108}
109
110//===----------------------------------------------------------------------===//
111// Recoverable Backend Errors
112//===----------------------------------------------------------------------===//
113
114void LLVMContext::setDiagnosticHandlerCallBack(
115 DiagnosticHandler::DiagnosticHandlerTy DiagnosticHandler,
116 void *DiagnosticContext, bool RespectFilters) {
117 pImpl->DiagHandler->DiagHandlerCallback = DiagnosticHandler;
118 pImpl->DiagHandler->DiagnosticContext = DiagnosticContext;
119 pImpl->RespectDiagnosticFilters = RespectFilters;
120}
121
122void LLVMContext::setDiagnosticHandler(std::unique_ptr<DiagnosticHandler> &&DH,
123 bool RespectFilters) {
124 pImpl->DiagHandler = std::move(DH);
125 pImpl->RespectDiagnosticFilters = RespectFilters;
126}
127
128void LLVMContext::setDiagnosticsHotnessRequested(bool Requested) {
129 pImpl->DiagnosticsHotnessRequested = Requested;
130}
131bool LLVMContext::getDiagnosticsHotnessRequested() const {
132 return pImpl->DiagnosticsHotnessRequested;
133}
134
135void LLVMContext::setDiagnosticsHotnessThreshold(Optional<uint64_t> Threshold) {
136 pImpl->DiagnosticsHotnessThreshold = Threshold;
137}
138
139uint64_t LLVMContext::getDiagnosticsHotnessThreshold() const {
140 return pImpl->DiagnosticsHotnessThreshold.getValueOr(UINT64_MAX(18446744073709551615UL));
141}
142
143bool LLVMContext::isDiagnosticsHotnessThresholdSetFromPSI() const {
144 return !pImpl->DiagnosticsHotnessThreshold.hasValue();
145}
146
147remarks::RemarkStreamer *LLVMContext::getMainRemarkStreamer() {
148 return pImpl->MainRemarkStreamer.get();
149}
150const remarks::RemarkStreamer *LLVMContext::getMainRemarkStreamer() const {
151 return const_cast<LLVMContext *>(this)->getMainRemarkStreamer();
152}
153void LLVMContext::setMainRemarkStreamer(
154 std::unique_ptr<remarks::RemarkStreamer> RemarkStreamer) {
155 pImpl->MainRemarkStreamer = std::move(RemarkStreamer);
156}
157
158LLVMRemarkStreamer *LLVMContext::getLLVMRemarkStreamer() {
159 return pImpl->LLVMRS.get();
160}
161const LLVMRemarkStreamer *LLVMContext::getLLVMRemarkStreamer() const {
162 return const_cast<LLVMContext *>(this)->getLLVMRemarkStreamer();
163}
164void LLVMContext::setLLVMRemarkStreamer(
165 std::unique_ptr<LLVMRemarkStreamer> RemarkStreamer) {
166 pImpl->LLVMRS = std::move(RemarkStreamer);
167}
168
169DiagnosticHandler::DiagnosticHandlerTy
170LLVMContext::getDiagnosticHandlerCallBack() const {
171 return pImpl->DiagHandler->DiagHandlerCallback;
172}
173
174void *LLVMContext::getDiagnosticContext() const {
175 return pImpl->DiagHandler->DiagnosticContext;
176}
177
178void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle)
179{
180 pImpl->YieldCallback = Callback;
181 pImpl->YieldOpaqueHandle = OpaqueHandle;
182}
183
184void LLVMContext::yield() {
185 if (pImpl->YieldCallback)
186 pImpl->YieldCallback(this, pImpl->YieldOpaqueHandle);
187}
188
189void LLVMContext::emitError(const Twine &ErrorStr) {
190 diagnose(DiagnosticInfoInlineAsm(ErrorStr));
191}
192
193void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) {
194 assert (I && "Invalid instruction")(static_cast <bool> (I && "Invalid instruction"
) ? void (0) : __assert_fail ("I && \"Invalid instruction\""
, "/build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/llvm/lib/IR/LLVMContext.cpp"
, 194, __extension__ __PRETTY_FUNCTION__))
;
195 diagnose(DiagnosticInfoInlineAsm(*I, ErrorStr));
196}
197
198static bool isDiagnosticEnabled(const DiagnosticInfo &DI) {
199 // Optimization remarks are selective. They need to check whether the regexp
200 // pattern, passed via one of the -pass-remarks* flags, matches the name of
201 // the pass that is emitting the diagnostic. If there is no match, ignore the
202 // diagnostic and return.
203 //
204 // Also noisy remarks are only enabled if we have hotness information to sort
205 // them.
206 if (auto *Remark
7.1
'Remark' is non-null
7.1
'Remark' is non-null
= dyn_cast<DiagnosticInfoOptimizationBase>(&DI))
7
The object is a 'DiagnosticInfoOptimizationBase'
8
Taking true branch
207 return Remark->isEnabled() &&
9
Assuming the condition is true
208 (!Remark->isVerbose() || Remark->getHotness());
10
Calling 'DiagnosticInfoOptimizationBase::isVerbose'
209
210 return true;
211}
212
213const char *
214LLVMContext::getDiagnosticMessagePrefix(DiagnosticSeverity Severity) {
215 switch (Severity) {
216 case DS_Error:
217 return "error";
218 case DS_Warning:
219 return "warning";
220 case DS_Remark:
221 return "remark";
222 case DS_Note:
223 return "note";
224 }
225 llvm_unreachable("Unknown DiagnosticSeverity")::llvm::llvm_unreachable_internal("Unknown DiagnosticSeverity"
, "/build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/llvm/lib/IR/LLVMContext.cpp"
, 225)
;
226}
227
228void LLVMContext::diagnose(const DiagnosticInfo &DI) {
229 if (auto *OptDiagBase
2.1
'OptDiagBase' is non-null
2.1
'OptDiagBase' is non-null
= dyn_cast<DiagnosticInfoOptimizationBase>(&DI))
2
Assuming the object is a 'DiagnosticInfoOptimizationBase'
3
Taking true branch
230 if (LLVMRemarkStreamer *RS = getLLVMRemarkStreamer())
4
Assuming 'RS' is null
5
Taking false branch
231 RS->emit(*OptDiagBase);
232
233 // If there is a report handler, use it.
234 if (pImpl->DiagHandler &&
235 (!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)) &&
236 pImpl->DiagHandler->handleDiagnostics(DI))
237 return;
238
239 if (!isDiagnosticEnabled(DI))
6
Calling 'isDiagnosticEnabled'
240 return;
241
242 // Otherwise, print the message with a prefix based on the severity.
243 DiagnosticPrinterRawOStream DP(errs());
244 errs() << getDiagnosticMessagePrefix(DI.getSeverity()) << ": ";
245 DI.print(DP);
246 errs() << "\n";
247 if (DI.getSeverity() == DS_Error)
248 exit(1);
249}
250
251void LLVMContext::emitError(uint64_t LocCookie, const Twine &ErrorStr) {
252 diagnose(DiagnosticInfoInlineAsm(LocCookie, ErrorStr));
1
Calling 'LLVMContext::diagnose'
253}
254
255//===----------------------------------------------------------------------===//
256// Metadata Kind Uniquing
257//===----------------------------------------------------------------------===//
258
259/// Return a unique non-zero ID for the specified metadata kind.
260unsigned LLVMContext::getMDKindID(StringRef Name) const {
261 // If this is new, assign it its ID.
262 return pImpl->CustomMDKindNames.insert(
263 std::make_pair(
264 Name, pImpl->CustomMDKindNames.size()))
265 .first->second;
266}
267
268/// getHandlerNames - Populate client-supplied smallvector using custom
269/// metadata name and ID.
270void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const {
271 Names.resize(pImpl->CustomMDKindNames.size());
272 for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(),
273 E = pImpl->CustomMDKindNames.end(); I != E; ++I)
274 Names[I->second] = I->first();
275}
276
277void LLVMContext::getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const {
278 pImpl->getOperandBundleTags(Tags);
279}
280
281StringMapEntry<uint32_t> *
282LLVMContext::getOrInsertBundleTag(StringRef TagName) const {
283 return pImpl->getOrInsertBundleTag(TagName);
284}
285
286uint32_t LLVMContext::getOperandBundleTagID(StringRef Tag) const {
287 return pImpl->getOperandBundleTagID(Tag);
288}
289
290SyncScope::ID LLVMContext::getOrInsertSyncScopeID(StringRef SSN) {
291 return pImpl->getOrInsertSyncScopeID(SSN);
292}
293
294void LLVMContext::getSyncScopeNames(SmallVectorImpl<StringRef> &SSNs) const {
295 pImpl->getSyncScopeNames(SSNs);
296}
297
298void LLVMContext::setGC(const Function &Fn, std::string GCName) {
299 auto It = pImpl->GCNames.find(&Fn);
300
301 if (It == pImpl->GCNames.end()) {
302 pImpl->GCNames.insert(std::make_pair(&Fn, std::move(GCName)));
303 return;
304 }
305 It->second = std::move(GCName);
306}
307
308const std::string &LLVMContext::getGC(const Function &Fn) {
309 return pImpl->GCNames[&Fn];
310}
311
312void LLVMContext::deleteGC(const Function &Fn) {
313 pImpl->GCNames.erase(&Fn);
314}
315
316bool LLVMContext::shouldDiscardValueNames() const {
317 return pImpl->DiscardValueNames;
318}
319
320bool LLVMContext::isODRUniquingDebugTypes() const { return !!pImpl->DITypeMap; }
321
322void LLVMContext::enableDebugTypeODRUniquing() {
323 if (pImpl->DITypeMap)
324 return;
325
326 pImpl->DITypeMap.emplace();
327}
328
329void LLVMContext::disableDebugTypeODRUniquing() { pImpl->DITypeMap.reset(); }
330
331void LLVMContext::setDiscardValueNames(bool Discard) {
332 pImpl->DiscardValueNames = Discard;
333}
334
335OptPassGate &LLVMContext::getOptPassGate() const {
336 return pImpl->getOptPassGate();
337}
338
339void LLVMContext::setOptPassGate(OptPassGate& OPG) {
340 pImpl->setOptPassGate(OPG);
341}
342
343const DiagnosticHandler *LLVMContext::getDiagHandlerPtr() const {
344 return pImpl->DiagHandler.get();
345}
346
347std::unique_ptr<DiagnosticHandler> LLVMContext::getDiagnosticHandler() {
348 return std::move(pImpl->DiagHandler);
349}
350
351bool LLVMContext::supportsTypedPointers() const {
352 return !pImpl->ForceOpaquePointers;
353}

/build/llvm-toolchain-snapshot-13~++20210726100616+dead50d4427c/llvm/include/llvm/IR/DiagnosticInfo.h

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