17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/Support/ErrorHandling.h"
21 using namespace clang;
29 struct StaticDiagInfoRec;
34 struct StaticDiagInfoDescriptionStringTable {
35 #define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \
36 SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
37 char ENUM##_desc[sizeof(DESC)];
39 #include "clang/Basic/DiagnosticCommonKinds.inc"
40 #include "clang/Basic/DiagnosticDriverKinds.inc"
41 #include "clang/Basic/DiagnosticFrontendKinds.inc"
42 #include "clang/Basic/DiagnosticSerializationKinds.inc"
43 #include "clang/Basic/DiagnosticLexKinds.inc"
44 #include "clang/Basic/DiagnosticParseKinds.inc"
45 #include "clang/Basic/DiagnosticASTKinds.inc"
46 #include "clang/Basic/DiagnosticCommentKinds.inc"
47 #include "clang/Basic/DiagnosticCrossTUKinds.inc"
48 #include "clang/Basic/DiagnosticSemaKinds.inc"
49 #include "clang/Basic/DiagnosticAnalysisKinds.inc"
50 #include "clang/Basic/DiagnosticRefactoringKinds.inc"
55 const StaticDiagInfoDescriptionStringTable StaticDiagInfoDescriptions = {
56 #define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \
57 SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
60 #include "clang/Basic/DiagnosticCommonKinds.inc"
61 #include "clang/Basic/DiagnosticDriverKinds.inc"
62 #include "clang/Basic/DiagnosticFrontendKinds.inc"
63 #include "clang/Basic/DiagnosticSerializationKinds.inc"
64 #include "clang/Basic/DiagnosticLexKinds.inc"
65 #include "clang/Basic/DiagnosticParseKinds.inc"
66 #include "clang/Basic/DiagnosticASTKinds.inc"
67 #include "clang/Basic/DiagnosticCommentKinds.inc"
68 #include "clang/Basic/DiagnosticCrossTUKinds.inc"
69 #include "clang/Basic/DiagnosticSemaKinds.inc"
70 #include "clang/Basic/DiagnosticAnalysisKinds.inc"
71 #include "clang/Basic/DiagnosticRefactoringKinds.inc"
76 extern const StaticDiagInfoRec StaticDiagInfo[];
80 const uint32_t StaticDiagInfoDescriptionOffsets[] = {
81 #define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \
82 SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
83 offsetof(StaticDiagInfoDescriptionStringTable, ENUM##_desc),
85 #include "clang/Basic/DiagnosticCommonKinds.inc"
86 #include "clang/Basic/DiagnosticDriverKinds.inc"
87 #include "clang/Basic/DiagnosticFrontendKinds.inc"
88 #include "clang/Basic/DiagnosticSerializationKinds.inc"
89 #include "clang/Basic/DiagnosticLexKinds.inc"
90 #include "clang/Basic/DiagnosticParseKinds.inc"
91 #include "clang/Basic/DiagnosticASTKinds.inc"
92 #include "clang/Basic/DiagnosticCommentKinds.inc"
93 #include "clang/Basic/DiagnosticCrossTUKinds.inc"
94 #include "clang/Basic/DiagnosticSemaKinds.inc"
95 #include "clang/Basic/DiagnosticAnalysisKinds.inc"
96 #include "clang/Basic/DiagnosticRefactoringKinds.inc"
105 CLASS_WARNING = 0x03,
106 CLASS_EXTENSION = 0x04,
110 struct StaticDiagInfoRec {
112 uint8_t DefaultSeverity : 3;
116 uint8_t WarnNoWerror : 1;
117 uint8_t WarnShowInSystemHeader : 1;
118 uint8_t WarnShowInSystemMacro : 1;
120 uint16_t OptionGroupIndex : 15;
121 uint16_t Deferrable : 1;
123 uint16_t DescriptionLen;
125 unsigned getOptionGroupIndex()
const {
126 return OptionGroupIndex;
129 StringRef getDescription()
const {
130 size_t MyIndex =
this - &StaticDiagInfo[0];
131 uint32_t StringOffset = StaticDiagInfoDescriptionOffsets[MyIndex];
132 const char* Table =
reinterpret_cast<const char*
>(&StaticDiagInfoDescriptions);
133 return StringRef(&Table[StringOffset], DescriptionLen);
141 bool operator<(
const StaticDiagInfoRec &RHS)
const {
142 return DiagID < RHS.DiagID;
146 #define STRINGIFY_NAME(NAME) #NAME
147 #define VALIDATE_DIAG_SIZE(NAME) \
149 static_cast<unsigned>(diag::NUM_BUILTIN_##NAME##_DIAGNOSTICS) < \
150 static_cast<unsigned>(diag::DIAG_START_##NAME) + \
151 static_cast<unsigned>(diag::DIAG_SIZE_##NAME), \
153 DIAG_SIZE_##NAME) " is insufficient to contain all " \
154 "diagnostics, it may need to be made larger in " \
168 #undef VALIDATE_DIAG_SIZE
169 #undef STRINGIFY_NAME
171 const StaticDiagInfoRec StaticDiagInfo[] = {
173 #define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \
174 SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
179 DiagnosticIDs::SFINAE, \
186 STR_SIZE(DESC, uint16_t)},
187 #include "clang/Basic/DiagnosticCommonKinds.inc"
188 #include "clang/Basic/DiagnosticDriverKinds.inc"
189 #include "clang/Basic/DiagnosticFrontendKinds.inc"
190 #include "clang/Basic/DiagnosticSerializationKinds.inc"
191 #include "clang/Basic/DiagnosticLexKinds.inc"
192 #include "clang/Basic/DiagnosticParseKinds.inc"
193 #include "clang/Basic/DiagnosticASTKinds.inc"
194 #include "clang/Basic/DiagnosticCommentKinds.inc"
195 #include "clang/Basic/DiagnosticCrossTUKinds.inc"
196 #include "clang/Basic/DiagnosticSemaKinds.inc"
197 #include "clang/Basic/DiagnosticAnalysisKinds.inc"
198 #include "clang/Basic/DiagnosticRefactoringKinds.inc"
211 using namespace diag;
225 #define CATEGORY(NAME, PREV) \
226 if (DiagID > DIAG_START_##NAME) { \
227 Offset += NUM_BUILTIN_##PREV##_DIAGNOSTICS - DIAG_START_##PREV - 1; \
228 ID -= DIAG_START_##NAME - DIAG_START_##PREV; \
249 const StaticDiagInfoRec *Found = &StaticDiagInfo[
ID +
Offset];
253 if (Found->DiagID != DiagID)
262 if (
const StaticDiagInfoRec *StaticInfo =
GetDiagInfo(DiagID)) {
265 if (StaticInfo->WarnNoWerror) {
267 "Unexpected mapping with no-Werror bit!");
278 if (
const StaticDiagInfoRec *Info =
GetDiagInfo(DiagID))
279 return Info->Category;
285 struct StaticDiagCategoryRec {
290 return StringRef(NameStr, NameLen);
300 std::pair<iterator, bool> Result =
307 return Result.first->second;
311 #define GET_CATEGORY_TABLE
312 #define CATEGORY(X, ENUM) { X, STR_SIZE(X, uint8_t) },
313 #include "clang/Basic/DiagnosticGroups.inc"
314 #undef GET_CATEGORY_TABLE
336 if (
const StaticDiagInfoRec *Info =
GetDiagInfo(DiagID))
342 if (
const StaticDiagInfoRec *Info =
GetDiagInfo(DiagID))
343 return Info->Deferrable;
350 if (
const StaticDiagInfoRec *Info =
GetDiagInfo(DiagID))
362 typedef std::pair<DiagnosticIDs::Level, std::string> DiagDesc;
363 std::vector<DiagDesc> DiagInfo;
364 std::map<DiagDesc, unsigned> DiagIDs;
371 "Invalid diagnostic ID");
378 "Invalid diagnostic ID");
386 std::map<DiagDesc, unsigned>::iterator I = DiagIDs.lower_bound(D);
387 if (I != DiagIDs.end() && I->first == D)
392 DiagIDs.insert(std::make_pair(D,
ID));
393 DiagInfo.push_back(D);
419 return CustomDiagInfo->getOrCreateDiagID(L, FormatString, *
this);
445 bool &EnabledByDefault) {
465 if (
const StaticDiagInfoRec *Info =
GetDiagInfo(DiagID))
466 return Info->getDescription();
467 assert(CustomDiagInfo &&
"Invalid CustomDiagInfo");
468 return CustomDiagInfo->getDescription(DiagID);
484 llvm_unreachable(
"unexpected severity");
491 DiagnosticIDs::getDiagnosticLevel(
unsigned DiagID,
SourceLocation Loc,
495 assert(CustomDiagInfo &&
"Invalid CustomDiagInfo");
496 return CustomDiagInfo->getLevel(DiagID);
501 return toLevel(getDiagnosticSeverity(DiagID, Loc,
Diag));
511 DiagnosticIDs::getDiagnosticSeverity(
unsigned DiagID,
SourceLocation Loc,
520 DiagnosticsEngine::DiagState *
State =
Diag.GetDiagStateForLoc(Loc);
535 bool EnabledByDefault =
false;
537 if (
Diag.AllExtensionsSilenced && IsExtensionDiag && !EnabledByDefault)
542 if (IsExtensionDiag && !Mapping.
isUser())
554 if (
State->IgnoreAllWarnings) {
576 Diag.CurDiagID != diag::fatal_too_many_errors &&
Diag.FatalsAsError)
580 bool ShowInSystemHeader =
586 if (
State->SuppressSystemWarnings && !ShowInSystemHeader && Loc.
isValid() &&
587 Diag.getSourceManager().isInSystemHeader(
588 Diag.getSourceManager().getExpansionLoc(Loc)))
592 bool ShowInSystemMacro =
594 if (
State->SuppressSystemWarnings && !ShowInSystemMacro && Loc.
isValid() &&
595 Diag.getSourceManager().isInSystemMacro(Loc))
601 #define GET_DIAG_ARRAYS
602 #include "clang/Basic/DiagnosticGroups.inc"
603 #undef GET_DIAG_ARRAYS
606 struct WarningOption {
613 return StringRef(DiagGroupNames + NameOffset + 1,
614 DiagGroupNames[NameOffset]);
621 #define DIAG_ENTRY(GroupName, FlagNameOffset, Members, SubGroups) \
622 {FlagNameOffset, Members, SubGroups},
623 #include "clang/Basic/DiagnosticGroups.inc"
633 const auto *Found = llvm::partition_point(
634 OptionTable, [=](
const WarningOption &O) {
return O.getName() < Name; });
635 if (Found == std::end(
OptionTable) || Found->getName() != Name)
641 if (
const StaticDiagInfoRec *Info =
GetDiagInfo(DiagID))
642 return static_cast<diag::Group>(Info->getOptionGroupIndex());
656 std::vector<std::string> Res;
657 for (
size_t I = 1; DiagGroupNames[I] !=
'\0';) {
659 I += DiagGroupNames[I] + 1;
660 Res.push_back(
"-W" +
Diag);
661 Res.push_back(
"-Wno-" +
Diag);
670 const WarningOption *
Group,
677 bool NotFound =
true;
680 const int16_t *
Member = DiagArrays +
Group->Members;
689 const int16_t *SubGroups = DiagSubGroups +
Group->SubGroups;
690 for (; *SubGroups != (int16_t)-1; ++SubGroups)
707 std::vector<diag::kind> &Diags) {
709 if (StaticDiagInfo[i].getFlavor() ==
Flavor)
710 Diags.push_back(StaticDiagInfo[i].DiagID);
716 unsigned BestDistance =
Group.size() + 1;
719 if (!O.Members && !O.SubGroups)
722 unsigned Distance = O.getName().edit_distance(
Group,
true, BestDistance);
723 if (Distance > BestDistance)
731 if (Distance == BestDistance) {
734 }
else if (Distance < BestDistance) {
737 BestDistance = Distance;
749 assert(
Diag.getClient() &&
"DiagnosticClient not set!");
752 unsigned DiagID = Info.getID();
754 = getDiagnosticLevel(DiagID, Info.getLocation(),
Diag);
759 ++
Diag.TrapNumErrorsOccurred;
760 if (isUnrecoverable(DiagID))
761 ++
Diag.TrapNumUnrecoverableErrorsOccurred;
764 if (
Diag.SuppressAllDiagnostics)
773 Diag.FatalErrorOccurred =
true;
775 Diag.LastDiagLevel = DiagLevel;
780 if (
Diag.FatalErrorOccurred) {
782 Diag.Client->IncludeInDiagnosticCounts()) {
797 if (isUnrecoverable(DiagID))
798 Diag.UnrecoverableErrorOccurred =
true;
802 Diag.UncompilableErrorOccurred =
true;
804 Diag.ErrorOccurred =
true;
805 if (
Diag.Client->IncludeInDiagnosticCounts()) {
811 if (
Diag.ErrorLimit &&
Diag.NumErrors >
Diag.ErrorLimit &&
813 Diag.SetDelayedDiagnostic(diag::fatal_too_many_errors);
820 if (
Diag.CurDiagID == diag::fatal_too_many_errors)
821 Diag.FatalErrorOccurred =
true;
823 EmitDiag(
Diag, DiagLevel);
832 if (
Diag.Client->IncludeInDiagnosticCounts()) {
837 Diag.CurDiagID = ~0
U;
840 bool DiagnosticIDs::isUnrecoverable(
unsigned DiagID)
const {
842 assert(CustomDiagInfo &&
"Invalid CustomDiagInfo");
851 if (DiagID == diag::err_unavailable ||
852 DiagID == diag::err_unavailable_message)