1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | #include "clang/Basic/DiagnosticIDs.h" |
14 | #include "clang/Basic/AllDiagnostics.h" |
15 | #include "clang/Basic/DiagnosticCategories.h" |
16 | #include "clang/Basic/SourceManager.h" |
17 | #include "llvm/ADT/STLExtras.h" |
18 | #include "llvm/ADT/SmallVector.h" |
19 | #include "llvm/Support/ErrorHandling.h" |
20 | #include <map> |
21 | using namespace clang; |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | namespace { |
28 | |
29 | |
30 | enum { |
31 | CLASS_NOTE = 0x01, |
32 | = 0x02, |
33 | CLASS_WARNING = 0x03, |
34 | CLASS_EXTENSION = 0x04, |
35 | CLASS_ERROR = 0x05 |
36 | }; |
37 | |
38 | struct StaticDiagInfoRec { |
39 | uint16_t DiagID; |
40 | unsigned DefaultSeverity : 3; |
41 | unsigned Class : 3; |
42 | unsigned SFINAE : 2; |
43 | unsigned WarnNoWerror : 1; |
44 | unsigned : 1; |
45 | unsigned Category : 6; |
46 | |
47 | uint16_t OptionGroupIndex; |
48 | |
49 | uint16_t DescriptionLen; |
50 | const char *DescriptionStr; |
51 | |
52 | unsigned getOptionGroupIndex() const { |
53 | return OptionGroupIndex; |
54 | } |
55 | |
56 | StringRef getDescription() const { |
57 | return StringRef(DescriptionStr, DescriptionLen); |
58 | } |
59 | |
60 | diag::Flavor getFlavor() const { |
61 | return Class == CLASS_REMARK ? diag::Flavor::Remark |
62 | : diag::Flavor::WarningOrError; |
63 | } |
64 | |
65 | bool operator<(const StaticDiagInfoRec &RHS) const { |
66 | return DiagID < RHS.DiagID; |
67 | } |
68 | }; |
69 | |
70 | #define STRINGIFY_NAME(NAME) #NAME |
71 | #define VALIDATE_DIAG_SIZE(NAME) \ |
72 | static_assert( \ |
73 | static_cast<unsigned>(diag::NUM_BUILTIN_##NAME##_DIAGNOSTICS) < \ |
74 | static_cast<unsigned>(diag::DIAG_START_##NAME) + \ |
75 | static_cast<unsigned>(diag::DIAG_SIZE_##NAME), \ |
76 | STRINGIFY_NAME( \ |
77 | DIAG_SIZE_##NAME) " is insufficient to contain all " \ |
78 | "diagnostics, it may need to be made larger in " \ |
79 | "DiagnosticIDs.h."); |
80 | VALIDATE_DIAG_SIZE(COMMON) |
81 | VALIDATE_DIAG_SIZE(DRIVER) |
82 | VALIDATE_DIAG_SIZE(FRONTEND) |
83 | VALIDATE_DIAG_SIZE(SERIALIZATION) |
84 | VALIDATE_DIAG_SIZE(LEX) |
85 | VALIDATE_DIAG_SIZE(PARSE) |
86 | VALIDATE_DIAG_SIZE(AST) |
87 | VALIDATE_DIAG_SIZE(COMMENT) |
88 | VALIDATE_DIAG_SIZE(SEMA) |
89 | VALIDATE_DIAG_SIZE(ANALYSIS) |
90 | VALIDATE_DIAG_SIZE(REFACTORING) |
91 | #undef VALIDATE_DIAG_SIZE |
92 | #undef STRINGIFY_NAME |
93 | |
94 | } |
95 | |
96 | static const StaticDiagInfoRec StaticDiagInfo[] = { |
97 | #define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \ |
98 | SHOWINSYSHEADER, CATEGORY) \ |
99 | { \ |
100 | diag::ENUM, DEFAULT_SEVERITY, CLASS, DiagnosticIDs::SFINAE, NOWERROR, \ |
101 | SHOWINSYSHEADER, CATEGORY, GROUP, STR_SIZE(DESC, uint16_t), DESC \ |
102 | } \ |
103 | , |
104 | #include "clang/Basic/DiagnosticCommonKinds.inc" |
105 | #include "clang/Basic/DiagnosticDriverKinds.inc" |
106 | #include "clang/Basic/DiagnosticFrontendKinds.inc" |
107 | #include "clang/Basic/DiagnosticSerializationKinds.inc" |
108 | #include "clang/Basic/DiagnosticLexKinds.inc" |
109 | #include "clang/Basic/DiagnosticParseKinds.inc" |
110 | #include "clang/Basic/DiagnosticASTKinds.inc" |
111 | #include "clang/Basic/DiagnosticCommentKinds.inc" |
112 | #include "clang/Basic/DiagnosticCrossTUKinds.inc" |
113 | #include "clang/Basic/DiagnosticSemaKinds.inc" |
114 | #include "clang/Basic/DiagnosticAnalysisKinds.inc" |
115 | #include "clang/Basic/DiagnosticRefactoringKinds.inc" |
116 | #undef DIAG |
117 | }; |
118 | |
119 | static const unsigned StaticDiagInfoSize = llvm::array_lengthof(StaticDiagInfo); |
120 | |
121 | |
122 | |
123 | static const StaticDiagInfoRec *GetDiagInfo(unsigned DiagID) { |
124 | |
125 | using namespace diag; |
126 | if (DiagID >= DIAG_UPPER_LIMIT || DiagID <= DIAG_START_COMMON) |
127 | return nullptr; |
128 | |
129 | |
130 | |
131 | |
132 | |
133 | |
134 | |
135 | |
136 | |
137 | unsigned Offset = 0; |
138 | unsigned ID = DiagID - DIAG_START_COMMON - 1; |
139 | #define CATEGORY(NAME, PREV) \ |
140 | if (DiagID > DIAG_START_##NAME) { \ |
141 | Offset += NUM_BUILTIN_##PREV##_DIAGNOSTICS - DIAG_START_##PREV - 1; \ |
142 | ID -= DIAG_START_##NAME - DIAG_START_##PREV; \ |
143 | } |
144 | CATEGORY(DRIVER, COMMON) |
145 | CATEGORY(FRONTEND, DRIVER) |
146 | CATEGORY(SERIALIZATION, FRONTEND) |
147 | CATEGORY(LEX, SERIALIZATION) |
148 | CATEGORY(PARSE, LEX) |
149 | CATEGORY(AST, PARSE) |
150 | CATEGORY(COMMENT, AST) |
151 | CATEGORY(CROSSTU, COMMENT) |
152 | CATEGORY(SEMA, CROSSTU) |
153 | CATEGORY(ANALYSIS, SEMA) |
154 | CATEGORY(REFACTORING, ANALYSIS) |
155 | #undef CATEGORY |
156 | |
157 | |
158 | if (ID + Offset >= StaticDiagInfoSize) |
159 | return nullptr; |
160 | |
161 | assert(ID < StaticDiagInfoSize && Offset < StaticDiagInfoSize); |
162 | |
163 | const StaticDiagInfoRec *Found = &StaticDiagInfo[ID + Offset]; |
164 | |
165 | |
166 | |
167 | if (Found->DiagID != DiagID) |
168 | return nullptr; |
169 | return Found; |
170 | } |
171 | |
172 | static DiagnosticMapping GetDefaultDiagMapping(unsigned DiagID) { |
173 | DiagnosticMapping Info = DiagnosticMapping::Make( |
174 | diag::Severity::Fatal, , ); |
175 | |
176 | if (const StaticDiagInfoRec *StaticInfo = GetDiagInfo(DiagID)) { |
177 | Info.setSeverity((diag::Severity)StaticInfo->DefaultSeverity); |
178 | |
179 | if (StaticInfo->WarnNoWerror) { |
180 | (0) . __assert_fail ("Info.getSeverity() == diag..Severity..Warning && \"Unexpected mapping with no-Werror bit!\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/DiagnosticIDs.cpp", 181, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Info.getSeverity() == diag::Severity::Warning && |
181 | (0) . __assert_fail ("Info.getSeverity() == diag..Severity..Warning && \"Unexpected mapping with no-Werror bit!\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/DiagnosticIDs.cpp", 181, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Unexpected mapping with no-Werror bit!"); |
182 | Info.setNoWarningAsError(true); |
183 | } |
184 | } |
185 | |
186 | return Info; |
187 | } |
188 | |
189 | |
190 | |
191 | unsigned DiagnosticIDs::getCategoryNumberForDiag(unsigned DiagID) { |
192 | if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) |
193 | return Info->Category; |
194 | return 0; |
195 | } |
196 | |
197 | namespace { |
198 | |
199 | struct StaticDiagCategoryRec { |
200 | const char *NameStr; |
201 | uint8_t NameLen; |
202 | |
203 | StringRef getName() const { |
204 | return StringRef(NameStr, NameLen); |
205 | } |
206 | }; |
207 | } |
208 | |
209 | |
210 | |
211 | |
212 | DiagnosticMapping & |
213 | DiagnosticsEngine::DiagState::getOrAddMapping(diag::kind Diag) { |
214 | std::pair<iterator, bool> Result = |
215 | DiagMap.insert(std::make_pair(Diag, DiagnosticMapping())); |
216 | |
217 | |
218 | if (Result.second) |
219 | Result.first->second = GetDefaultDiagMapping(Diag); |
220 | |
221 | return Result.first->second; |
222 | } |
223 | |
224 | static const StaticDiagCategoryRec CategoryNameTable[] = { |
225 | #define GET_CATEGORY_TABLE |
226 | #define CATEGORY(X, ENUM) { X, STR_SIZE(X, uint8_t) }, |
227 | #include "clang/Basic/DiagnosticGroups.inc" |
228 | #undef GET_CATEGORY_TABLE |
229 | { nullptr, 0 } |
230 | }; |
231 | |
232 | |
233 | unsigned DiagnosticIDs::getNumberOfCategories() { |
234 | return llvm::array_lengthof(CategoryNameTable) - 1; |
235 | } |
236 | |
237 | |
238 | |
239 | |
240 | StringRef DiagnosticIDs::getCategoryNameFromID(unsigned CategoryID) { |
241 | if (CategoryID >= getNumberOfCategories()) |
242 | return StringRef(); |
243 | return CategoryNameTable[CategoryID].getName(); |
244 | } |
245 | |
246 | |
247 | |
248 | DiagnosticIDs::SFINAEResponse |
249 | DiagnosticIDs::getDiagnosticSFINAEResponse(unsigned DiagID) { |
250 | if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) |
251 | return static_cast<DiagnosticIDs::SFINAEResponse>(Info->SFINAE); |
252 | return SFINAE_Report; |
253 | } |
254 | |
255 | |
256 | |
257 | static unsigned getBuiltinDiagClass(unsigned DiagID) { |
258 | if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) |
259 | return Info->Class; |
260 | return ~0U; |
261 | } |
262 | |
263 | |
264 | |
265 | |
266 | |
267 | namespace clang { |
268 | namespace diag { |
269 | class CustomDiagInfo { |
270 | typedef std::pair<DiagnosticIDs::Level, std::string> DiagDesc; |
271 | std::vector<DiagDesc> DiagInfo; |
272 | std::map<DiagDesc, unsigned> DiagIDs; |
273 | public: |
274 | |
275 | |
276 | |
277 | StringRef getDescription(unsigned DiagID) const { |
278 | (0) . __assert_fail ("DiagID - DIAG_UPPER_LIMIT < DiagInfo.size() && \"Invalid diagnostic ID\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/DiagnosticIDs.cpp", 279, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(DiagID - DIAG_UPPER_LIMIT < DiagInfo.size() && |
279 | (0) . __assert_fail ("DiagID - DIAG_UPPER_LIMIT < DiagInfo.size() && \"Invalid diagnostic ID\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/DiagnosticIDs.cpp", 279, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Invalid diagnostic ID"); |
280 | return DiagInfo[DiagID-DIAG_UPPER_LIMIT].second; |
281 | } |
282 | |
283 | |
284 | DiagnosticIDs::Level getLevel(unsigned DiagID) const { |
285 | (0) . __assert_fail ("DiagID - DIAG_UPPER_LIMIT < DiagInfo.size() && \"Invalid diagnostic ID\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/DiagnosticIDs.cpp", 286, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(DiagID - DIAG_UPPER_LIMIT < DiagInfo.size() && |
286 | (0) . __assert_fail ("DiagID - DIAG_UPPER_LIMIT < DiagInfo.size() && \"Invalid diagnostic ID\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/DiagnosticIDs.cpp", 286, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Invalid diagnostic ID"); |
287 | return DiagInfo[DiagID-DIAG_UPPER_LIMIT].first; |
288 | } |
289 | |
290 | unsigned getOrCreateDiagID(DiagnosticIDs::Level L, StringRef Message, |
291 | DiagnosticIDs &Diags) { |
292 | DiagDesc D(L, Message); |
293 | |
294 | std::map<DiagDesc, unsigned>::iterator I = DiagIDs.lower_bound(D); |
295 | if (I != DiagIDs.end() && I->first == D) |
296 | return I->second; |
297 | |
298 | |
299 | unsigned ID = DiagInfo.size()+DIAG_UPPER_LIMIT; |
300 | DiagIDs.insert(std::make_pair(D, ID)); |
301 | DiagInfo.push_back(D); |
302 | return ID; |
303 | } |
304 | }; |
305 | |
306 | } |
307 | } |
308 | |
309 | |
310 | |
311 | |
312 | |
313 | |
314 | DiagnosticIDs::DiagnosticIDs() { CustomDiagInfo = nullptr; } |
315 | |
316 | DiagnosticIDs::~DiagnosticIDs() { |
317 | delete CustomDiagInfo; |
318 | } |
319 | |
320 | |
321 | |
322 | |
323 | |
324 | |
325 | |
326 | unsigned DiagnosticIDs::getCustomDiagID(Level L, StringRef FormatString) { |
327 | if (!CustomDiagInfo) |
328 | CustomDiagInfo = new diag::CustomDiagInfo(); |
329 | return CustomDiagInfo->getOrCreateDiagID(L, FormatString, *this); |
330 | } |
331 | |
332 | |
333 | |
334 | |
335 | |
336 | |
337 | bool DiagnosticIDs::isBuiltinWarningOrExtension(unsigned DiagID) { |
338 | return DiagID < diag::DIAG_UPPER_LIMIT && |
339 | getBuiltinDiagClass(DiagID) != CLASS_ERROR; |
340 | } |
341 | |
342 | |
343 | |
344 | bool DiagnosticIDs::isBuiltinNote(unsigned DiagID) { |
345 | return DiagID < diag::DIAG_UPPER_LIMIT && |
346 | getBuiltinDiagClass(DiagID) == CLASS_NOTE; |
347 | } |
348 | |
349 | |
350 | |
351 | |
352 | |
353 | |
354 | bool DiagnosticIDs::isBuiltinExtensionDiag(unsigned DiagID, |
355 | bool &EnabledByDefault) { |
356 | if (DiagID >= diag::DIAG_UPPER_LIMIT || |
357 | getBuiltinDiagClass(DiagID) != CLASS_EXTENSION) |
358 | return false; |
359 | |
360 | EnabledByDefault = |
361 | GetDefaultDiagMapping(DiagID).getSeverity() != diag::Severity::Ignored; |
362 | return true; |
363 | } |
364 | |
365 | bool DiagnosticIDs::isDefaultMappingAsError(unsigned DiagID) { |
366 | if (DiagID >= diag::DIAG_UPPER_LIMIT) |
367 | return false; |
368 | |
369 | return GetDefaultDiagMapping(DiagID).getSeverity() >= diag::Severity::Error; |
370 | } |
371 | |
372 | |
373 | |
374 | StringRef DiagnosticIDs::getDescription(unsigned DiagID) const { |
375 | if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) |
376 | return Info->getDescription(); |
377 | (0) . __assert_fail ("CustomDiagInfo && \"Invalid CustomDiagInfo\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/DiagnosticIDs.cpp", 377, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(CustomDiagInfo && "Invalid CustomDiagInfo"); |
378 | return CustomDiagInfo->getDescription(DiagID); |
379 | } |
380 | |
381 | static DiagnosticIDs::Level toLevel(diag::Severity SV) { |
382 | switch (SV) { |
383 | case diag::Severity::Ignored: |
384 | return DiagnosticIDs::Ignored; |
385 | case diag::Severity::Remark: |
386 | return DiagnosticIDs::Remark; |
387 | case diag::Severity::Warning: |
388 | return DiagnosticIDs::Warning; |
389 | case diag::Severity::Error: |
390 | return DiagnosticIDs::Error; |
391 | case diag::Severity::Fatal: |
392 | return DiagnosticIDs::Fatal; |
393 | } |
394 | llvm_unreachable("unexpected severity"); |
395 | } |
396 | |
397 | |
398 | |
399 | |
400 | DiagnosticIDs::Level |
401 | DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, SourceLocation Loc, |
402 | const DiagnosticsEngine &Diag) const { |
403 | |
404 | if (DiagID >= diag::DIAG_UPPER_LIMIT) { |
405 | (0) . __assert_fail ("CustomDiagInfo && \"Invalid CustomDiagInfo\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/DiagnosticIDs.cpp", 405, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(CustomDiagInfo && "Invalid CustomDiagInfo"); |
406 | return CustomDiagInfo->getLevel(DiagID); |
407 | } |
408 | |
409 | unsigned DiagClass = getBuiltinDiagClass(DiagID); |
410 | if (DiagClass == CLASS_NOTE) return DiagnosticIDs::Note; |
411 | return toLevel(getDiagnosticSeverity(DiagID, Loc, Diag)); |
412 | } |
413 | |
414 | |
415 | |
416 | |
417 | |
418 | |
419 | |
420 | diag::Severity |
421 | DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc, |
422 | const DiagnosticsEngine &Diag) const { |
423 | assert(getBuiltinDiagClass(DiagID) != CLASS_NOTE); |
424 | |
425 | |
426 | |
427 | diag::Severity Result = diag::Severity::Fatal; |
428 | |
429 | |
430 | DiagnosticsEngine::DiagState *State = Diag.GetDiagStateForLoc(Loc); |
431 | DiagnosticMapping &Mapping = State->getOrAddMapping((diag::kind)DiagID); |
432 | |
433 | |
434 | if (Mapping.getSeverity() != diag::Severity()) |
435 | Result = Mapping.getSeverity(); |
436 | |
437 | |
438 | if (State->EnableAllWarnings && Result == diag::Severity::Ignored && |
439 | !Mapping.isUser() && getBuiltinDiagClass(DiagID) != CLASS_REMARK) |
440 | Result = diag::Severity::Warning; |
441 | |
442 | |
443 | |
444 | |
445 | bool EnabledByDefault = false; |
446 | bool IsExtensionDiag = isBuiltinExtensionDiag(DiagID, EnabledByDefault); |
447 | if (Diag.AllExtensionsSilenced && IsExtensionDiag && !EnabledByDefault) |
448 | return diag::Severity::Ignored; |
449 | |
450 | |
451 | |
452 | if (IsExtensionDiag && !Mapping.isUser()) |
453 | Result = std::max(Result, State->ExtBehavior); |
454 | |
455 | |
456 | if (Result == diag::Severity::Ignored) |
457 | return Result; |
458 | |
459 | |
460 | |
461 | |
462 | |
463 | |
464 | if (State->IgnoreAllWarnings) { |
465 | if (Result == diag::Severity::Warning || |
466 | (Result >= diag::Severity::Error && |
467 | !isDefaultMappingAsError((diag::kind)DiagID))) |
468 | return diag::Severity::Ignored; |
469 | } |
470 | |
471 | |
472 | if (Result == diag::Severity::Warning) { |
473 | if (State->WarningsAsErrors && !Mapping.hasNoWarningAsError()) |
474 | Result = diag::Severity::Error; |
475 | } |
476 | |
477 | |
478 | |
479 | if (Result == diag::Severity::Error) { |
480 | if (State->ErrorsAsFatal && !Mapping.hasNoErrorAsFatal()) |
481 | Result = diag::Severity::Fatal; |
482 | } |
483 | |
484 | |
485 | if (Result == diag::Severity::Fatal && |
486 | Diag.CurDiagID != diag::fatal_too_many_errors && Diag.FatalsAsError) |
487 | Result = diag::Severity::Error; |
488 | |
489 | |
490 | bool = |
491 | !GetDiagInfo(DiagID) || GetDiagInfo(DiagID)->WarnShowInSystemHeader; |
492 | |
493 | |
494 | |
495 | |
496 | if (State->SuppressSystemWarnings && !ShowInSystemHeader && Loc.isValid() && |
497 | Diag.getSourceManager().isInSystemHeader( |
498 | Diag.getSourceManager().getExpansionLoc(Loc))) |
499 | return diag::Severity::Ignored; |
500 | |
501 | return Result; |
502 | } |
503 | |
504 | #define GET_DIAG_ARRAYS |
505 | #include "clang/Basic/DiagnosticGroups.inc" |
506 | #undef GET_DIAG_ARRAYS |
507 | |
508 | namespace { |
509 | struct WarningOption { |
510 | uint16_t NameOffset; |
511 | uint16_t Members; |
512 | uint16_t SubGroups; |
513 | |
514 | |
515 | StringRef getName() const { |
516 | return StringRef(DiagGroupNames + NameOffset + 1, |
517 | DiagGroupNames[NameOffset]); |
518 | } |
519 | }; |
520 | } |
521 | |
522 | |
523 | static const WarningOption OptionTable[] = { |
524 | #define GET_DIAG_TABLE |
525 | #include "clang/Basic/DiagnosticGroups.inc" |
526 | #undef GET_DIAG_TABLE |
527 | }; |
528 | |
529 | |
530 | |
531 | |
532 | StringRef DiagnosticIDs::getWarningOptionForDiag(unsigned DiagID) { |
533 | if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) |
534 | return OptionTable[Info->getOptionGroupIndex()].getName(); |
535 | return StringRef(); |
536 | } |
537 | |
538 | std::vector<std::string> DiagnosticIDs::getDiagnosticFlags() { |
539 | std::vector<std::string> Res; |
540 | for (size_t I = 1; DiagGroupNames[I] != '\0';) { |
541 | std::string Diag(DiagGroupNames + I + 1, DiagGroupNames[I]); |
542 | I += DiagGroupNames[I] + 1; |
543 | Res.push_back("-W" + Diag); |
544 | Res.push_back("-Wno-" + Diag); |
545 | } |
546 | |
547 | return Res; |
548 | } |
549 | |
550 | |
551 | |
552 | static bool getDiagnosticsInGroup(diag::Flavor Flavor, |
553 | const WarningOption *Group, |
554 | SmallVectorImpl<diag::kind> &Diags) { |
555 | |
556 | |
557 | if (!Group->Members && !Group->SubGroups) |
558 | return Flavor == diag::Flavor::Remark; |
559 | |
560 | bool NotFound = true; |
561 | |
562 | |
563 | const int16_t *Member = DiagArrays + Group->Members; |
564 | for (; *Member != -1; ++Member) { |
565 | if (GetDiagInfo(*Member)->getFlavor() == Flavor) { |
566 | NotFound = false; |
567 | Diags.push_back(*Member); |
568 | } |
569 | } |
570 | |
571 | |
572 | const int16_t *SubGroups = DiagSubGroups + Group->SubGroups; |
573 | for (; *SubGroups != (int16_t)-1; ++SubGroups) |
574 | NotFound &= getDiagnosticsInGroup(Flavor, &OptionTable[(short)*SubGroups], |
575 | Diags); |
576 | |
577 | return NotFound; |
578 | } |
579 | |
580 | bool |
581 | DiagnosticIDs::getDiagnosticsInGroup(diag::Flavor Flavor, StringRef Group, |
582 | SmallVectorImpl<diag::kind> &Diags) const { |
583 | auto Found = std::lower_bound(std::begin(OptionTable), std::end(OptionTable), |
584 | Group, |
585 | [](const WarningOption &LHS, StringRef RHS) { |
586 | return LHS.getName() < RHS; |
587 | }); |
588 | if (Found == std::end(OptionTable) || Found->getName() != Group) |
589 | return true; |
590 | |
591 | return ::getDiagnosticsInGroup(Flavor, Found, Diags); |
592 | } |
593 | |
594 | void DiagnosticIDs::getAllDiagnostics(diag::Flavor Flavor, |
595 | std::vector<diag::kind> &Diags) { |
596 | for (unsigned i = 0; i != StaticDiagInfoSize; ++i) |
597 | if (StaticDiagInfo[i].getFlavor() == Flavor) |
598 | Diags.push_back(StaticDiagInfo[i].DiagID); |
599 | } |
600 | |
601 | StringRef DiagnosticIDs::getNearestOption(diag::Flavor Flavor, |
602 | StringRef Group) { |
603 | StringRef Best; |
604 | unsigned BestDistance = Group.size() + 1; |
605 | for (const WarningOption &O : OptionTable) { |
606 | |
607 | if (!O.Members && !O.SubGroups) |
608 | continue; |
609 | |
610 | unsigned Distance = O.getName().edit_distance(Group, true, BestDistance); |
611 | if (Distance > BestDistance) |
612 | continue; |
613 | |
614 | |
615 | llvm::SmallVector<diag::kind, 8> Diags; |
616 | if (::getDiagnosticsInGroup(Flavor, &O, Diags) || Diags.empty()) |
617 | continue; |
618 | |
619 | if (Distance == BestDistance) { |
620 | |
621 | Best = ""; |
622 | } else if (Distance < BestDistance) { |
623 | |
624 | Best = O.getName(); |
625 | BestDistance = Distance; |
626 | } |
627 | } |
628 | |
629 | return Best; |
630 | } |
631 | |
632 | |
633 | |
634 | bool DiagnosticIDs::ProcessDiag(DiagnosticsEngine &Diag) const { |
635 | Diagnostic Info(&Diag); |
636 | |
637 | (0) . __assert_fail ("Diag.getClient() && \"DiagnosticClient not set!\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/DiagnosticIDs.cpp", 637, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Diag.getClient() && "DiagnosticClient not set!"); |
638 | |
639 | |
640 | unsigned DiagID = Info.getID(); |
641 | DiagnosticIDs::Level DiagLevel |
642 | = getDiagnosticLevel(DiagID, Info.getLocation(), Diag); |
643 | |
644 | |
645 | |
646 | if (DiagLevel >= DiagnosticIDs::Error) { |
647 | ++Diag.TrapNumErrorsOccurred; |
648 | if (isUnrecoverable(DiagID)) |
649 | ++Diag.TrapNumUnrecoverableErrorsOccurred; |
650 | } |
651 | |
652 | if (Diag.SuppressAllDiagnostics) |
653 | return false; |
654 | |
655 | if (DiagLevel != DiagnosticIDs::Note) { |
656 | |
657 | |
658 | |
659 | |
660 | if (Diag.LastDiagLevel == DiagnosticIDs::Fatal) |
661 | Diag.FatalErrorOccurred = true; |
662 | |
663 | Diag.LastDiagLevel = DiagLevel; |
664 | } |
665 | |
666 | |
667 | |
668 | if (Diag.FatalErrorOccurred) { |
669 | if (DiagLevel >= DiagnosticIDs::Error && |
670 | Diag.Client->IncludeInDiagnosticCounts()) { |
671 | ++Diag.NumErrors; |
672 | } |
673 | |
674 | return false; |
675 | } |
676 | |
677 | |
678 | |
679 | if (DiagLevel == DiagnosticIDs::Ignored || |
680 | (DiagLevel == DiagnosticIDs::Note && |
681 | Diag.LastDiagLevel == DiagnosticIDs::Ignored)) |
682 | return false; |
683 | |
684 | if (DiagLevel >= DiagnosticIDs::Error) { |
685 | if (isUnrecoverable(DiagID)) |
686 | Diag.UnrecoverableErrorOccurred = true; |
687 | |
688 | |
689 | if (isDefaultMappingAsError(DiagID)) |
690 | Diag.UncompilableErrorOccurred = true; |
691 | |
692 | Diag.ErrorOccurred = true; |
693 | if (Diag.Client->IncludeInDiagnosticCounts()) { |
694 | ++Diag.NumErrors; |
695 | } |
696 | |
697 | |
698 | |
699 | if (Diag.ErrorLimit && Diag.NumErrors > Diag.ErrorLimit && |
700 | DiagLevel == DiagnosticIDs::Error) { |
701 | Diag.SetDelayedDiagnostic(diag::fatal_too_many_errors); |
702 | return false; |
703 | } |
704 | } |
705 | |
706 | |
707 | |
708 | if (Diag.CurDiagID == diag::fatal_too_many_errors) |
709 | Diag.FatalErrorOccurred = true; |
710 | |
711 | EmitDiag(Diag, DiagLevel); |
712 | return true; |
713 | } |
714 | |
715 | void DiagnosticIDs::EmitDiag(DiagnosticsEngine &Diag, Level DiagLevel) const { |
716 | Diagnostic Info(&Diag); |
717 | (0) . __assert_fail ("DiagLevel != DiagnosticIDs..Ignored && \"Cannot emit ignored diagnostics!\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/DiagnosticIDs.cpp", 717, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(DiagLevel != DiagnosticIDs::Ignored && "Cannot emit ignored diagnostics!"); |
718 | |
719 | Diag.Client->HandleDiagnostic((DiagnosticsEngine::Level)DiagLevel, Info); |
720 | if (Diag.Client->IncludeInDiagnosticCounts()) { |
721 | if (DiagLevel == DiagnosticIDs::Warning) |
722 | ++Diag.NumWarnings; |
723 | } |
724 | |
725 | Diag.CurDiagID = ~0U; |
726 | } |
727 | |
728 | bool DiagnosticIDs::isUnrecoverable(unsigned DiagID) const { |
729 | if (DiagID >= diag::DIAG_UPPER_LIMIT) { |
730 | (0) . __assert_fail ("CustomDiagInfo && \"Invalid CustomDiagInfo\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/DiagnosticIDs.cpp", 730, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(CustomDiagInfo && "Invalid CustomDiagInfo"); |
731 | |
732 | return CustomDiagInfo->getLevel(DiagID) >= DiagnosticIDs::Error; |
733 | } |
734 | |
735 | |
736 | if (getBuiltinDiagClass(DiagID) < CLASS_ERROR) |
737 | return false; |
738 | |
739 | if (DiagID == diag::err_unavailable || |
740 | DiagID == diag::err_unavailable_message) |
741 | return false; |
742 | |
743 | |
744 | if (isARCDiagnostic(DiagID)) |
745 | return false; |
746 | |
747 | return true; |
748 | } |
749 | |
750 | bool DiagnosticIDs::isARCDiagnostic(unsigned DiagID) { |
751 | unsigned cat = getCategoryNumberForDiag(DiagID); |
752 | return DiagnosticIDs::getCategoryNameFromID(cat).startswith("ARC "); |
753 | } |
754 | |