From ab8f3fd2e1c07231deffba8ea4ecd06ac559afe4 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Tue, 15 Feb 2011 07:42:16 +0000 Subject: 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 --- utils/TableGen/ClangSACheckersEmitter.cpp | 89 +++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 27 deletions(-) (limited to 'utils/TableGen') diff --git a/utils/TableGen/ClangSACheckersEmitter.cpp b/utils/TableGen/ClangSACheckersEmitter.cpp index 05d3f5b..3e49ab1 100644 --- a/utils/TableGen/ClangSACheckersEmitter.cpp +++ b/utils/TableGen/ClangSACheckersEmitter.cpp @@ -34,32 +34,49 @@ static bool isHidden(const Record &R) { return false; } -static std::string getPackageFullName(Record *R); +static bool isCheckerNamed(const Record *R) { + return !R->getValueAsString("CheckerName").empty(); +} + +static std::string getPackageFullName(const Record *R); -static std::string getParentPackageFullName(Record *R) { +static std::string getParentPackageFullName(const Record *R) { std::string name; if (DefInit *DI = dynamic_cast(R->getValueInit("ParentPackage"))) name = getPackageFullName(DI->getDef()); return name; } -static std::string getPackageFullName(Record *R) { +static std::string getPackageFullName(const Record *R) { std::string name = getParentPackageFullName(R); if (!name.empty()) name += "."; return name + R->getValueAsString("PackageName"); } -static std::string getCheckerFullName(Record *R) { +static std::string getCheckerFullName(const Record *R) { std::string name = getParentPackageFullName(R); - if (!name.empty()) name += "."; - return name + R->getValueAsString("CheckerName"); + if (isCheckerNamed(R)) { + if (!name.empty()) name += "."; + name += R->getValueAsString("CheckerName"); + } + return name; +} + +static std::string getStringValue(const Record &R, StringRef field) { + if (StringInit * + SI = dynamic_cast(R.getValueInit(field))) + return SI->getValue(); + return std::string(); } namespace { struct GroupInfo { std::vector Checkers; llvm::DenseSet SubGroups; + bool Hidden; unsigned Index; + + GroupInfo() : Hidden(false) { } }; } @@ -72,13 +89,16 @@ void ClangSACheckersEmitter::run(raw_ostream &OS) { OS << "\n#ifdef GET_CHECKERS\n"; for (unsigned i = 0, e = checkers.size(); i != e; ++i) { const Record &R = *checkers[i]; - + OS << "CHECKER(" << "\""; - OS.write_escaped(R.getValueAsString("CheckerName")) << "\", "; - OS << R.getValueAsString("ClassName") << ", "; - OS << R.getValueAsString("DescFile") << ", "; + std::string name; + if (isCheckerNamed(&R)) + name = getCheckerFullName(&R); + OS.write_escaped(name) << "\", "; + OS << R.getName() << ", "; + OS << getStringValue(R, "DescFile") << ", "; OS << "\""; - OS.write_escaped(R.getValueAsString("HelpText")) << "\", "; + OS.write_escaped(getStringValue(R, "HelpText")) << "\", "; // Hidden bit if (isHidden(R)) OS << "true"; @@ -99,6 +119,7 @@ void ClangSACheckersEmitter::run(raw_ostream &OS) { std::string fullName = getPackageFullName(R); if (!fullName.empty()) { GroupInfo &info = groupInfoByName[fullName]; + info.Hidden = isHidden(*R); recordGroupMap[R] = &info; } } @@ -116,24 +137,35 @@ void ClangSACheckersEmitter::run(raw_ostream &OS) { for (unsigned i = 0, e = checkers.size(); i != e; ++i) { Record *R = checkers[i]; - std::string fullName = getCheckerFullName(R); - if (!fullName.empty()) { + Record *package = 0; + if (DefInit * + DI = dynamic_cast(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); GroupInfo &info = groupInfoByName[fullName]; recordGroupMap[R] = &info; info.Checkers.push_back(R); - Record *currR = R; - // Insert the checker and its parent packages into the set of the - // corresponding parent package. - while (DefInit *DI - = dynamic_cast(currR->getValueInit("ParentPackage"))) { - Record *parentPackage = DI->getDef(); - recordGroupMap[parentPackage]->SubGroups.insert(currR); - currR = parentPackage; - } - // Insert the checker into the set of its group. - if (DefInit *DI = dynamic_cast(R->getValueInit("Group"))) - recordGroupMap[DI->getDef()]->SubGroups.insert(R); + } else { + recordGroupMap[package]->Checkers.push_back(R); + } + + 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 + = dynamic_cast(currR->getValueInit("ParentPackage"))) { + Record *parentPackage = DI->getDef(); + recordGroupMap[parentPackage]->SubGroups.insert(currR); + currR = parentPackage; } + // Insert the checker into the set of its group. + if (DefInit *DI = dynamic_cast(R->getValueInit("Group"))) + recordGroupMap[DI->getDef()]->Checkers.push_back(R); } unsigned index = 0; @@ -185,9 +217,12 @@ void ClangSACheckersEmitter::run(raw_ostream &OS) { // Subgroups. if (I->second.SubGroups.empty()) - OS << 0; + OS << "0, "; else - OS << "SubPackageArray" << I->second.Index; + OS << "SubPackageArray" << I->second.Index << ", "; + + OS << (I->second.Hidden ? "true" : "false"); + OS << " },\n"; } OS << "#endif // GET_CHECKNAME_TABLE\n\n"; -- cgit v1.1