1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | #include "clang/Basic/Diagnostic.h" |
14 | #include "clang/Basic/CharInfo.h" |
15 | #include "clang/Basic/DiagnosticError.h" |
16 | #include "clang/Basic/DiagnosticIDs.h" |
17 | #include "clang/Basic/DiagnosticOptions.h" |
18 | #include "clang/Basic/IdentifierTable.h" |
19 | #include "clang/Basic/PartialDiagnostic.h" |
20 | #include "clang/Basic/SourceLocation.h" |
21 | #include "clang/Basic/SourceManager.h" |
22 | #include "clang/Basic/Specifiers.h" |
23 | #include "clang/Basic/TokenKinds.h" |
24 | #include "llvm/ADT/SmallString.h" |
25 | #include "llvm/ADT/SmallVector.h" |
26 | #include "llvm/ADT/StringExtras.h" |
27 | #include "llvm/ADT/StringRef.h" |
28 | #include "llvm/Support/CrashRecoveryContext.h" |
29 | #include "llvm/Support/Locale.h" |
30 | #include "llvm/Support/raw_ostream.h" |
31 | #include <algorithm> |
32 | #include <cassert> |
33 | #include <cstddef> |
34 | #include <cstdint> |
35 | #include <cstring> |
36 | #include <limits> |
37 | #include <string> |
38 | #include <utility> |
39 | #include <vector> |
40 | |
41 | using namespace clang; |
42 | |
43 | const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, |
44 | DiagNullabilityKind nullability) { |
45 | StringRef string; |
46 | switch (nullability.first) { |
47 | case NullabilityKind::NonNull: |
48 | string = nullability.second ? "'nonnull'" : "'_Nonnull'"; |
49 | break; |
50 | |
51 | case NullabilityKind::Nullable: |
52 | string = nullability.second ? "'nullable'" : "'_Nullable'"; |
53 | break; |
54 | |
55 | case NullabilityKind::Unspecified: |
56 | string = nullability.second ? "'null_unspecified'" : "'_Null_unspecified'"; |
57 | break; |
58 | } |
59 | |
60 | DB.AddString(string); |
61 | return DB; |
62 | } |
63 | |
64 | static void DummyArgToStringFn(DiagnosticsEngine::ArgumentKind AK, intptr_t QT, |
65 | StringRef Modifier, StringRef Argument, |
66 | ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs, |
67 | SmallVectorImpl<char> &Output, |
68 | void *Cookie, |
69 | ArrayRef<intptr_t> QualTypeVals) { |
70 | StringRef Str = "<can't format argument>"; |
71 | Output.append(Str.begin(), Str.end()); |
72 | } |
73 | |
74 | DiagnosticsEngine::DiagnosticsEngine( |
75 | IntrusiveRefCntPtr<DiagnosticIDs> diags, |
76 | IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, DiagnosticConsumer *client, |
77 | bool ShouldOwnClient) |
78 | : Diags(std::move(diags)), DiagOpts(std::move(DiagOpts)) { |
79 | setClient(client, ShouldOwnClient); |
80 | ArgToStringFn = DummyArgToStringFn; |
81 | |
82 | Reset(); |
83 | } |
84 | |
85 | DiagnosticsEngine::~DiagnosticsEngine() { |
86 | |
87 | |
88 | setClient(nullptr); |
89 | } |
90 | |
91 | void DiagnosticsEngine::dump() const { |
92 | DiagStatesByLoc.dump(*SourceMgr); |
93 | } |
94 | |
95 | void DiagnosticsEngine::dump(StringRef DiagName) const { |
96 | DiagStatesByLoc.dump(*SourceMgr, DiagName); |
97 | } |
98 | |
99 | void DiagnosticsEngine::setClient(DiagnosticConsumer *client, |
100 | bool ShouldOwnClient) { |
101 | Owner.reset(ShouldOwnClient ? client : nullptr); |
102 | Client = client; |
103 | } |
104 | |
105 | void DiagnosticsEngine::pushMappings(SourceLocation Loc) { |
106 | DiagStateOnPushStack.push_back(GetCurDiagState()); |
107 | } |
108 | |
109 | bool DiagnosticsEngine::popMappings(SourceLocation Loc) { |
110 | if (DiagStateOnPushStack.empty()) |
111 | return false; |
112 | |
113 | if (DiagStateOnPushStack.back() != GetCurDiagState()) { |
114 | |
115 | PushDiagStatePoint(DiagStateOnPushStack.back(), Loc); |
116 | } |
117 | DiagStateOnPushStack.pop_back(); |
118 | return true; |
119 | } |
120 | |
121 | void DiagnosticsEngine::Reset() { |
122 | ErrorOccurred = false; |
123 | UncompilableErrorOccurred = false; |
124 | FatalErrorOccurred = false; |
125 | UnrecoverableErrorOccurred = false; |
126 | |
127 | NumWarnings = 0; |
128 | NumErrors = 0; |
129 | TrapNumErrorsOccurred = 0; |
130 | TrapNumUnrecoverableErrorsOccurred = 0; |
131 | |
132 | CurDiagID = std::numeric_limits<unsigned>::max(); |
133 | LastDiagLevel = DiagnosticIDs::Ignored; |
134 | DelayedDiagID = 0; |
135 | |
136 | |
137 | DiagStates.clear(); |
138 | DiagStatesByLoc.clear(); |
139 | DiagStateOnPushStack.clear(); |
140 | |
141 | |
142 | |
143 | DiagStates.emplace_back(); |
144 | DiagStatesByLoc.appendFirst(&DiagStates.back()); |
145 | } |
146 | |
147 | void DiagnosticsEngine::SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1, |
148 | StringRef Arg2) { |
149 | if (DelayedDiagID) |
150 | return; |
151 | |
152 | DelayedDiagID = DiagID; |
153 | DelayedDiagArg1 = Arg1.str(); |
154 | DelayedDiagArg2 = Arg2.str(); |
155 | } |
156 | |
157 | void DiagnosticsEngine::ReportDelayed() { |
158 | unsigned ID = DelayedDiagID; |
159 | DelayedDiagID = 0; |
160 | Report(ID) << DelayedDiagArg1 << DelayedDiagArg2; |
161 | } |
162 | |
163 | void DiagnosticsEngine::DiagStateMap::appendFirst(DiagState *State) { |
164 | (0) . __assert_fail ("Files.empty() && \"not first\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 164, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Files.empty() && "not first"); |
165 | FirstDiagState = CurDiagState = State; |
166 | CurDiagStateLoc = SourceLocation(); |
167 | } |
168 | |
169 | void DiagnosticsEngine::DiagStateMap::append(SourceManager &SrcMgr, |
170 | SourceLocation Loc, |
171 | DiagState *State) { |
172 | CurDiagState = State; |
173 | CurDiagStateLoc = Loc; |
174 | |
175 | std::pair<FileID, unsigned> Decomp = SrcMgr.getDecomposedLoc(Loc); |
176 | unsigned Offset = Decomp.second; |
177 | for (File *F = getFile(SrcMgr, Decomp.first); F; |
178 | Offset = F->ParentOffset, F = F->Parent) { |
179 | F->HasLocalTransitions = true; |
180 | auto &Last = F->StateTransitions.back(); |
181 | (0) . __assert_fail ("Last.Offset <= Offset && \"state transitions added out of order\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 181, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Last.Offset <= Offset && "state transitions added out of order"); |
182 | |
183 | if (Last.Offset == Offset) { |
184 | if (Last.State == State) |
185 | break; |
186 | Last.State = State; |
187 | continue; |
188 | } |
189 | |
190 | F->StateTransitions.push_back({State, Offset}); |
191 | } |
192 | } |
193 | |
194 | DiagnosticsEngine::DiagState * |
195 | DiagnosticsEngine::DiagStateMap::lookup(SourceManager &SrcMgr, |
196 | SourceLocation Loc) const { |
197 | |
198 | if (Files.empty()) |
199 | return FirstDiagState; |
200 | |
201 | std::pair<FileID, unsigned> Decomp = SrcMgr.getDecomposedLoc(Loc); |
202 | const File *F = getFile(SrcMgr, Decomp.first); |
203 | return F->lookup(Decomp.second); |
204 | } |
205 | |
206 | DiagnosticsEngine::DiagState * |
207 | DiagnosticsEngine::DiagStateMap::File::lookup(unsigned Offset) const { |
208 | auto OnePastIt = std::upper_bound( |
209 | StateTransitions.begin(), StateTransitions.end(), Offset, |
210 | [](unsigned Offset, const DiagStatePoint &P) { |
211 | return Offset < P.Offset; |
212 | }); |
213 | (0) . __assert_fail ("OnePastIt != StateTransitions.begin() && \"missing initial state\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 213, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(OnePastIt != StateTransitions.begin() && "missing initial state"); |
214 | return OnePastIt[-1].State; |
215 | } |
216 | |
217 | DiagnosticsEngine::DiagStateMap::File * |
218 | DiagnosticsEngine::DiagStateMap::getFile(SourceManager &SrcMgr, |
219 | FileID ID) const { |
220 | |
221 | auto Range = Files.equal_range(ID); |
222 | if (Range.first != Range.second) |
223 | return &Range.first->second; |
224 | auto &F = Files.insert(Range.first, std::make_pair(ID, File()))->second; |
225 | |
226 | |
227 | |
228 | if (ID.isValid()) { |
229 | std::pair<FileID, unsigned> Decomp = SrcMgr.getDecomposedIncludedLoc(ID); |
230 | F.Parent = getFile(SrcMgr, Decomp.first); |
231 | F.ParentOffset = Decomp.second; |
232 | F.StateTransitions.push_back({F.Parent->lookup(Decomp.second), 0}); |
233 | } else { |
234 | |
235 | |
236 | |
237 | |
238 | |
239 | |
240 | |
241 | F.StateTransitions.push_back({FirstDiagState, 0}); |
242 | } |
243 | return &F; |
244 | } |
245 | |
246 | void DiagnosticsEngine::DiagStateMap::dump(SourceManager &SrcMgr, |
247 | StringRef DiagName) const { |
248 | llvm::errs() << "diagnostic state at "; |
249 | CurDiagStateLoc.print(llvm::errs(), SrcMgr); |
250 | llvm::errs() << ": " << CurDiagState << "\n"; |
251 | |
252 | for (auto &F : Files) { |
253 | FileID ID = F.first; |
254 | File &File = F.second; |
255 | |
256 | bool PrintedOuterHeading = false; |
257 | auto PrintOuterHeading = [&] { |
258 | if (PrintedOuterHeading) return; |
259 | PrintedOuterHeading = true; |
260 | |
261 | llvm::errs() << "File " << &File << " <FileID " << ID.getHashValue() |
262 | << ">: " << SrcMgr.getBuffer(ID)->getBufferIdentifier(); |
263 | if (F.second.Parent) { |
264 | std::pair<FileID, unsigned> Decomp = |
265 | SrcMgr.getDecomposedIncludedLoc(ID); |
266 | assert(File.ParentOffset == Decomp.second); |
267 | llvm::errs() << " parent " << File.Parent << " <FileID " |
268 | << Decomp.first.getHashValue() << "> "; |
269 | SrcMgr.getLocForStartOfFile(Decomp.first) |
270 | .getLocWithOffset(Decomp.second) |
271 | .print(llvm::errs(), SrcMgr); |
272 | } |
273 | if (File.HasLocalTransitions) |
274 | llvm::errs() << " has_local_transitions"; |
275 | llvm::errs() << "\n"; |
276 | }; |
277 | |
278 | if (DiagName.empty()) |
279 | PrintOuterHeading(); |
280 | |
281 | for (DiagStatePoint &Transition : File.StateTransitions) { |
282 | bool PrintedInnerHeading = false; |
283 | auto PrintInnerHeading = [&] { |
284 | if (PrintedInnerHeading) return; |
285 | PrintedInnerHeading = true; |
286 | |
287 | PrintOuterHeading(); |
288 | llvm::errs() << " "; |
289 | SrcMgr.getLocForStartOfFile(ID) |
290 | .getLocWithOffset(Transition.Offset) |
291 | .print(llvm::errs(), SrcMgr); |
292 | llvm::errs() << ": state " << Transition.State << ":\n"; |
293 | }; |
294 | |
295 | if (DiagName.empty()) |
296 | PrintInnerHeading(); |
297 | |
298 | for (auto &Mapping : *Transition.State) { |
299 | StringRef Option = |
300 | DiagnosticIDs::getWarningOptionForDiag(Mapping.first); |
301 | if (!DiagName.empty() && DiagName != Option) |
302 | continue; |
303 | |
304 | PrintInnerHeading(); |
305 | llvm::errs() << " "; |
306 | if (Option.empty()) |
307 | llvm::errs() << "<unknown " << Mapping.first << ">"; |
308 | else |
309 | llvm::errs() << Option; |
310 | llvm::errs() << ": "; |
311 | |
312 | switch (Mapping.second.getSeverity()) { |
313 | case diag::Severity::Ignored: llvm::errs() << "ignored"; break; |
314 | case diag::Severity::Remark: llvm::errs() << "remark"; break; |
315 | case diag::Severity::Warning: llvm::errs() << "warning"; break; |
316 | case diag::Severity::Error: llvm::errs() << "error"; break; |
317 | case diag::Severity::Fatal: llvm::errs() << "fatal"; break; |
318 | } |
319 | |
320 | if (!Mapping.second.isUser()) |
321 | llvm::errs() << " default"; |
322 | if (Mapping.second.isPragma()) |
323 | llvm::errs() << " pragma"; |
324 | if (Mapping.second.hasNoWarningAsError()) |
325 | llvm::errs() << " no-error"; |
326 | if (Mapping.second.hasNoErrorAsFatal()) |
327 | llvm::errs() << " no-fatal"; |
328 | if (Mapping.second.wasUpgradedFromWarning()) |
329 | llvm::errs() << " overruled"; |
330 | llvm::errs() << "\n"; |
331 | } |
332 | } |
333 | } |
334 | } |
335 | |
336 | void DiagnosticsEngine::PushDiagStatePoint(DiagState *State, |
337 | SourceLocation Loc) { |
338 | (0) . __assert_fail ("Loc.isValid() && \"Adding invalid loc point\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 338, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Loc.isValid() && "Adding invalid loc point"); |
339 | DiagStatesByLoc.append(*SourceMgr, Loc, State); |
340 | } |
341 | |
342 | void DiagnosticsEngine::setSeverity(diag::kind Diag, diag::Severity Map, |
343 | SourceLocation L) { |
344 | (0) . __assert_fail ("Diag < diag..DIAG_UPPER_LIMIT && \"Can only map builtin diagnostics\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 345, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Diag < diag::DIAG_UPPER_LIMIT && |
345 | (0) . __assert_fail ("Diag < diag..DIAG_UPPER_LIMIT && \"Can only map builtin diagnostics\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 345, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Can only map builtin diagnostics"); |
346 | (0) . __assert_fail ("(Diags->isBuiltinWarningOrExtension(Diag) || (Map == diag..Severity..Fatal || Map == diag..Severity..Error)) && \"Cannot map errors into warnings!\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 348, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((Diags->isBuiltinWarningOrExtension(Diag) || |
347 | (0) . __assert_fail ("(Diags->isBuiltinWarningOrExtension(Diag) || (Map == diag..Severity..Fatal || Map == diag..Severity..Error)) && \"Cannot map errors into warnings!\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 348, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> (Map == diag::Severity::Fatal || Map == diag::Severity::Error)) && |
348 | (0) . __assert_fail ("(Diags->isBuiltinWarningOrExtension(Diag) || (Map == diag..Severity..Fatal || Map == diag..Severity..Error)) && \"Cannot map errors into warnings!\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 348, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Cannot map errors into warnings!"); |
349 | (0) . __assert_fail ("(L.isInvalid() || SourceMgr) && \"No SourceMgr for valid location\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 349, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((L.isInvalid() || SourceMgr) && "No SourceMgr for valid location"); |
350 | |
351 | |
352 | bool WasUpgradedFromWarning = false; |
353 | if (Map == diag::Severity::Warning) { |
354 | DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag); |
355 | if (Info.getSeverity() == diag::Severity::Error || |
356 | Info.getSeverity() == diag::Severity::Fatal) { |
357 | Map = Info.getSeverity(); |
358 | WasUpgradedFromWarning = true; |
359 | } |
360 | } |
361 | DiagnosticMapping Mapping = makeUserMapping(Map, L); |
362 | Mapping.setUpgradedFromWarning(WasUpgradedFromWarning); |
363 | |
364 | |
365 | if ((L.isInvalid() || L == DiagStatesByLoc.getCurDiagStateLoc()) && |
366 | DiagStatesByLoc.getCurDiagState()) { |
367 | |
368 | |
369 | |
370 | |
371 | DiagStatesByLoc.getCurDiagState()->setMapping(Diag, Mapping); |
372 | return; |
373 | } |
374 | |
375 | |
376 | |
377 | |
378 | DiagStates.push_back(*GetCurDiagState()); |
379 | DiagStates.back().setMapping(Diag, Mapping); |
380 | PushDiagStatePoint(&DiagStates.back(), L); |
381 | } |
382 | |
383 | bool DiagnosticsEngine::setSeverityForGroup(diag::Flavor Flavor, |
384 | StringRef Group, diag::Severity Map, |
385 | SourceLocation Loc) { |
386 | |
387 | SmallVector<diag::kind, 256> GroupDiags; |
388 | if (Diags->getDiagnosticsInGroup(Flavor, Group, GroupDiags)) |
389 | return true; |
390 | |
391 | |
392 | for (diag::kind Diag : GroupDiags) |
393 | setSeverity(Diag, Map, Loc); |
394 | |
395 | return false; |
396 | } |
397 | |
398 | bool DiagnosticsEngine::setDiagnosticGroupWarningAsError(StringRef Group, |
399 | bool Enabled) { |
400 | |
401 | |
402 | if (Enabled) |
403 | return setSeverityForGroup(diag::Flavor::WarningOrError, Group, |
404 | diag::Severity::Error); |
405 | |
406 | |
407 | |
408 | |
409 | |
410 | SmallVector<diag::kind, 8> GroupDiags; |
411 | if (Diags->getDiagnosticsInGroup(diag::Flavor::WarningOrError, Group, |
412 | GroupDiags)) |
413 | return true; |
414 | |
415 | |
416 | for (diag::kind Diag : GroupDiags) { |
417 | DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag); |
418 | |
419 | if (Info.getSeverity() == diag::Severity::Error || |
420 | Info.getSeverity() == diag::Severity::Fatal) |
421 | Info.setSeverity(diag::Severity::Warning); |
422 | |
423 | Info.setNoWarningAsError(true); |
424 | } |
425 | |
426 | return false; |
427 | } |
428 | |
429 | bool DiagnosticsEngine::setDiagnosticGroupErrorAsFatal(StringRef Group, |
430 | bool Enabled) { |
431 | |
432 | |
433 | if (Enabled) |
434 | return setSeverityForGroup(diag::Flavor::WarningOrError, Group, |
435 | diag::Severity::Fatal); |
436 | |
437 | |
438 | |
439 | |
440 | |
441 | SmallVector<diag::kind, 8> GroupDiags; |
442 | if (Diags->getDiagnosticsInGroup(diag::Flavor::WarningOrError, Group, |
443 | GroupDiags)) |
444 | return true; |
445 | |
446 | |
447 | for (diag::kind Diag : GroupDiags) { |
448 | DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag); |
449 | |
450 | if (Info.getSeverity() == diag::Severity::Fatal) |
451 | Info.setSeverity(diag::Severity::Error); |
452 | |
453 | Info.setNoErrorAsFatal(true); |
454 | } |
455 | |
456 | return false; |
457 | } |
458 | |
459 | void DiagnosticsEngine::setSeverityForAll(diag::Flavor Flavor, |
460 | diag::Severity Map, |
461 | SourceLocation Loc) { |
462 | |
463 | std::vector<diag::kind> AllDiags; |
464 | DiagnosticIDs::getAllDiagnostics(Flavor, AllDiags); |
465 | |
466 | |
467 | for (diag::kind Diag : AllDiags) |
468 | if (Diags->isBuiltinWarningOrExtension(Diag)) |
469 | setSeverity(Diag, Map, Loc); |
470 | } |
471 | |
472 | void DiagnosticsEngine::Report(const StoredDiagnostic &storedDiag) { |
473 | (0) . __assert_fail ("CurDiagID == std..numeric_limits..max() && \"Multiple diagnostics in flight at once!\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 474, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(CurDiagID == std::numeric_limits<unsigned>::max() && |
474 | (0) . __assert_fail ("CurDiagID == std..numeric_limits..max() && \"Multiple diagnostics in flight at once!\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 474, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Multiple diagnostics in flight at once!"); |
475 | |
476 | CurDiagLoc = storedDiag.getLocation(); |
477 | CurDiagID = storedDiag.getID(); |
478 | NumDiagArgs = 0; |
479 | |
480 | DiagRanges.clear(); |
481 | DiagRanges.append(storedDiag.range_begin(), storedDiag.range_end()); |
482 | |
483 | DiagFixItHints.clear(); |
484 | DiagFixItHints.append(storedDiag.fixit_begin(), storedDiag.fixit_end()); |
485 | |
486 | (0) . __assert_fail ("Client && \"DiagnosticConsumer not set!\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 486, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Client && "DiagnosticConsumer not set!"); |
487 | Level DiagLevel = storedDiag.getLevel(); |
488 | Diagnostic Info(this, storedDiag.getMessage()); |
489 | Client->HandleDiagnostic(DiagLevel, Info); |
490 | if (Client->IncludeInDiagnosticCounts()) { |
491 | if (DiagLevel == DiagnosticsEngine::Warning) |
492 | ++NumWarnings; |
493 | } |
494 | |
495 | CurDiagID = std::numeric_limits<unsigned>::max(); |
496 | } |
497 | |
498 | bool DiagnosticsEngine::EmitCurrentDiagnostic(bool Force) { |
499 | (0) . __assert_fail ("getClient() && \"DiagnosticClient not set!\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 499, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(getClient() && "DiagnosticClient not set!"); |
500 | |
501 | bool Emitted; |
502 | if (Force) { |
503 | Diagnostic Info(this); |
504 | |
505 | |
506 | DiagnosticIDs::Level DiagLevel |
507 | = Diags->getDiagnosticLevel(Info.getID(), Info.getLocation(), *this); |
508 | |
509 | Emitted = (DiagLevel != DiagnosticIDs::Ignored); |
510 | if (Emitted) { |
511 | |
512 | Diags->EmitDiag(*this, DiagLevel); |
513 | } |
514 | } else { |
515 | |
516 | |
517 | Emitted = ProcessDiag(); |
518 | } |
519 | |
520 | |
521 | Clear(); |
522 | |
523 | |
524 | if (!Force && DelayedDiagID) |
525 | ReportDelayed(); |
526 | |
527 | return Emitted; |
528 | } |
529 | |
530 | DiagnosticConsumer::~DiagnosticConsumer() = default; |
531 | |
532 | void DiagnosticConsumer::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, |
533 | const Diagnostic &Info) { |
534 | if (!IncludeInDiagnosticCounts()) |
535 | return; |
536 | |
537 | if (DiagLevel == DiagnosticsEngine::Warning) |
538 | ++NumWarnings; |
539 | else if (DiagLevel >= DiagnosticsEngine::Error) |
540 | ++NumErrors; |
541 | } |
542 | |
543 | |
544 | template <std::size_t StrLen> |
545 | static bool ModifierIs(const char *Modifier, unsigned ModifierLen, |
546 | const char (&Str)[StrLen]) { |
547 | return StrLen-1 == ModifierLen && memcmp(Modifier, Str, StrLen-1) == 0; |
548 | } |
549 | |
550 | |
551 | |
552 | static const char *ScanFormat(const char *I, const char *E, char Target) { |
553 | unsigned Depth = 0; |
554 | |
555 | for ( ; I != E; ++I) { |
556 | if (Depth == 0 && *I == Target) return I; |
557 | if (Depth != 0 && *I == '}') Depth--; |
558 | |
559 | if (*I == '%') { |
560 | I++; |
561 | if (I == E) break; |
562 | |
563 | |
564 | |
565 | |
566 | if (!isDigit(*I) && !isPunctuation(*I)) { |
567 | for (I++; I != E && !isDigit(*I) && *I != '{'; I++) ; |
568 | if (I == E) break; |
569 | if (*I == '{') |
570 | Depth++; |
571 | } |
572 | } |
573 | } |
574 | return E; |
575 | } |
576 | |
577 | |
578 | |
579 | |
580 | |
581 | |
582 | static void HandleSelectModifier(const Diagnostic &DInfo, unsigned ValNo, |
583 | const char *Argument, unsigned ArgumentLen, |
584 | SmallVectorImpl<char> &OutStr) { |
585 | const char *ArgumentEnd = Argument+ArgumentLen; |
586 | |
587 | |
588 | while (ValNo) { |
589 | const char *NextVal = ScanFormat(Argument, ArgumentEnd, '|'); |
590 | (0) . __assert_fail ("NextVal != ArgumentEnd && \"Value for integer select modifier was\" \" larger than the number of options in the diagnostic string!\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 591, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(NextVal != ArgumentEnd && "Value for integer select modifier was" |
591 | (0) . __assert_fail ("NextVal != ArgumentEnd && \"Value for integer select modifier was\" \" larger than the number of options in the diagnostic string!\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 591, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> " larger than the number of options in the diagnostic string!"); |
592 | Argument = NextVal+1; |
593 | --ValNo; |
594 | } |
595 | |
596 | |
597 | const char *EndPtr = ScanFormat(Argument, ArgumentEnd, '|'); |
598 | |
599 | |
600 | DInfo.FormatDiagnostic(Argument, EndPtr, OutStr); |
601 | } |
602 | |
603 | |
604 | |
605 | |
606 | static void HandleIntegerSModifier(unsigned ValNo, |
607 | SmallVectorImpl<char> &OutStr) { |
608 | if (ValNo != 1) |
609 | OutStr.push_back('s'); |
610 | } |
611 | |
612 | |
613 | |
614 | |
615 | |
616 | static void HandleOrdinalModifier(unsigned ValNo, |
617 | SmallVectorImpl<char> &OutStr) { |
618 | (0) . __assert_fail ("ValNo != 0 && \"ValNo must be strictly positive!\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 618, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ValNo != 0 && "ValNo must be strictly positive!"); |
619 | |
620 | llvm::raw_svector_ostream Out(OutStr); |
621 | |
622 | |
623 | |
624 | Out << ValNo << llvm::getOrdinalSuffix(ValNo); |
625 | } |
626 | |
627 | |
628 | static unsigned PluralNumber(const char *&Start, const char *End) { |
629 | |
630 | unsigned Val = 0; |
631 | while (Start != End && *Start >= '0' && *Start <= '9') { |
632 | Val *= 10; |
633 | Val += *Start - '0'; |
634 | ++Start; |
635 | } |
636 | return Val; |
637 | } |
638 | |
639 | |
640 | static bool TestPluralRange(unsigned Val, const char *&Start, const char *End) { |
641 | if (*Start != '[') { |
642 | unsigned Ref = PluralNumber(Start, End); |
643 | return Ref == Val; |
644 | } |
645 | |
646 | ++Start; |
647 | unsigned Low = PluralNumber(Start, End); |
648 | (0) . __assert_fail ("*Start == ',' && \"Bad plural expression syntax. expected ,\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 648, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(*Start == ',' && "Bad plural expression syntax: expected ,"); |
649 | ++Start; |
650 | unsigned High = PluralNumber(Start, End); |
651 | (0) . __assert_fail ("*Start == ']' && \"Bad plural expression syntax. expected )\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 651, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(*Start == ']' && "Bad plural expression syntax: expected )"); |
652 | ++Start; |
653 | return Low <= Val && Val <= High; |
654 | } |
655 | |
656 | |
657 | static bool EvalPluralExpr(unsigned ValNo, const char *Start, const char *End) { |
658 | |
659 | if (*Start == ':') |
660 | return true; |
661 | |
662 | while (true) { |
663 | char C = *Start; |
664 | if (C == '%') { |
665 | |
666 | ++Start; |
667 | unsigned Arg = PluralNumber(Start, End); |
668 | assert(*Start == '=' && "Bad plural expression syntax: expected ="); |
669 | ++Start; |
670 | unsigned ValMod = ValNo % Arg; |
671 | if (TestPluralRange(ValMod, Start, End)) |
672 | return true; |
673 | } else { |
674 | (0) . __assert_fail ("(C == '[' || (C >= '0' && C <= '9')) && \"Bad plural expression syntax. unexpected character\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 675, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((C == '[' || (C >= '0' && C <= '9')) && |
675 | (0) . __assert_fail ("(C == '[' || (C >= '0' && C <= '9')) && \"Bad plural expression syntax. unexpected character\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 675, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Bad plural expression syntax: unexpected character"); |
676 | |
677 | if (TestPluralRange(ValNo, Start, End)) |
678 | return true; |
679 | } |
680 | |
681 | |
682 | Start = std::find(Start, End, ','); |
683 | if (Start == End) |
684 | break; |
685 | ++Start; |
686 | } |
687 | return false; |
688 | } |
689 | |
690 | |
691 | |
692 | |
693 | |
694 | |
695 | |
696 | |
697 | |
698 | |
699 | |
700 | |
701 | |
702 | |
703 | |
704 | |
705 | |
706 | |
707 | |
708 | |
709 | |
710 | |
711 | |
712 | |
713 | |
714 | |
715 | |
716 | |
717 | |
718 | |
719 | |
720 | |
721 | |
722 | |
723 | static void HandlePluralModifier(const Diagnostic &DInfo, unsigned ValNo, |
724 | const char *Argument, unsigned ArgumentLen, |
725 | SmallVectorImpl<char> &OutStr) { |
726 | const char *ArgumentEnd = Argument + ArgumentLen; |
727 | while (true) { |
728 | (0) . __assert_fail ("Argument < ArgumentEnd && \"Plural expression didn't match.\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 728, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Argument < ArgumentEnd && "Plural expression didn't match."); |
729 | const char *ExprEnd = Argument; |
730 | while (*ExprEnd != ':') { |
731 | (0) . __assert_fail ("ExprEnd != ArgumentEnd && \"Plural missing expression end\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 731, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ExprEnd != ArgumentEnd && "Plural missing expression end"); |
732 | ++ExprEnd; |
733 | } |
734 | if (EvalPluralExpr(ValNo, Argument, ExprEnd)) { |
735 | Argument = ExprEnd + 1; |
736 | ExprEnd = ScanFormat(Argument, ArgumentEnd, '|'); |
737 | |
738 | |
739 | |
740 | DInfo.FormatDiagnostic(Argument, ExprEnd, OutStr); |
741 | return; |
742 | } |
743 | Argument = ScanFormat(Argument, ArgumentEnd - 1, '|') + 1; |
744 | } |
745 | } |
746 | |
747 | |
748 | |
749 | |
750 | static const char *getTokenDescForDiagnostic(tok::TokenKind Kind) { |
751 | switch (Kind) { |
752 | case tok::identifier: |
753 | return "identifier"; |
754 | default: |
755 | return nullptr; |
756 | } |
757 | } |
758 | |
759 | |
760 | |
761 | |
762 | void Diagnostic:: |
763 | FormatDiagnostic(SmallVectorImpl<char> &OutStr) const { |
764 | if (!StoredDiagMessage.empty()) { |
765 | OutStr.append(StoredDiagMessage.begin(), StoredDiagMessage.end()); |
766 | return; |
767 | } |
768 | |
769 | StringRef Diag = |
770 | getDiags()->getDiagnosticIDs()->getDescription(getID()); |
771 | |
772 | FormatDiagnostic(Diag.begin(), Diag.end(), OutStr); |
773 | } |
774 | |
775 | void Diagnostic:: |
776 | FormatDiagnostic(const char *DiagStr, const char *DiagEnd, |
777 | SmallVectorImpl<char> &OutStr) const { |
778 | |
779 | |
780 | |
781 | if (DiagEnd - DiagStr == 2 && |
782 | StringRef(DiagStr, DiagEnd - DiagStr).equals("%0") && |
783 | getArgKind(0) == DiagnosticsEngine::ak_std_string) { |
784 | const std::string &S = getArgStdStr(0); |
785 | for (char c : S) { |
786 | if (llvm::sys::locale::isPrint(c) || c == '\t') { |
787 | OutStr.push_back(c); |
788 | } |
789 | } |
790 | return; |
791 | } |
792 | |
793 | |
794 | |
795 | |
796 | |
797 | SmallVector<DiagnosticsEngine::ArgumentValue, 8> FormattedArgs; |
798 | |
799 | |
800 | |
801 | SmallVector<intptr_t, 2> QualTypeVals; |
802 | SmallVector<char, 64> Tree; |
803 | |
804 | for (unsigned i = 0, e = getNumArgs(); i < e; ++i) |
805 | if (getArgKind(i) == DiagnosticsEngine::ak_qualtype) |
806 | QualTypeVals.push_back(getRawArg(i)); |
807 | |
808 | while (DiagStr != DiagEnd) { |
809 | if (DiagStr[0] != '%') { |
810 | |
811 | const char *StrEnd = std::find(DiagStr, DiagEnd, '%'); |
812 | OutStr.append(DiagStr, StrEnd); |
813 | DiagStr = StrEnd; |
814 | continue; |
815 | } else if (isPunctuation(DiagStr[1])) { |
816 | OutStr.push_back(DiagStr[1]); |
817 | DiagStr += 2; |
818 | continue; |
819 | } |
820 | |
821 | |
822 | ++DiagStr; |
823 | |
824 | |
825 | |
826 | |
827 | |
828 | |
829 | const char *Modifier = nullptr, *Argument = nullptr; |
830 | unsigned ModifierLen = 0, ArgumentLen = 0; |
831 | |
832 | |
833 | if (!isDigit(DiagStr[0])) { |
834 | Modifier = DiagStr; |
835 | while (DiagStr[0] == '-' || |
836 | (DiagStr[0] >= 'a' && DiagStr[0] <= 'z')) |
837 | ++DiagStr; |
838 | ModifierLen = DiagStr-Modifier; |
839 | |
840 | |
841 | if (DiagStr[0] == '{') { |
842 | ++DiagStr; |
843 | Argument = DiagStr; |
844 | |
845 | DiagStr = ScanFormat(DiagStr, DiagEnd, '}'); |
846 | (0) . __assert_fail ("DiagStr != DiagEnd && \"Mismatched {}'s in diagnostic string!\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 846, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(DiagStr != DiagEnd && "Mismatched {}'s in diagnostic string!"); |
847 | ArgumentLen = DiagStr-Argument; |
848 | ++DiagStr; |
849 | } |
850 | } |
851 | |
852 | (0) . __assert_fail ("isDigit(*DiagStr) && \"Invalid format for argument in diagnostic\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 852, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isDigit(*DiagStr) && "Invalid format for argument in diagnostic"); |
853 | unsigned ArgNo = *DiagStr++ - '0'; |
854 | |
855 | |
856 | unsigned ArgNo2 = ArgNo; |
857 | |
858 | DiagnosticsEngine::ArgumentKind Kind = getArgKind(ArgNo); |
859 | if (ModifierIs(Modifier, ModifierLen, "diff")) { |
860 | (0) . __assert_fail ("*DiagStr == ',' && isDigit(*(DiagStr + 1)) && \"Invalid format for diff modifier\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 861, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(*DiagStr == ',' && isDigit(*(DiagStr + 1)) && |
861 | (0) . __assert_fail ("*DiagStr == ',' && isDigit(*(DiagStr + 1)) && \"Invalid format for diff modifier\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 861, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Invalid format for diff modifier"); |
862 | ++DiagStr; |
863 | ArgNo2 = *DiagStr++ - '0'; |
864 | DiagnosticsEngine::ArgumentKind Kind2 = getArgKind(ArgNo2); |
865 | if (Kind == DiagnosticsEngine::ak_qualtype && |
866 | Kind2 == DiagnosticsEngine::ak_qualtype) |
867 | Kind = DiagnosticsEngine::ak_qualtype_pair; |
868 | else { |
869 | |
870 | |
871 | |
872 | |
873 | |
874 | const char *ArgumentEnd = Argument + ArgumentLen; |
875 | const char *Pipe = ScanFormat(Argument, ArgumentEnd, '|'); |
876 | (0) . __assert_fail ("ScanFormat(Pipe + 1, ArgumentEnd, '|') == ArgumentEnd && \"Found too many '|'s in a %diff modifier!\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 877, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ScanFormat(Pipe + 1, ArgumentEnd, '|') == ArgumentEnd && |
877 | (0) . __assert_fail ("ScanFormat(Pipe + 1, ArgumentEnd, '|') == ArgumentEnd && \"Found too many '|'s in a %diff modifier!\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 877, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Found too many '|'s in a %diff modifier!"); |
878 | const char *FirstDollar = ScanFormat(Argument, Pipe, '$'); |
879 | const char *SecondDollar = ScanFormat(FirstDollar + 1, Pipe, '$'); |
880 | const char ArgStr1[] = { '%', static_cast<char>('0' + ArgNo) }; |
881 | const char ArgStr2[] = { '%', static_cast<char>('0' + ArgNo2) }; |
882 | FormatDiagnostic(Argument, FirstDollar, OutStr); |
883 | FormatDiagnostic(ArgStr1, ArgStr1 + 2, OutStr); |
884 | FormatDiagnostic(FirstDollar + 1, SecondDollar, OutStr); |
885 | FormatDiagnostic(ArgStr2, ArgStr2 + 2, OutStr); |
886 | FormatDiagnostic(SecondDollar + 1, Pipe, OutStr); |
887 | continue; |
888 | } |
889 | } |
890 | |
891 | switch (Kind) { |
892 | |
893 | case DiagnosticsEngine::ak_std_string: { |
894 | const std::string &S = getArgStdStr(ArgNo); |
895 | (0) . __assert_fail ("ModifierLen == 0 && \"No modifiers for strings yet\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 895, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ModifierLen == 0 && "No modifiers for strings yet"); |
896 | OutStr.append(S.begin(), S.end()); |
897 | break; |
898 | } |
899 | case DiagnosticsEngine::ak_c_string: { |
900 | const char *S = getArgCStr(ArgNo); |
901 | (0) . __assert_fail ("ModifierLen == 0 && \"No modifiers for strings yet\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 901, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ModifierLen == 0 && "No modifiers for strings yet"); |
902 | |
903 | |
904 | if (!S) |
905 | S = "(null)"; |
906 | |
907 | OutStr.append(S, S + strlen(S)); |
908 | break; |
909 | } |
910 | |
911 | case DiagnosticsEngine::ak_sint: { |
912 | int Val = getArgSInt(ArgNo); |
913 | |
914 | if (ModifierIs(Modifier, ModifierLen, "select")) { |
915 | HandleSelectModifier(*this, (unsigned)Val, Argument, ArgumentLen, |
916 | OutStr); |
917 | } else if (ModifierIs(Modifier, ModifierLen, "s")) { |
918 | HandleIntegerSModifier(Val, OutStr); |
919 | } else if (ModifierIs(Modifier, ModifierLen, "plural")) { |
920 | HandlePluralModifier(*this, (unsigned)Val, Argument, ArgumentLen, |
921 | OutStr); |
922 | } else if (ModifierIs(Modifier, ModifierLen, "ordinal")) { |
923 | HandleOrdinalModifier((unsigned)Val, OutStr); |
924 | } else { |
925 | (0) . __assert_fail ("ModifierLen == 0 && \"Unknown integer modifier\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 925, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ModifierLen == 0 && "Unknown integer modifier"); |
926 | llvm::raw_svector_ostream(OutStr) << Val; |
927 | } |
928 | break; |
929 | } |
930 | case DiagnosticsEngine::ak_uint: { |
931 | unsigned Val = getArgUInt(ArgNo); |
932 | |
933 | if (ModifierIs(Modifier, ModifierLen, "select")) { |
934 | HandleSelectModifier(*this, Val, Argument, ArgumentLen, OutStr); |
935 | } else if (ModifierIs(Modifier, ModifierLen, "s")) { |
936 | HandleIntegerSModifier(Val, OutStr); |
937 | } else if (ModifierIs(Modifier, ModifierLen, "plural")) { |
938 | HandlePluralModifier(*this, (unsigned)Val, Argument, ArgumentLen, |
939 | OutStr); |
940 | } else if (ModifierIs(Modifier, ModifierLen, "ordinal")) { |
941 | HandleOrdinalModifier(Val, OutStr); |
942 | } else { |
943 | (0) . __assert_fail ("ModifierLen == 0 && \"Unknown integer modifier\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 943, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ModifierLen == 0 && "Unknown integer modifier"); |
944 | llvm::raw_svector_ostream(OutStr) << Val; |
945 | } |
946 | break; |
947 | } |
948 | |
949 | case DiagnosticsEngine::ak_tokenkind: { |
950 | tok::TokenKind Kind = static_cast<tok::TokenKind>(getRawArg(ArgNo)); |
951 | (0) . __assert_fail ("ModifierLen == 0 && \"No modifiers for token kinds yet\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 951, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ModifierLen == 0 && "No modifiers for token kinds yet"); |
952 | |
953 | llvm::raw_svector_ostream Out(OutStr); |
954 | if (const char *S = tok::getPunctuatorSpelling(Kind)) |
955 | |
956 | Out << '\'' << S << '\''; |
957 | else if (const char *S = tok::getKeywordSpelling(Kind)) |
958 | |
959 | Out << S; |
960 | else if (const char *S = getTokenDescForDiagnostic(Kind)) |
961 | |
962 | Out << S; |
963 | else if (const char *S = tok::getTokenName(Kind)) |
964 | |
965 | Out << '<' << S << '>'; |
966 | else |
967 | Out << "(null)"; |
968 | break; |
969 | } |
970 | |
971 | case DiagnosticsEngine::ak_identifierinfo: { |
972 | const IdentifierInfo *II = getArgIdentifier(ArgNo); |
973 | (0) . __assert_fail ("ModifierLen == 0 && \"No modifiers for strings yet\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 973, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ModifierLen == 0 && "No modifiers for strings yet"); |
974 | |
975 | |
976 | if (!II) { |
977 | const char *S = "(null)"; |
978 | OutStr.append(S, S + strlen(S)); |
979 | continue; |
980 | } |
981 | |
982 | llvm::raw_svector_ostream(OutStr) << '\'' << II->getName() << '\''; |
983 | break; |
984 | } |
985 | case DiagnosticsEngine::ak_qual: |
986 | case DiagnosticsEngine::ak_qualtype: |
987 | case DiagnosticsEngine::ak_declarationname: |
988 | case DiagnosticsEngine::ak_nameddecl: |
989 | case DiagnosticsEngine::ak_nestednamespec: |
990 | case DiagnosticsEngine::ak_declcontext: |
991 | case DiagnosticsEngine::ak_attr: |
992 | getDiags()->ConvertArgToString(Kind, getRawArg(ArgNo), |
993 | StringRef(Modifier, ModifierLen), |
994 | StringRef(Argument, ArgumentLen), |
995 | FormattedArgs, |
996 | OutStr, QualTypeVals); |
997 | break; |
998 | case DiagnosticsEngine::ak_qualtype_pair: { |
999 | |
1000 | TemplateDiffTypes TDT; |
1001 | TDT.FromType = getRawArg(ArgNo); |
1002 | TDT.ToType = getRawArg(ArgNo2); |
1003 | TDT.ElideType = getDiags()->ElideType; |
1004 | TDT.ShowColors = getDiags()->ShowColors; |
1005 | TDT.TemplateDiffUsed = false; |
1006 | intptr_t val = reinterpret_cast<intptr_t>(&TDT); |
1007 | |
1008 | const char *ArgumentEnd = Argument + ArgumentLen; |
1009 | const char *Pipe = ScanFormat(Argument, ArgumentEnd, '|'); |
1010 | |
1011 | |
1012 | |
1013 | if (getDiags()->PrintTemplateTree && Tree.empty()) { |
1014 | TDT.PrintFromType = true; |
1015 | TDT.PrintTree = true; |
1016 | getDiags()->ConvertArgToString(Kind, val, |
1017 | StringRef(Modifier, ModifierLen), |
1018 | StringRef(Argument, ArgumentLen), |
1019 | FormattedArgs, |
1020 | Tree, QualTypeVals); |
1021 | |
1022 | if (!Tree.empty()) { |
1023 | FormatDiagnostic(Pipe + 1, ArgumentEnd, OutStr); |
1024 | break; |
1025 | } |
1026 | } |
1027 | |
1028 | |
1029 | |
1030 | const char *FirstDollar = ScanFormat(Argument, ArgumentEnd, '$'); |
1031 | const char *SecondDollar = ScanFormat(FirstDollar + 1, ArgumentEnd, '$'); |
1032 | |
1033 | |
1034 | FormatDiagnostic(Argument, FirstDollar, OutStr); |
1035 | |
1036 | |
1037 | TDT.PrintTree = false; |
1038 | TDT.PrintFromType = true; |
1039 | getDiags()->ConvertArgToString(Kind, val, |
1040 | StringRef(Modifier, ModifierLen), |
1041 | StringRef(Argument, ArgumentLen), |
1042 | FormattedArgs, |
1043 | OutStr, QualTypeVals); |
1044 | if (!TDT.TemplateDiffUsed) |
1045 | FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_qualtype, |
1046 | TDT.FromType)); |
1047 | |
1048 | |
1049 | FormatDiagnostic(FirstDollar + 1, SecondDollar, OutStr); |
1050 | |
1051 | |
1052 | TDT.PrintFromType = false; |
1053 | getDiags()->ConvertArgToString(Kind, val, |
1054 | StringRef(Modifier, ModifierLen), |
1055 | StringRef(Argument, ArgumentLen), |
1056 | FormattedArgs, |
1057 | OutStr, QualTypeVals); |
1058 | if (!TDT.TemplateDiffUsed) |
1059 | FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_qualtype, |
1060 | TDT.ToType)); |
1061 | |
1062 | |
1063 | FormatDiagnostic(SecondDollar + 1, Pipe, OutStr); |
1064 | break; |
1065 | } |
1066 | } |
1067 | |
1068 | |
1069 | |
1070 | |
1071 | if (Kind == DiagnosticsEngine::ak_qualtype_pair) |
1072 | continue; |
1073 | else if (Kind != DiagnosticsEngine::ak_std_string) |
1074 | FormattedArgs.push_back(std::make_pair(Kind, getRawArg(ArgNo))); |
1075 | else |
1076 | FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_c_string, |
1077 | (intptr_t)getArgStdStr(ArgNo).c_str())); |
1078 | } |
1079 | |
1080 | |
1081 | OutStr.append(Tree.begin(), Tree.end()); |
1082 | } |
1083 | |
1084 | StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, |
1085 | StringRef Message) |
1086 | : ID(ID), Level(Level), Message(Message) {} |
1087 | |
1088 | StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, |
1089 | const Diagnostic &Info) |
1090 | : ID(Info.getID()), Level(Level) { |
1091 | (0) . __assert_fail ("(Info.getLocation().isInvalid() || Info.hasSourceManager()) && \"Valid source location without setting a source manager for diagnostic\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 1092, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((Info.getLocation().isInvalid() || Info.hasSourceManager()) && |
1092 | (0) . __assert_fail ("(Info.getLocation().isInvalid() || Info.hasSourceManager()) && \"Valid source location without setting a source manager for diagnostic\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 1092, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Valid source location without setting a source manager for diagnostic"); |
1093 | if (Info.getLocation().isValid()) |
1094 | Loc = FullSourceLoc(Info.getLocation(), Info.getSourceManager()); |
1095 | SmallString<64> Message; |
1096 | Info.FormatDiagnostic(Message); |
1097 | this->Message.assign(Message.begin(), Message.end()); |
1098 | this->Ranges.assign(Info.getRanges().begin(), Info.getRanges().end()); |
1099 | this->FixIts.assign(Info.getFixItHints().begin(), Info.getFixItHints().end()); |
1100 | } |
1101 | |
1102 | StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, |
1103 | StringRef Message, FullSourceLoc Loc, |
1104 | ArrayRef<CharSourceRange> Ranges, |
1105 | ArrayRef<FixItHint> FixIts) |
1106 | : ID(ID), Level(Level), Loc(Loc), Message(Message), |
1107 | Ranges(Ranges.begin(), Ranges.end()), FixIts(FixIts.begin(), FixIts.end()) |
1108 | { |
1109 | } |
1110 | |
1111 | |
1112 | |
1113 | |
1114 | |
1115 | bool DiagnosticConsumer::IncludeInDiagnosticCounts() const { return true; } |
1116 | |
1117 | void IgnoringDiagConsumer::anchor() {} |
1118 | |
1119 | ForwardingDiagnosticConsumer::~ForwardingDiagnosticConsumer() = default; |
1120 | |
1121 | void ForwardingDiagnosticConsumer::HandleDiagnostic( |
1122 | DiagnosticsEngine::Level DiagLevel, |
1123 | const Diagnostic &Info) { |
1124 | Target.HandleDiagnostic(DiagLevel, Info); |
1125 | } |
1126 | |
1127 | void ForwardingDiagnosticConsumer::clear() { |
1128 | DiagnosticConsumer::clear(); |
1129 | Target.clear(); |
1130 | } |
1131 | |
1132 | bool ForwardingDiagnosticConsumer::IncludeInDiagnosticCounts() const { |
1133 | return Target.IncludeInDiagnosticCounts(); |
1134 | } |
1135 | |
1136 | PartialDiagnostic::StorageAllocator::StorageAllocator() { |
1137 | for (unsigned I = 0; I != NumCached; ++I) |
1138 | FreeList[I] = Cached + I; |
1139 | NumFreeListEntries = NumCached; |
1140 | } |
1141 | |
1142 | PartialDiagnostic::StorageAllocator::~StorageAllocator() { |
1143 | |
1144 | |
1145 | (0) . __assert_fail ("(NumFreeListEntries == NumCached || llvm..CrashRecoveryContext..isRecoveringFromCrash()) && \"A partial is on the lam\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 1147, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((NumFreeListEntries == NumCached || |
1146 | (0) . __assert_fail ("(NumFreeListEntries == NumCached || llvm..CrashRecoveryContext..isRecoveringFromCrash()) && \"A partial is on the lam\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 1147, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> llvm::CrashRecoveryContext::isRecoveringFromCrash()) && |
1147 | (0) . __assert_fail ("(NumFreeListEntries == NumCached || llvm..CrashRecoveryContext..isRecoveringFromCrash()) && \"A partial is on the lam\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Diagnostic.cpp", 1147, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "A partial is on the lam"); |
1148 | } |
1149 | |
1150 | char DiagnosticError::ID; |
1151 | |