aboutsummaryrefslogtreecommitdiff
path: root/lib/Basic/DiagnosticIDs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Basic/DiagnosticIDs.cpp')
-rw-r--r--lib/Basic/DiagnosticIDs.cpp185
1 files changed, 121 insertions, 64 deletions
diff --git a/lib/Basic/DiagnosticIDs.cpp b/lib/Basic/DiagnosticIDs.cpp
index b4dd575a9684..6d7e3204cba3 100644
--- a/lib/Basic/DiagnosticIDs.cpp
+++ b/lib/Basic/DiagnosticIDs.cpp
@@ -45,14 +45,37 @@ struct StaticDiagInfoRec {
unsigned SFINAE : 1;
unsigned AccessControl : 1;
unsigned Category : 5;
-
- const char *Name;
-
- const char *Description;
- const char *OptionGroup;
- const char *BriefExplanation;
- const char *FullExplanation;
+ uint8_t NameLen;
+ uint8_t OptionGroupLen;
+
+ uint16_t DescriptionLen;
+ uint16_t BriefExplanationLen;
+ uint16_t FullExplanationLen;
+
+ const char *NameStr;
+ const char *OptionGroupStr;
+
+ const char *DescriptionStr;
+ const char *BriefExplanationStr;
+ const char *FullExplanationStr;
+
+ llvm::StringRef getName() const {
+ return llvm::StringRef(NameStr, NameLen);
+ }
+ llvm::StringRef getOptionGroup() const {
+ return llvm::StringRef(OptionGroupStr, OptionGroupLen);
+ }
+
+ llvm::StringRef getDescription() const {
+ return llvm::StringRef(DescriptionStr, DescriptionLen);
+ }
+ llvm::StringRef getBriefExplanation() const {
+ return llvm::StringRef(BriefExplanationStr, BriefExplanationLen);
+ }
+ llvm::StringRef getFullExplanation() const {
+ return llvm::StringRef(FullExplanationStr, FullExplanationLen);
+ }
bool operator<(const StaticDiagInfoRec &RHS) const {
return DiagID < RHS.DiagID;
@@ -60,27 +83,42 @@ struct StaticDiagInfoRec {
};
struct StaticDiagNameIndexRec {
- const char *Name;
+ const char *NameStr;
unsigned short DiagID;
-
+ uint8_t NameLen;
+
+ llvm::StringRef getName() const {
+ return llvm::StringRef(NameStr, NameLen);
+ }
+
bool operator<(const StaticDiagNameIndexRec &RHS) const {
- assert(Name && RHS.Name && "Null Diagnostic Name");
- return strcmp(Name, RHS.Name) == -1;
+ return getName() < RHS.getName();
}
bool operator==(const StaticDiagNameIndexRec &RHS) const {
- assert(Name && RHS.Name && "Null Diagnostic Name");
- return strcmp(Name, RHS.Name) == 0;
+ return getName() == RHS.getName();
}
};
-}
+template <size_t SizeOfStr, typename FieldType>
+class StringSizerHelper {
+ char FIELD_TOO_SMALL[SizeOfStr <= FieldType(~0U) ? 1 : -1];
+public:
+ enum { Size = SizeOfStr };
+};
+
+} // namespace anonymous
+
+#define STR_SIZE(str, fieldTy) StringSizerHelper<sizeof(str)-1, fieldTy>::Size
static const StaticDiagInfoRec StaticDiagInfo[] = {
-#define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC,GROUP, \
- SFINAE,ACCESS,CATEGORY,BRIEF,FULL) \
- { diag::ENUM, DEFAULT_MAPPING, CLASS, SFINAE, \
- ACCESS, CATEGORY, #ENUM, DESC, GROUP, BRIEF, FULL },
+#define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC,GROUP, \
+ SFINAE,ACCESS,CATEGORY,BRIEF,FULL) \
+ { diag::ENUM, DEFAULT_MAPPING, CLASS, SFINAE, ACCESS, CATEGORY, \
+ STR_SIZE(#ENUM, uint8_t), STR_SIZE(GROUP, uint8_t), \
+ STR_SIZE(DESC, uint16_t), STR_SIZE(BRIEF, uint16_t), \
+ STR_SIZE(FULL, uint16_t), \
+ #ENUM, GROUP, DESC, BRIEF, FULL },
#include "clang/Basic/DiagnosticCommonKinds.inc"
#include "clang/Basic/DiagnosticDriverKinds.inc"
#include "clang/Basic/DiagnosticFrontendKinds.inc"
@@ -90,7 +128,7 @@ static const StaticDiagInfoRec StaticDiagInfo[] = {
#include "clang/Basic/DiagnosticSemaKinds.inc"
#include "clang/Basic/DiagnosticAnalysisKinds.inc"
#undef DIAG
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
static const unsigned StaticDiagInfoSize =
@@ -98,10 +136,10 @@ static const unsigned StaticDiagInfoSize =
/// To be sorted before first use (since it's splitted among multiple files)
static StaticDiagNameIndexRec StaticDiagNameIndex[] = {
-#define DIAG_NAME_INDEX(ENUM) { #ENUM, diag::ENUM },
+#define DIAG_NAME_INDEX(ENUM) { #ENUM, diag::ENUM, STR_SIZE(#ENUM, uint8_t) },
#include "clang/Basic/DiagnosticIndexName.inc"
#undef DIAG_NAME_INDEX
- { 0, 0 }
+ { 0, 0, 0 }
};
static const unsigned StaticDiagNameIndexSize =
@@ -127,7 +165,7 @@ static const StaticDiagInfoRec *GetDiagInfo(unsigned DiagID) {
#endif
// Search the diagnostic table with a binary search.
- StaticDiagInfoRec Find = { DiagID, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ StaticDiagInfoRec Find = { DiagID, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0 };
const StaticDiagInfoRec *Found =
std::lower_bound(StaticDiagInfo, StaticDiagInfo + StaticDiagInfoSize, Find);
@@ -147,10 +185,10 @@ static unsigned GetDefaultDiagMapping(unsigned DiagID) {
/// getWarningOptionForDiag - Return the lowest-level warning option that
/// enables the specified diagnostic. If there is no -Wfoo flag that controls
/// the diagnostic, this returns null.
-const char *DiagnosticIDs::getWarningOptionForDiag(unsigned DiagID) {
+llvm::StringRef DiagnosticIDs::getWarningOptionForDiag(unsigned DiagID) {
if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
- return Info->OptionGroup;
- return 0;
+ return Info->getOptionGroup();
+ return llvm::StringRef();
}
/// getCategoryNumberForDiag - Return the category number that a specified
@@ -161,23 +199,36 @@ unsigned DiagnosticIDs::getCategoryNumberForDiag(unsigned DiagID) {
return 0;
}
-/// getCategoryNameFromID - Given a category ID, return the name of the
-/// category, an empty string if CategoryID is zero, or null if CategoryID is
-/// invalid.
-const char *DiagnosticIDs::getCategoryNameFromID(unsigned CategoryID) {
- // Second the table of options, sorted by name for fast binary lookup.
- static const char *CategoryNameTable[] = {
+// The diagnostic category names.
+struct StaticDiagCategoryRec {
+ const char *NameStr;
+ uint8_t NameLen;
+
+ llvm::StringRef getName() const {
+ return llvm::StringRef(NameStr, NameLen);
+ }
+};
+
+static StaticDiagCategoryRec CategoryNameTable[] = {
#define GET_CATEGORY_TABLE
-#define CATEGORY(X) X,
+#define CATEGORY(X) { X, STR_SIZE(X, uint8_t) },
#include "clang/Basic/DiagnosticGroups.inc"
#undef GET_CATEGORY_TABLE
- "<<END>>"
- };
- static const size_t CategoryNameTableSize =
- sizeof(CategoryNameTable) / sizeof(CategoryNameTable[0])-1;
-
- if (CategoryID >= CategoryNameTableSize) return 0;
- return CategoryNameTable[CategoryID];
+ { 0, 0 }
+};
+
+/// getNumberOfCategories - Return the number of categories
+unsigned DiagnosticIDs::getNumberOfCategories() {
+ return sizeof(CategoryNameTable) / sizeof(CategoryNameTable[0])-1;
+}
+
+/// getCategoryNameFromID - Given a category ID, return the name of the
+/// category, an empty string if CategoryID is zero, or null if CategoryID is
+/// invalid.
+llvm::StringRef DiagnosticIDs::getCategoryNameFromID(unsigned CategoryID) {
+ if (CategoryID >= getNumberOfCategories())
+ return llvm::StringRef();
+ return CategoryNameTable[CategoryID].getName();
}
@@ -202,25 +253,25 @@ DiagnosticIDs::getDiagnosticSFINAEResponse(unsigned DiagID) {
}
/// getName - Given a diagnostic ID, return its name
-const char *DiagnosticIDs::getName(unsigned DiagID) {
+llvm::StringRef DiagnosticIDs::getName(unsigned DiagID) {
if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
- return Info->Name;
- return 0;
+ return Info->getName();
+ return llvm::StringRef();
}
/// getIdFromName - Given a diagnostic name, return its ID, or 0
-unsigned DiagnosticIDs::getIdFromName(char const *Name) {
+unsigned DiagnosticIDs::getIdFromName(llvm::StringRef Name) {
StaticDiagNameIndexRec *StaticDiagNameIndexEnd =
StaticDiagNameIndex + StaticDiagNameIndexSize;
- if (Name == 0) { return diag::DIAG_UPPER_LIMIT; }
+ if (Name.empty()) { return diag::DIAG_UPPER_LIMIT; }
- StaticDiagNameIndexRec Find = { Name, 0 };
+ StaticDiagNameIndexRec Find = { Name.data(), 0, Name.size() };
const StaticDiagNameIndexRec *Found =
std::lower_bound( StaticDiagNameIndex, StaticDiagNameIndexEnd, Find);
if (Found == StaticDiagNameIndexEnd ||
- strcmp(Found->Name, Name) != 0)
+ Found->getName() != Name)
return diag::DIAG_UPPER_LIMIT;
return Found->DiagID;
@@ -228,18 +279,18 @@ unsigned DiagnosticIDs::getIdFromName(char const *Name) {
/// getBriefExplanation - Given a diagnostic ID, return a brief explanation
/// of the issue
-const char *DiagnosticIDs::getBriefExplanation(unsigned DiagID) {
+llvm::StringRef DiagnosticIDs::getBriefExplanation(unsigned DiagID) {
if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
- return Info->BriefExplanation;
- return 0;
+ return Info->getBriefExplanation();
+ return llvm::StringRef();
}
/// getFullExplanation - Given a diagnostic ID, return a full explanation
/// of the issue
-const char *DiagnosticIDs::getFullExplanation(unsigned DiagID) {
+llvm::StringRef DiagnosticIDs::getFullExplanation(unsigned DiagID) {
if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
- return Info->FullExplanation;
- return 0;
+ return Info->getFullExplanation();
+ return llvm::StringRef();
}
/// getBuiltinDiagClass - Return the class field of the diagnostic.
@@ -264,10 +315,10 @@ namespace clang {
/// getDescription - Return the description of the specified custom
/// diagnostic.
- const char *getDescription(unsigned DiagID) const {
+ llvm::StringRef getDescription(unsigned DiagID) const {
assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() &&
"Invalid diagnosic ID");
- return DiagInfo[DiagID-DIAG_UPPER_LIMIT].second.c_str();
+ return DiagInfo[DiagID-DIAG_UPPER_LIMIT].second;
}
/// getLevel - Return the level of the specified custom diagnostic.
@@ -352,9 +403,9 @@ bool DiagnosticIDs::isBuiltinExtensionDiag(unsigned DiagID,
/// getDescription - Given a diagnostic ID, return a description of the
/// issue.
-const char *DiagnosticIDs::getDescription(unsigned DiagID) const {
+llvm::StringRef DiagnosticIDs::getDescription(unsigned DiagID) const {
if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
- return Info->Description;
+ return Info->getDescription();
return CustomDiagInfo->getDescription(DiagID);
}
@@ -493,9 +544,15 @@ DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass,
}
struct WarningOption {
- const char *Name;
+ // Be safe with the size of 'NameLen' because we don't statically check if the
+ // size will fit in the field; the struct size won't decrease with a shorter
+ // type anyway.
+ size_t NameLen;
+ const char *NameStr;
const short *Members;
const short *SubGroups;
+
+ llvm::StringRef getName() const { return llvm::StringRef(NameStr, NameLen); }
};
#define GET_DIAG_ARRAYS
@@ -513,7 +570,7 @@ sizeof(OptionTable) / sizeof(OptionTable[0]);
static bool WarningOptionCompare(const WarningOption &LHS,
const WarningOption &RHS) {
- return strcmp(LHS.Name, RHS.Name) < 0;
+ return LHS.getName() < RHS.getName();
}
static void MapGroupMembers(const WarningOption *Group, diag::Mapping Mapping,
@@ -534,10 +591,10 @@ static void MapGroupMembers(const WarningOption *Group, diag::Mapping Mapping,
/// setDiagnosticGroupMapping - Change an entire diagnostic group (e.g.
/// "unknown-pragmas" to have the specified mapping. This returns true and
/// ignores the request if "Group" was unknown, false otherwise.
-bool DiagnosticIDs::setDiagnosticGroupMapping(const char *Group,
- diag::Mapping Map,
- SourceLocation Loc,
- Diagnostic &Diag) const {
+bool DiagnosticIDs::setDiagnosticGroupMapping(llvm::StringRef Group,
+ diag::Mapping Map,
+ SourceLocation Loc,
+ Diagnostic &Diag) const {
assert((Loc.isValid() ||
Diag.DiagStatePoints.empty() ||
Diag.DiagStatePoints.back().Loc.isInvalid()) &&
@@ -548,12 +605,12 @@ bool DiagnosticIDs::setDiagnosticGroupMapping(const char *Group,
Diag.DiagStatePoints.back().Loc)) &&
"Source location of new mapping is before the previous one!");
- WarningOption Key = { Group, 0, 0 };
+ WarningOption Key = { Group.size(), Group.data(), 0, 0 };
const WarningOption *Found =
std::lower_bound(OptionTable, OptionTable + OptionTableSize, Key,
WarningOptionCompare);
if (Found == OptionTable + OptionTableSize ||
- strcmp(Found->Name, Group) != 0)
+ Found->getName() != Group)
return true; // Option not found.
MapGroupMembers(Found, Map, Loc, Diag);