17#include "llvm/ADT/STLExtras.h"
18#include "llvm/ADT/SmallVector.h"
19#include "llvm/ADT/StringTable.h"
20#include "llvm/Support/ErrorHandling.h"
21#include "llvm/Support/Path.h"
32struct StaticDiagInfoRec;
37struct StaticDiagInfoDescriptionStringTable {
38#define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \
39 SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
40 char ENUM##_desc[sizeof(DESC)];
45const StaticDiagInfoDescriptionStringTable StaticDiagInfoDescriptions = {
46#define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \
47 SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
53extern const StaticDiagInfoRec StaticDiagInfo[];
57const uint32_t StaticDiagInfoDescriptionOffsets[] = {
58#define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \
59 SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
60 offsetof(StaticDiagInfoDescriptionStringTable, ENUM##_desc),
70 CLASS_EXTENSION = 0x04,
74struct StaticDiagInfoRec {
77 uint8_t DefaultSeverity : 3;
78 LLVM_PREFERRED_TYPE(DiagnosticClass)
83 LLVM_PREFERRED_TYPE(
bool)
84 uint8_t WarnNoWerror : 1;
85 LLVM_PREFERRED_TYPE(
bool)
86 uint8_t WarnShowInSystemHeader : 1;
87 LLVM_PREFERRED_TYPE(
bool)
88 uint8_t WarnShowInSystemMacro : 1;
90 uint16_t OptionGroupIndex : 15;
91 LLVM_PREFERRED_TYPE(
bool)
92 uint16_t Deferrable : 1;
94 uint16_t DescriptionLen;
96 unsigned getOptionGroupIndex()
const {
97 return OptionGroupIndex;
100 StringRef getDescription()
const {
101 size_t MyIndex =
this - &StaticDiagInfo[0];
102 uint32_t StringOffset = StaticDiagInfoDescriptionOffsets[MyIndex];
103 const char* Table =
reinterpret_cast<const char*
>(&StaticDiagInfoDescriptions);
104 return StringRef(&Table[StringOffset], DescriptionLen);
108 return Class == CLASS_REMARK ? diag::Flavor::Remark
109 : diag::Flavor::WarningOrError;
112 bool operator<(
const StaticDiagInfoRec &RHS)
const {
113 return DiagID < RHS.DiagID;
117#define STRINGIFY_NAME(NAME) #NAME
118#define VALIDATE_DIAG_SIZE(NAME) \
120 static_cast<unsigned>(diag::NUM_BUILTIN_##NAME##_DIAGNOSTICS) < \
121 static_cast<unsigned>(diag::DIAG_START_##NAME) + \
122 static_cast<unsigned>(diag::DIAG_SIZE_##NAME), \
124 DIAG_SIZE_##NAME) " is insufficient to contain all " \
125 "diagnostics, it may need to be made larger in " \
140#undef VALIDATE_DIAG_SIZE
143const StaticDiagInfoRec StaticDiagInfo[] = {
145#define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \
146 SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
151 DiagnosticIDs::SFINAE, \
158 STR_SIZE(DESC, uint16_t)},
159#include "clang/Basic/DiagnosticCommonKinds.inc"
160#include "clang/Basic/DiagnosticDriverKinds.inc"
161#include "clang/Basic/DiagnosticFrontendKinds.inc"
162#include "clang/Basic/DiagnosticSerializationKinds.inc"
163#include "clang/Basic/DiagnosticLexKinds.inc"
164#include "clang/Basic/DiagnosticParseKinds.inc"
165#include "clang/Basic/DiagnosticASTKinds.inc"
166#include "clang/Basic/DiagnosticCommentKinds.inc"
167#include "clang/Basic/DiagnosticCrossTUKinds.inc"
168#include "clang/Basic/DiagnosticSemaKinds.inc"
169#include "clang/Basic/DiagnosticAnalysisKinds.inc"
170#include "clang/Basic/DiagnosticRefactoringKinds.inc"
171#include "clang/Basic/DiagnosticInstallAPIKinds.inc"
184 using namespace diag;
185 if (DiagID >= DIAG_UPPER_LIMIT || DiagID <= DIAG_START_COMMON)
197 unsigned ID = DiagID - DIAG_START_COMMON - 1;
198#define CATEGORY(NAME, PREV) \
199 if (DiagID > DIAG_START_##NAME) { \
200 Offset += NUM_BUILTIN_##PREV##_DIAGNOSTICS - DIAG_START_##PREV - 1; \
201 ID -= DIAG_START_##NAME - DIAG_START_##PREV; \
223 const StaticDiagInfoRec *
Found = &StaticDiagInfo[ID + Offset];
227 if (
Found->DiagID != DiagID)
236 if (
const StaticDiagInfoRec *StaticInfo =
GetDiagInfo(DiagID)) {
239 if (StaticInfo->WarnNoWerror) {
241 "Unexpected mapping with no-Werror bit!");
252 if (
const StaticDiagInfoRec *Info =
GetDiagInfo(DiagID))
253 return Info->Category;
259 struct StaticDiagCategoryRec {
264 return StringRef(NameStr,
NameLen);
270#define GET_CATEGORY_TABLE
271#define CATEGORY(X, ENUM) { X, STR_SIZE(X, uint8_t) },
272#include "clang/Basic/DiagnosticGroups.inc"
273#undef GET_CATEGORY_TABLE
295 if (
const StaticDiagInfoRec *Info =
GetDiagInfo(DiagID))
301 if (
const StaticDiagInfoRec *Info =
GetDiagInfo(DiagID))
302 return Info->Deferrable;
309 if (
const StaticDiagInfoRec *Info =
GetDiagInfo(DiagID))
321 typedef std::pair<DiagnosticIDs::Level, std::string> DiagDesc;
322 std::vector<DiagDesc> DiagInfo;
323 std::map<DiagDesc, unsigned> DiagIDs;
330 "Invalid diagnostic ID");
337 "Invalid diagnostic ID");
343 DiagDesc
D(L, std::string(Message));
345 std::map<DiagDesc, unsigned>::iterator I = DiagIDs.lower_bound(
D);
346 if (I != DiagIDs.end() && I->first ==
D)
351 DiagIDs.insert(std::make_pair(
D, ID));
352 DiagInfo.push_back(
D);