Skip to content

[NFC][Clang] Use StringRef instead of string in ClangDiagnosticEmitter #115959

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 13, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 35 additions & 52 deletions clang/utils/TableGen/ClangDiagnosticsEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ class DiagGroupParentMap {
};
} // end anonymous namespace.

static std::string
static StringRef
getCategoryFromDiagGroup(const Record *Group,
DiagGroupParentMap &DiagGroupParents) {
// If the DiagGroup has a category, return it.
std::string CatName = std::string(Group->getValueAsString("CategoryName"));
StringRef CatName = Group->getValueAsString("CategoryName");
if (!CatName.empty()) return CatName;

// The diag group may the subgroup of one or more other diagnostic groups,
Expand All @@ -73,25 +73,26 @@ getCategoryFromDiagGroup(const Record *Group,

/// getDiagnosticCategory - Return the category that the specified diagnostic
/// lives in.
static std::string getDiagnosticCategory(const Record *R,
DiagGroupParentMap &DiagGroupParents) {
static StringRef getDiagnosticCategory(const Record *R,
DiagGroupParentMap &DiagGroupParents) {
// If the diagnostic is in a group, and that group has a category, use it.
if (const auto *Group = dyn_cast<DefInit>(R->getValueInit("Group"))) {
// Check the diagnostic's diag group for a category.
std::string CatName = getCategoryFromDiagGroup(Group->getDef(),
DiagGroupParents);
StringRef CatName =
getCategoryFromDiagGroup(Group->getDef(), DiagGroupParents);
if (!CatName.empty()) return CatName;
}

// If the diagnostic itself has a category, get it.
return std::string(R->getValueAsString("CategoryName"));
return R->getValueAsString("CategoryName");
}

namespace {
class DiagCategoryIDMap {
const RecordKeeper &Records;
StringMap<unsigned> CategoryIDs;
std::vector<std::string> CategoryStrings;
std::vector<StringRef> CategoryStrings;

public:
DiagCategoryIDMap(const RecordKeeper &records) : Records(records) {
DiagGroupParentMap ParentInfo(Records);
Expand All @@ -102,7 +103,7 @@ namespace {

for (const Record *Diag :
Records.getAllDerivedDefinitions("Diagnostic")) {
std::string Category = getDiagnosticCategory(Diag, ParentInfo);
StringRef Category = getDiagnosticCategory(Diag, ParentInfo);
if (Category.empty()) continue; // Skip diags with no category.

unsigned &ID = CategoryIDs[Category];
Expand All @@ -117,15 +118,15 @@ namespace {
return CategoryIDs[CategoryString];
}

typedef std::vector<std::string>::const_iterator const_iterator;
typedef std::vector<StringRef>::const_iterator const_iterator;
const_iterator begin() const { return CategoryStrings.begin(); }
const_iterator end() const { return CategoryStrings.end(); }
};

struct GroupInfo {
StringRef GroupName;
std::vector<const Record*> DiagsInGroup;
std::vector<std::string> SubGroups;
std::vector<StringRef> SubGroups;
unsigned IDNo = 0;

SmallVector<const Record *, 1> Defs;
Expand All @@ -145,7 +146,7 @@ static bool diagGroupBeforeByName(const Record *LHS, const Record *RHS) {
RHS->getValueAsString("GroupName");
}

using DiagsInGroupTy = std::map<std::string, GroupInfo, std::less<>>;
using DiagsInGroupTy = std::map<StringRef, GroupInfo>;

/// Invert the 1-[0/1] mapping of diags to group into a one to many
/// mapping of groups to diags in the group.
Expand All @@ -158,21 +159,19 @@ static void groupDiagnostics(ArrayRef<const Record *> Diags,
continue;
assert(R->getValueAsDef("Class")->getName() != "CLASS_NOTE" &&
"Note can't be in a DiagGroup");
std::string GroupName =
std::string(DI->getDef()->getValueAsString("GroupName"));
StringRef GroupName = DI->getDef()->getValueAsString("GroupName");
DiagsInGroup[GroupName].DiagsInGroup.push_back(R);
}

// Add all DiagGroup's to the DiagsInGroup list to make sure we pick up empty
// groups (these are warnings that GCC supports that clang never produces).
for (const Record *Group : DiagGroups) {
GroupInfo &GI =
DiagsInGroup[std::string(Group->getValueAsString("GroupName"))];
GroupInfo &GI = DiagsInGroup[Group->getValueAsString("GroupName")];
GI.GroupName = Group->getName();
GI.Defs.push_back(Group);

for (const Record *SubGroup : Group->getValueAsListOfDefs("SubGroups"))
GI.SubGroups.push_back(SubGroup->getValueAsString("GroupName").str());
GI.SubGroups.push_back(SubGroup->getValueAsString("GroupName"));
}

// Assign unique ID numbers to the groups.
Expand Down Expand Up @@ -281,8 +280,7 @@ class InferPedantic {
} // end anonymous namespace

bool InferPedantic::isSubGroupOfGroup(const Record *Group, StringRef GName) {
const std::string &GroupName =
std::string(Group->getValueAsString("GroupName"));
StringRef GroupName = Group->getValueAsString("GroupName");
if (GName == GroupName)
return true;

Expand All @@ -307,8 +305,7 @@ bool InferPedantic::groupInPedantic(const Record *Group, bool increment) {
GMap::mapped_type &V = GroupCount[Group];
// Lazily compute the threshold value for the group count.
if (!V.second) {
const GroupInfo &GI =
DiagsInGroup[std::string(Group->getValueAsString("GroupName"))];
const GroupInfo &GI = DiagsInGroup[Group->getValueAsString("GroupName")];
V.second = GI.SubGroups.size() + GI.DiagsInGroup.size();
}

Expand Down Expand Up @@ -1183,15 +1180,11 @@ std::string DiagnosticTextBuilder::buildForDefinition(const Record *R) {
//===----------------------------------------------------------------------===//

static bool isError(const Record &Diag) {
const std::string &ClsName =
std::string(Diag.getValueAsDef("Class")->getName());
return ClsName == "CLASS_ERROR";
return Diag.getValueAsDef("Class")->getName() == "CLASS_ERROR";
}

static bool isRemark(const Record &Diag) {
const std::string &ClsName =
std::string(Diag.getValueAsDef("Class")->getName());
return ClsName == "CLASS_REMARK";
return Diag.getValueAsDef("Class")->getName() == "CLASS_REMARK";
}

// Presumes the text has been split at the first whitespace or hyphen.
Expand Down Expand Up @@ -1419,16 +1412,13 @@ void clang::EmitClangDiagsDefs(const RecordKeeper &Records, raw_ostream &OS,
InferPedantic inferPedantic(DGParentMap, Diags, DiagGroups, DiagsInGroup);
inferPedantic.compute(&DiagsInPedantic, (RecordVec*)nullptr);

for (unsigned i = 0, e = Diags.size(); i != e; ++i) {
const Record &R = *Diags[i];

for (const Record &R : make_pointee_range(Diags)) {
// Check if this is an error that is accidentally in a warning
// group.
if (isError(R)) {
if (const auto *Group = dyn_cast<DefInit>(R.getValueInit("Group"))) {
const Record *GroupRec = Group->getDef();
const std::string &GroupName =
std::string(GroupRec->getValueAsString("GroupName"));
StringRef GroupName = GroupRec->getValueAsString("GroupName");
PrintFatalError(R.getLoc(), "Error " + R.getName() +
" cannot be in a warning group [" + GroupName + "]");
}
Expand Down Expand Up @@ -1461,13 +1451,11 @@ void clang::EmitClangDiagsDefs(const RecordKeeper &Records, raw_ostream &OS,
// Warning group associated with the diagnostic. This is stored as an index
// into the alphabetically sorted warning group table.
if (const auto *DI = dyn_cast<DefInit>(R.getValueInit("Group"))) {
std::map<std::string, GroupInfo>::iterator I = DiagsInGroup.find(
std::string(DI->getDef()->getValueAsString("GroupName")));
auto I = DiagsInGroup.find(DI->getDef()->getValueAsString("GroupName"));
assert(I != DiagsInGroup.end());
OS << ", " << I->second.IDNo;
} else if (DiagsInPedantic.count(&R)) {
std::map<std::string, GroupInfo>::iterator I =
DiagsInGroup.find("pedantic");
auto I = DiagsInGroup.find("pedantic");
assert(I != DiagsInGroup.end() && "pedantic group not defined");
OS << ", " << I->second.IDNo;
} else {
Expand Down Expand Up @@ -1537,19 +1525,18 @@ static void emitDiagSubGroups(DiagsInGroupTy &DiagsInGroup,
<< " /* Empty */ -1,\n";
for (auto const &[Name, Group] : DiagsInGroup) {
const bool IsPedantic = Name == "pedantic";
const std::vector<std::string> &SubGroups = Group.SubGroups;
const std::vector<StringRef> &SubGroups = Group.SubGroups;
if (!SubGroups.empty() || (IsPedantic && !GroupsInPedantic.empty())) {
OS << " /* DiagSubGroup" << Group.IDNo << " */ ";
for (auto const &SubGroup : SubGroups) {
for (StringRef SubGroup : SubGroups) {
auto RI = DiagsInGroup.find(SubGroup);
assert(RI != DiagsInGroup.end() && "Referenced without existing?");
OS << RI->second.IDNo << ", ";
}
// Emit the groups implicitly in "pedantic".
if (IsPedantic) {
for (auto const &Group : GroupsInPedantic) {
const std::string &GroupName =
std::string(Group->getValueAsString("GroupName"));
StringRef GroupName = Group->getValueAsString("GroupName");
auto RI = DiagsInGroup.find(GroupName);
assert(RI != DiagsInGroup.end() && "Referenced without existing?");
OS << RI->second.IDNo << ", ";
Expand Down Expand Up @@ -1682,7 +1669,7 @@ static void emitDiagTable(DiagsInGroupTy &DiagsInGroup,
PrintFatalError("Invalid character in diagnostic group '" + Name + "'");
OS << Name << " */, ";
// Store a pascal-style length byte at the beginning of the string.
std::string PascalName = char(Name.size()) + Name;
std::string PascalName = char(Name.size()) + Name.str();
OS << *GroupNames.GetStringOffset(PascalName) << ", ";

// Special handling for 'pedantic'.
Expand All @@ -1703,7 +1690,7 @@ static void emitDiagTable(DiagsInGroupTy &DiagsInGroup,
}

// Subgroups.
const std::vector<std::string> &SubGroups = GroupInfo.SubGroups;
const std::vector<StringRef> &SubGroups = GroupInfo.SubGroups;
const bool hasSubGroups =
!SubGroups.empty() || (IsPedantic && !GroupsInPedantic.empty());
if (hasSubGroups) {
Expand Down Expand Up @@ -1771,13 +1758,10 @@ void clang::EmitClangDiagGroups(const RecordKeeper &Records, raw_ostream &OS) {
inferPedantic.compute(&DiagsInPedantic, &GroupsInPedantic);

StringToOffsetTable GroupNames;
for (std::map<std::string, GroupInfo>::const_iterator
I = DiagsInGroup.begin(),
E = DiagsInGroup.end();
I != E; ++I) {
for (const auto &[Name, Group] : DiagsInGroup) {
// Store a pascal-style length byte at the beginning of the string.
std::string Name = char(I->first.size()) + I->first;
GroupNames.GetOrAddStringOffset(Name, false);
std::string PascalName = char(Name.size()) + Name.str();
GroupNames.GetOrAddStringOffset(PascalName, false);
}

emitAllDiagArrays(DiagsInGroup, DiagsInPedantic, GroupsInPedantic, GroupNames,
Expand Down Expand Up @@ -1835,7 +1819,7 @@ bool isRemarkGroup(const Record *DiagGroup,
auto &GroupInfo = DiagsInGroup.find(GroupName)->second;
for (const Record *Diag : GroupInfo.DiagsInGroup)
(isRemark(*Diag) ? AnyRemarks : AnyNonRemarks) = true;
for (const auto &Name : GroupInfo.SubGroups)
for (StringRef Name : GroupInfo.SubGroups)
Visit(Name);
};
Visit(DiagGroup->getValueAsString("GroupName"));
Expand Down Expand Up @@ -1932,8 +1916,7 @@ void clang::EmitClangDiagDocs(const RecordKeeper &Records, raw_ostream &OS) {
DiagsInPedantic.begin(),
DiagsInPedantic.end());
for (auto *Group : GroupsInPedantic)
PedDiags.SubGroups.push_back(
std::string(Group->getValueAsString("GroupName")));
PedDiags.SubGroups.push_back(Group->getValueAsString("GroupName"));
}

// FIXME: Write diagnostic categories and link to diagnostic groups in each.
Expand Down Expand Up @@ -1979,7 +1962,7 @@ void clang::EmitClangDiagDocs(const RecordKeeper &Records, raw_ostream &OS) {

bool First = true;
sort(GroupInfo.SubGroups);
for (const auto &Name : GroupInfo.SubGroups) {
for (StringRef Name : GroupInfo.SubGroups) {
if (!First) OS << ", ";
OS << "`" << (IsRemarkGroup ? "-R" : "-W") << Name << "`_";
First = false;
Expand Down
Loading