When tablegen'ing the clang analyzer checkers:

-Use the tablegen class name for the checker class name.
-Mark checker packages as hidden/not hidden.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125558 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Argyrios Kyrtzidis 2011-02-15 07:42:16 +00:00
parent d9e087bbc3
commit ab8f3fd2e1

View File

@ -34,32 +34,49 @@ static bool isHidden(const Record &R) {
return false; return false;
} }
static std::string getPackageFullName(Record *R); static bool isCheckerNamed(const Record *R) {
return !R->getValueAsString("CheckerName").empty();
}
static std::string getParentPackageFullName(Record *R) { static std::string getPackageFullName(const Record *R);
static std::string getParentPackageFullName(const Record *R) {
std::string name; std::string name;
if (DefInit *DI = dynamic_cast<DefInit*>(R->getValueInit("ParentPackage"))) if (DefInit *DI = dynamic_cast<DefInit*>(R->getValueInit("ParentPackage")))
name = getPackageFullName(DI->getDef()); name = getPackageFullName(DI->getDef());
return name; return name;
} }
static std::string getPackageFullName(Record *R) { static std::string getPackageFullName(const Record *R) {
std::string name = getParentPackageFullName(R); std::string name = getParentPackageFullName(R);
if (!name.empty()) name += "."; if (!name.empty()) name += ".";
return name + R->getValueAsString("PackageName"); return name + R->getValueAsString("PackageName");
} }
static std::string getCheckerFullName(Record *R) { static std::string getCheckerFullName(const Record *R) {
std::string name = getParentPackageFullName(R); std::string name = getParentPackageFullName(R);
if (isCheckerNamed(R)) {
if (!name.empty()) name += "."; if (!name.empty()) name += ".";
return name + R->getValueAsString("CheckerName"); name += R->getValueAsString("CheckerName");
}
return name;
}
static std::string getStringValue(const Record &R, StringRef field) {
if (StringInit *
SI = dynamic_cast<StringInit*>(R.getValueInit(field)))
return SI->getValue();
return std::string();
} }
namespace { namespace {
struct GroupInfo { struct GroupInfo {
std::vector<const Record*> Checkers; std::vector<const Record*> Checkers;
llvm::DenseSet<const Record *> SubGroups; llvm::DenseSet<const Record *> SubGroups;
bool Hidden;
unsigned Index; unsigned Index;
GroupInfo() : Hidden(false) { }
}; };
} }
@ -74,11 +91,14 @@ void ClangSACheckersEmitter::run(raw_ostream &OS) {
const Record &R = *checkers[i]; const Record &R = *checkers[i];
OS << "CHECKER(" << "\""; OS << "CHECKER(" << "\"";
OS.write_escaped(R.getValueAsString("CheckerName")) << "\", "; std::string name;
OS << R.getValueAsString("ClassName") << ", "; if (isCheckerNamed(&R))
OS << R.getValueAsString("DescFile") << ", "; name = getCheckerFullName(&R);
OS.write_escaped(name) << "\", ";
OS << R.getName() << ", ";
OS << getStringValue(R, "DescFile") << ", ";
OS << "\""; OS << "\"";
OS.write_escaped(R.getValueAsString("HelpText")) << "\", "; OS.write_escaped(getStringValue(R, "HelpText")) << "\", ";
// Hidden bit // Hidden bit
if (isHidden(R)) if (isHidden(R))
OS << "true"; OS << "true";
@ -99,6 +119,7 @@ void ClangSACheckersEmitter::run(raw_ostream &OS) {
std::string fullName = getPackageFullName(R); std::string fullName = getPackageFullName(R);
if (!fullName.empty()) { if (!fullName.empty()) {
GroupInfo &info = groupInfoByName[fullName]; GroupInfo &info = groupInfoByName[fullName];
info.Hidden = isHidden(*R);
recordGroupMap[R] = &info; recordGroupMap[R] = &info;
} }
} }
@ -116,14 +137,26 @@ void ClangSACheckersEmitter::run(raw_ostream &OS) {
for (unsigned i = 0, e = checkers.size(); i != e; ++i) { for (unsigned i = 0, e = checkers.size(); i != e; ++i) {
Record *R = checkers[i]; Record *R = checkers[i];
Record *package = 0;
if (DefInit *
DI = dynamic_cast<DefInit*>(R->getValueInit("ParentPackage")))
package = DI->getDef();
if (!isCheckerNamed(R) && !package)
throw "Checker '" + R->getName() + "' is neither named, nor in a package!";
if (isCheckerNamed(R)) {
// Create a pseudo-group to hold this checker.
std::string fullName = getCheckerFullName(R); std::string fullName = getCheckerFullName(R);
if (!fullName.empty()) {
GroupInfo &info = groupInfoByName[fullName]; GroupInfo &info = groupInfoByName[fullName];
recordGroupMap[R] = &info; recordGroupMap[R] = &info;
info.Checkers.push_back(R); info.Checkers.push_back(R);
Record *currR = R; } else {
// Insert the checker and its parent packages into the set of the recordGroupMap[package]->Checkers.push_back(R);
// corresponding parent package. }
Record *currR = isCheckerNamed(R) ? R : package;
// Insert the checker and its parent packages into the subgroups set of
// the corresponding parent package.
while (DefInit *DI while (DefInit *DI
= dynamic_cast<DefInit*>(currR->getValueInit("ParentPackage"))) { = dynamic_cast<DefInit*>(currR->getValueInit("ParentPackage"))) {
Record *parentPackage = DI->getDef(); Record *parentPackage = DI->getDef();
@ -132,8 +165,7 @@ void ClangSACheckersEmitter::run(raw_ostream &OS) {
} }
// Insert the checker into the set of its group. // Insert the checker into the set of its group.
if (DefInit *DI = dynamic_cast<DefInit*>(R->getValueInit("Group"))) if (DefInit *DI = dynamic_cast<DefInit*>(R->getValueInit("Group")))
recordGroupMap[DI->getDef()]->SubGroups.insert(R); recordGroupMap[DI->getDef()]->Checkers.push_back(R);
}
} }
unsigned index = 0; unsigned index = 0;
@ -185,9 +217,12 @@ void ClangSACheckersEmitter::run(raw_ostream &OS) {
// Subgroups. // Subgroups.
if (I->second.SubGroups.empty()) if (I->second.SubGroups.empty())
OS << 0; OS << "0, ";
else else
OS << "SubPackageArray" << I->second.Index; OS << "SubPackageArray" << I->second.Index << ", ";
OS << (I->second.Hidden ? "true" : "false");
OS << " },\n"; OS << " },\n";
} }
OS << "#endif // GET_CHECKNAME_TABLE\n\n"; OS << "#endif // GET_CHECKNAME_TABLE\n\n";