/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/IR/DiagnosticInfo.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- llvm/Support/DiagnosticInfo.cpp - Diagnostic Definitions -*- C++ -*-===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | // |
10 | | // This file defines the different classes involved in low level diagnostics. |
11 | | // |
12 | | // Diagnostics reporting is still done as part of the LLVMContext. |
13 | | //===----------------------------------------------------------------------===// |
14 | | |
15 | | #include "llvm/IR/DiagnosticInfo.h" |
16 | | #include "LLVMContextImpl.h" |
17 | | #include "llvm/ADT/StringExtras.h" |
18 | | #include "llvm/ADT/Twine.h" |
19 | | #include "llvm/ADT/iterator_range.h" |
20 | | #include "llvm/IR/BasicBlock.h" |
21 | | #include "llvm/IR/Constants.h" |
22 | | #include "llvm/IR/DebugInfoMetadata.h" |
23 | | #include "llvm/IR/DerivedTypes.h" |
24 | | #include "llvm/IR/DiagnosticPrinter.h" |
25 | | #include "llvm/IR/Function.h" |
26 | | #include "llvm/IR/GlobalValue.h" |
27 | | #include "llvm/IR/Instruction.h" |
28 | | #include "llvm/IR/LLVMContext.h" |
29 | | #include "llvm/IR/Metadata.h" |
30 | | #include "llvm/IR/Module.h" |
31 | | #include "llvm/IR/Type.h" |
32 | | #include "llvm/IR/Value.h" |
33 | | #include "llvm/Support/Casting.h" |
34 | | #include "llvm/Support/CommandLine.h" |
35 | | #include "llvm/Support/ErrorHandling.h" |
36 | | #include "llvm/Support/Regex.h" |
37 | | #include "llvm/Support/raw_ostream.h" |
38 | | #include <atomic> |
39 | | #include <cassert> |
40 | | #include <memory> |
41 | | #include <string> |
42 | | |
43 | | using namespace llvm; |
44 | | |
45 | 69.8k | int llvm::getNextAvailablePluginDiagnosticKind() { |
46 | 69.8k | static std::atomic<int> PluginKindID(DK_FirstPluginKind); |
47 | 69.8k | return ++PluginKindID; |
48 | 69.8k | } |
49 | | |
50 | | const char *OptimizationRemarkAnalysis::AlwaysPrint = ""; |
51 | | |
52 | | DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I, |
53 | | const Twine &MsgStr, |
54 | | DiagnosticSeverity Severity) |
55 | 85 | : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr), Instr(&I) { |
56 | 85 | if (const MDNode *SrcLoc85 = I.getMetadata("srcloc")) { |
57 | 11 | if (SrcLoc->getNumOperands() != 0) |
58 | 11 | if (const auto *11 CI11 = |
59 | 11 | mdconst::dyn_extract<ConstantInt>(SrcLoc->getOperand(0))) |
60 | 11 | LocCookie = CI->getZExtValue(); |
61 | 11 | } |
62 | 85 | } |
63 | | |
64 | 253 | void DiagnosticInfoInlineAsm::print(DiagnosticPrinter &DP) const { |
65 | 253 | DP << getMsgStr(); |
66 | 253 | if (getLocCookie()) |
67 | 7 | DP << " at line " << getLocCookie(); |
68 | 253 | } |
69 | | |
70 | 12 | void DiagnosticInfoResourceLimit::print(DiagnosticPrinter &DP) const { |
71 | 12 | DP << getResourceName() << " limit"; |
72 | 12 | |
73 | 12 | if (getResourceLimit() != 0) |
74 | 5 | DP << " of " << getResourceLimit(); |
75 | 12 | |
76 | 12 | DP << " exceeded (" << getResourceSize() << ") in " << getFunction(); |
77 | 12 | } |
78 | | |
79 | 55 | void DiagnosticInfoDebugMetadataVersion::print(DiagnosticPrinter &DP) const { |
80 | 55 | DP << "ignoring debug info with an invalid version (" << getMetadataVersion() |
81 | 55 | << ") in " << getModule(); |
82 | 55 | } |
83 | | |
84 | | void DiagnosticInfoIgnoringInvalidDebugMetadata::print( |
85 | 9 | DiagnosticPrinter &DP) const { |
86 | 9 | DP << "ignoring invalid debug info in " << getModule().getModuleIdentifier(); |
87 | 9 | } |
88 | | |
89 | 25 | void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const { |
90 | 25 | if (!FileName.empty()25 ) { |
91 | 20 | DP << getFileName(); |
92 | 20 | if (LineNum > 0) |
93 | 16 | DP << ":" << getLineNum(); |
94 | 20 | DP << ": "; |
95 | 20 | } |
96 | 25 | DP << getMsg(); |
97 | 25 | } |
98 | | |
99 | 8 | void DiagnosticInfoPGOProfile::print(DiagnosticPrinter &DP) const { |
100 | 8 | if (getFileName()) |
101 | 8 | DP << getFileName() << ": "; |
102 | 8 | DP << getMsg(); |
103 | 8 | } |
104 | | |
105 | 5.60M | DiagnosticLocation::DiagnosticLocation(const DebugLoc &DL) { |
106 | 5.60M | if (!DL) |
107 | 5.50M | return; |
108 | 95.6k | Filename = DL->getFilename(); |
109 | 95.6k | Line = DL->getLine(); |
110 | 95.6k | Column = DL->getColumn(); |
111 | 95.6k | } |
112 | | |
113 | 1.21M | DiagnosticLocation::DiagnosticLocation(const DISubprogram *SP) { |
114 | 1.21M | if (!SP) |
115 | 1.17M | return; |
116 | 39.5k | Filename = SP->getFilename(); |
117 | 39.5k | Line = SP->getScopeLine(); |
118 | 39.5k | Column = 0; |
119 | 39.5k | } |
120 | | |
121 | | void DiagnosticInfoWithLocationBase::getLocation(StringRef *Filename, |
122 | | unsigned *Line, |
123 | 310 | unsigned *Column) const { |
124 | 310 | *Filename = Loc.getFilename(); |
125 | 310 | *Line = Loc.getLine(); |
126 | 310 | *Column = Loc.getColumn(); |
127 | 310 | } |
128 | | |
129 | 904 | const std::string DiagnosticInfoWithLocationBase::getLocationStr() const { |
130 | 904 | StringRef Filename("<unknown>"); |
131 | 904 | unsigned Line = 0; |
132 | 904 | unsigned Column = 0; |
133 | 904 | if (isLocationAvailable()) |
134 | 283 | getLocation(&Filename, &Line, &Column); |
135 | 904 | return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str(); |
136 | 904 | } |
137 | | |
138 | | DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, const Value *V) |
139 | 1.73M | : Key(Key) { |
140 | 1.73M | if (auto *F1.73M = dyn_cast<Function>(V)) { |
141 | 1.45M | if (DISubprogram *SP = F->getSubprogram()) |
142 | 20.3k | Loc = SP; |
143 | 1.45M | } |
144 | 276k | else if (auto *276k I276k = dyn_cast<Instruction>(V)) |
145 | 274k | Loc = I->getDebugLoc(); |
146 | 1.73M | |
147 | 1.73M | // Only include names that correspond to user variables. FIXME: we should use |
148 | 1.73M | // debug info if available to get the name of the user variable. |
149 | 1.73M | if (isa<llvm::Argument>(V) || 1.73M isa<GlobalValue>(V)1.73M ) |
150 | 1.45M | Val = GlobalValue::dropLLVMManglingEscape(V->getName()); |
151 | 276k | else if (276k isa<Constant>(V)276k ) { |
152 | 2.13k | raw_string_ostream OS(Val); |
153 | 2.13k | V->printAsOperand(OS, /*PrintType=*/false); |
154 | 276k | } else if (auto *274k I274k = dyn_cast<Instruction>(V)) |
155 | 274k | Val = I->getOpcodeName(); |
156 | 1.73M | } |
157 | | |
158 | | DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, const Type *T) |
159 | 49.8k | : Key(Key) { |
160 | 49.8k | raw_string_ostream OS(Val); |
161 | 49.8k | OS << *T; |
162 | 49.8k | } |
163 | | |
164 | | DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, StringRef S) |
165 | 28 | : Key(Key), Val(S.str()) {} |
166 | | |
167 | | DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, int N) |
168 | 681k | : Key(Key), Val(itostr(N)) {} |
169 | | |
170 | | DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, long N) |
171 | 0 | : Key(Key), Val(itostr(N)) {} |
172 | | |
173 | | DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, long long N) |
174 | 594k | : Key(Key), Val(itostr(N)) {} |
175 | | |
176 | | DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, unsigned N) |
177 | 180k | : Key(Key), Val(utostr(N)) {} |
178 | | |
179 | | DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, |
180 | | unsigned long N) |
181 | 4 | : Key(Key), Val(utostr(N)) {} |
182 | | |
183 | | DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, |
184 | | unsigned long long N) |
185 | 294 | : Key(Key), Val(utostr(N)) {} |
186 | | |
187 | | DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, DebugLoc Loc) |
188 | 66 | : Key(Key), Loc(Loc) { |
189 | 66 | if (Loc66 ) { |
190 | 60 | Val = (Loc->getFilename() + ":" + Twine(Loc.getLine()) + ":" + |
191 | 60 | Twine(Loc.getCol())).str(); |
192 | 66 | } else { |
193 | 6 | Val = "<UNKNOWN LOCATION>"; |
194 | 6 | } |
195 | 66 | } |
196 | | |
197 | 782 | void DiagnosticInfoOptimizationBase::print(DiagnosticPrinter &DP) const { |
198 | 782 | DP << getLocationStr() << ": " << getMsg(); |
199 | 782 | if (Hotness) |
200 | 35 | DP << " (hotness: " << *Hotness << ")"; |
201 | 782 | } |
202 | | |
203 | | OptimizationRemark::OptimizationRemark(const char *PassName, |
204 | | StringRef RemarkName, |
205 | | const DiagnosticLocation &Loc, |
206 | | const Value *CodeRegion) |
207 | | : DiagnosticInfoIROptimization( |
208 | | DK_OptimizationRemark, DS_Remark, PassName, RemarkName, |
209 | 2.15M | *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {} |
210 | | |
211 | | OptimizationRemark::OptimizationRemark(const char *PassName, |
212 | | StringRef RemarkName, |
213 | | const Instruction *Inst) |
214 | | : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName, |
215 | | RemarkName, *Inst->getParent()->getParent(), |
216 | 913k | Inst->getDebugLoc(), Inst->getParent()) {} |
217 | | |
218 | | // Helper to allow for an assert before attempting to return an invalid |
219 | | // reference. |
220 | 189 | static const BasicBlock &getFirstFunctionBlock(const Function *Func) { |
221 | 189 | assert(!Func->empty() && "Function does not have a body"); |
222 | 189 | return Func->front(); |
223 | 189 | } |
224 | | |
225 | | OptimizationRemark::OptimizationRemark(const char *PassName, |
226 | | StringRef RemarkName, |
227 | | const Function *Func) |
228 | | : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName, |
229 | | RemarkName, *Func, Func->getSubprogram(), |
230 | 189 | &getFirstFunctionBlock(Func)) {} |
231 | | |
232 | 2.39M | bool OptimizationRemark::isEnabled() const { |
233 | 2.39M | const Function &Fn = getFunction(); |
234 | 2.39M | LLVMContext &Ctx = Fn.getContext(); |
235 | 2.39M | return Ctx.getDiagHandlerPtr()->isPassedOptRemarkEnabled(getPassName()); |
236 | 2.39M | } |
237 | | |
238 | | OptimizationRemarkMissed::OptimizationRemarkMissed( |
239 | | const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc, |
240 | | const Value *CodeRegion) |
241 | | : DiagnosticInfoIROptimization( |
242 | | DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName, |
243 | 233k | *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {} |
244 | | |
245 | | OptimizationRemarkMissed::OptimizationRemarkMissed(const char *PassName, |
246 | | StringRef RemarkName, |
247 | | const Instruction *Inst) |
248 | | : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark, |
249 | | PassName, RemarkName, |
250 | | *Inst->getParent()->getParent(), |
251 | 1.49M | Inst->getDebugLoc(), Inst->getParent()) {} |
252 | | |
253 | 603k | bool OptimizationRemarkMissed::isEnabled() const { |
254 | 603k | const Function &Fn = getFunction(); |
255 | 603k | LLVMContext &Ctx = Fn.getContext(); |
256 | 603k | return Ctx.getDiagHandlerPtr()->isMissedOptRemarkEnabled(getPassName()); |
257 | 603k | } |
258 | | |
259 | | OptimizationRemarkAnalysis::OptimizationRemarkAnalysis( |
260 | | const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc, |
261 | | const Value *CodeRegion) |
262 | | : DiagnosticInfoIROptimization( |
263 | | DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName, |
264 | 439k | *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {} |
265 | | |
266 | | OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(const char *PassName, |
267 | | StringRef RemarkName, |
268 | | const Instruction *Inst) |
269 | | : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark, |
270 | | PassName, RemarkName, |
271 | | *Inst->getParent()->getParent(), |
272 | 1.60k | Inst->getDebugLoc(), Inst->getParent()) {} |
273 | | |
274 | | OptimizationRemarkAnalysis::OptimizationRemarkAnalysis( |
275 | | enum DiagnosticKind Kind, const char *PassName, StringRef RemarkName, |
276 | | const DiagnosticLocation &Loc, const Value *CodeRegion) |
277 | | : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, RemarkName, |
278 | | *cast<BasicBlock>(CodeRegion)->getParent(), |
279 | 1.98k | Loc, CodeRegion) {} |
280 | | |
281 | 177k | bool OptimizationRemarkAnalysis::isEnabled() const { |
282 | 177k | const Function &Fn = getFunction(); |
283 | 177k | LLVMContext &Ctx = Fn.getContext(); |
284 | 177k | return Ctx.getDiagHandlerPtr()->isAnalysisRemarkEnabled(getPassName()) || |
285 | 177k | shouldAlwaysPrint(); |
286 | 177k | } |
287 | | |
288 | 112 | void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const { |
289 | 112 | DP << Diagnostic; |
290 | 112 | } |
291 | | |
292 | | DiagnosticInfoOptimizationFailure::DiagnosticInfoOptimizationFailure( |
293 | | const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc, |
294 | | const Value *CodeRegion) |
295 | | : DiagnosticInfoIROptimization( |
296 | | DK_OptimizationFailure, DS_Warning, PassName, RemarkName, |
297 | 13 | *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {} |
298 | | |
299 | 17 | bool DiagnosticInfoOptimizationFailure::isEnabled() const { |
300 | 17 | // Only print warnings. |
301 | 17 | return getSeverity() == DS_Warning; |
302 | 17 | } |
303 | | |
304 | 122 | void DiagnosticInfoUnsupported::print(DiagnosticPrinter &DP) const { |
305 | 122 | std::string Str; |
306 | 122 | raw_string_ostream OS(Str); |
307 | 122 | |
308 | 122 | OS << getLocationStr() << ": in function " << getFunction().getName() << ' ' |
309 | 122 | << *getFunction().getFunctionType() << ": " << Msg << '\n'; |
310 | 122 | OS.flush(); |
311 | 122 | DP << Str; |
312 | 122 | } |
313 | | |
314 | 63.6k | void DiagnosticInfoISelFallback::print(DiagnosticPrinter &DP) const { |
315 | 63.6k | DP << "Instruction selection used fallback path for " << getFunction(); |
316 | 63.6k | } |
317 | | |
318 | 5.75M | void DiagnosticInfoOptimizationBase::insert(StringRef S) { |
319 | 5.75M | Args.emplace_back(S); |
320 | 5.75M | } |
321 | | |
322 | 3.24M | void DiagnosticInfoOptimizationBase::insert(Argument A) { |
323 | 3.24M | Args.push_back(std::move(A)); |
324 | 3.24M | } |
325 | | |
326 | 660k | void DiagnosticInfoOptimizationBase::insert(setIsVerbose V) { |
327 | 660k | IsVerbose = true; |
328 | 660k | } |
329 | | |
330 | 45.6k | void DiagnosticInfoOptimizationBase::insert(setExtraArgs EA) { |
331 | 45.6k | FirstExtraArgIndex = Args.size(); |
332 | 45.6k | } |
333 | | |
334 | 858 | std::string DiagnosticInfoOptimizationBase::getMsg() const { |
335 | 858 | std::string Str; |
336 | 858 | raw_string_ostream OS(Str); |
337 | 858 | for (const DiagnosticInfoOptimizationBase::Argument &Arg : |
338 | 858 | make_range(Args.begin(), FirstExtraArgIndex == -1 |
339 | 849 | ? Args.end() |
340 | 9 | : Args.begin() + FirstExtraArgIndex)) |
341 | 1.94k | OS << Arg.Val; |
342 | 858 | return OS.str(); |
343 | 858 | } |