diff options
author | Kristof Umann <dkszelethus@gmail.com> | 2018-11-12 17:49:51 +0000 |
---|---|---|
committer | Kristof Umann <dkszelethus@gmail.com> | 2018-11-12 17:49:51 +0000 |
commit | a216d79fac00fe42a7661b255ad3df040e764a19 (patch) | |
tree | 649e95316bda46413a60e49d4b9d8254a413d724 /utils | |
parent | 8e8c9f7c8a9e74c7007e3d71e308b4abe231712e (diff) | |
download | clang-a216d79fac00fe42a7661b255ad3df040e764a19.tar.gz |
[analyzer] Drastically simplify the tblgen files used for checkers
Interestingly, only about the quarter of the emitter file is used, the DescFile
entry hasn't ever been touched [1], and the entire concept of groups is a
mystery, so I removed them.
[1] http://lists.llvm.org/pipermail/cfe-dev/2018-October/059664.html
Differential Revision: https://reviews.llvm.org/D53995
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@346680 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r-- | utils/TableGen/ClangSACheckersEmitter.cpp | 252 |
1 files changed, 13 insertions, 239 deletions
diff --git a/utils/TableGen/ClangSACheckersEmitter.cpp b/utils/TableGen/ClangSACheckersEmitter.cpp index 4fda8e47e4..e01d55c527 100644 --- a/utils/TableGen/ClangSACheckersEmitter.cpp +++ b/utils/TableGen/ClangSACheckersEmitter.cpp @@ -11,34 +11,19 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/StringMap.h" #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" #include "llvm/TableGen/TableGenBackend.h" #include <map> #include <string> + using namespace llvm; //===----------------------------------------------------------------------===// // Static Analyzer Checkers Tables generation //===----------------------------------------------------------------------===// -/// True if it is specified hidden or a parent package is specified -/// as hidden, otherwise false. -static bool isHidden(const Record &R) { - if (R.getValueAsBit("Hidden")) - return true; - // Not declared as hidden, check the parent package if it is hidden. - if (DefInit *DI = dyn_cast<DefInit>(R.getValueInit("ParentPackage"))) - return isHidden(*DI->getDef()); - - return false; -} - -static bool isCheckerNamed(const Record *R) { - return !R->getValueAsString("CheckerName").empty(); -} - static std::string getPackageFullName(const Record *R); static std::string getParentPackageFullName(const Record *R) { @@ -50,17 +35,19 @@ static std::string getParentPackageFullName(const Record *R) { static std::string getPackageFullName(const Record *R) { std::string name = getParentPackageFullName(R); - if (!name.empty()) name += "."; + if (!name.empty()) + name += "."; + assert(!R->getValueAsString("PackageName").empty()); name += R->getValueAsString("PackageName"); return name; } static std::string getCheckerFullName(const Record *R) { std::string name = getParentPackageFullName(R); - if (isCheckerNamed(R)) { - if (!name.empty()) name += "."; - name += R->getValueAsString("CheckerName"); - } + if (!name.empty()) + name += "."; + assert(!R->getValueAsString("CheckerName").empty()); + name += R->getValueAsString("CheckerName"); return name; } @@ -70,129 +57,12 @@ static std::string getStringValue(const Record &R, StringRef field) { return std::string(); } -namespace { -struct GroupInfo { - llvm::DenseSet<const Record*> Checkers; - llvm::DenseSet<const Record *> SubGroups; - bool Hidden; - unsigned Index; - - GroupInfo() : Hidden(false) { } -}; -} - -static void addPackageToCheckerGroup(const Record *package, const Record *group, - llvm::DenseMap<const Record *, GroupInfo *> &recordGroupMap) { - llvm::DenseSet<const Record *> &checkers = recordGroupMap[package]->Checkers; - for (llvm::DenseSet<const Record *>::iterator - I = checkers.begin(), E = checkers.end(); I != E; ++I) - recordGroupMap[group]->Checkers.insert(*I); - - llvm::DenseSet<const Record *> &subGroups = recordGroupMap[package]->SubGroups; - for (llvm::DenseSet<const Record *>::iterator - I = subGroups.begin(), E = subGroups.end(); I != E; ++I) - addPackageToCheckerGroup(*I, group, recordGroupMap); -} - namespace clang { void EmitClangSACheckers(RecordKeeper &Records, raw_ostream &OS) { std::vector<Record*> checkers = Records.getAllDerivedDefinitions("Checker"); - llvm::DenseMap<const Record *, unsigned> checkerRecIndexMap; - for (unsigned i = 0, e = checkers.size(); i != e; ++i) - checkerRecIndexMap[checkers[i]] = i; - - // Invert the mapping of checkers to package/group into a one to many - // mapping of packages/groups to checkers. - std::map<std::string, GroupInfo> groupInfoByName; - llvm::DenseMap<const Record *, GroupInfo *> recordGroupMap; - std::vector<Record*> packages = Records.getAllDerivedDefinitions("Package"); - for (unsigned i = 0, e = packages.size(); i != e; ++i) { - Record *R = packages[i]; - std::string fullName = getPackageFullName(R); - if (!fullName.empty()) { - GroupInfo &info = groupInfoByName[fullName]; - info.Hidden = isHidden(*R); - recordGroupMap[R] = &info; - } - } - - std::vector<Record*> - checkerGroups = Records.getAllDerivedDefinitions("CheckerGroup"); - for (unsigned i = 0, e = checkerGroups.size(); i != e; ++i) { - Record *R = checkerGroups[i]; - std::string name = R->getValueAsString("GroupName"); - if (!name.empty()) { - GroupInfo &info = groupInfoByName[name]; - recordGroupMap[R] = &info; - } - } - - for (unsigned i = 0, e = checkers.size(); i != e; ++i) { - Record *R = checkers[i]; - Record *package = nullptr; - if (DefInit * - DI = dyn_cast<DefInit>(R->getValueInit("ParentPackage"))) - package = DI->getDef(); - if (!isCheckerNamed(R) && !package) - PrintFatalError(R->getLoc(), "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]; - info.Hidden = R->getValueAsBit("Hidden"); - recordGroupMap[R] = &info; - info.Checkers.insert(R); - } else { - recordGroupMap[package]->Checkers.insert(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 - = dyn_cast<DefInit>(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 = dyn_cast<DefInit>(R->getValueInit("Group"))) - recordGroupMap[DI->getDef()]->Checkers.insert(R); - } - // If a package is in group, add all its checkers and its sub-packages - // checkers into the group. - for (unsigned i = 0, e = packages.size(); i != e; ++i) - if (DefInit *DI = dyn_cast<DefInit>(packages[i]->getValueInit("Group"))) - addPackageToCheckerGroup(packages[i], DI->getDef(), recordGroupMap); - - typedef std::map<std::string, const Record *> SortedRecords; - typedef llvm::DenseMap<const Record *, unsigned> RecToSortIndex; - - SortedRecords sortedGroups; - RecToSortIndex groupToSortIndex; - OS << "\n#ifdef GET_GROUPS\n"; - { - for (unsigned i = 0, e = checkerGroups.size(); i != e; ++i) - sortedGroups[checkerGroups[i]->getValueAsString("GroupName")] - = checkerGroups[i]; - - unsigned sortIndex = 0; - for (SortedRecords::iterator - I = sortedGroups.begin(), E = sortedGroups.end(); I != E; ++I) { - const Record *R = I->second; - - OS << "GROUP(" << "\""; - OS.write_escaped(R->getValueAsString("GroupName")) << "\""; - OS << ")\n"; - - groupToSortIndex[R] = sortIndex++; - } - } - OS << "#endif // GET_GROUPS\n\n"; + using SortedRecords = llvm::StringMap<const Record *>; OS << "\n#ifdef GET_PACKAGES\n"; { @@ -205,17 +75,7 @@ void EmitClangSACheckers(RecordKeeper &Records, raw_ostream &OS) { const Record &R = *I->second; OS << "PACKAGE(" << "\""; - OS.write_escaped(getPackageFullName(&R)) << "\", "; - // Group index - if (DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group"))) - OS << groupToSortIndex[DI->getDef()] << ", "; - else - OS << "-1, "; - // Hidden bit - if (isHidden(R)) - OS << "true"; - else - OS << "false"; + OS.write_escaped(getPackageFullName(&R)) << '\"'; OS << ")\n"; } } @@ -226,98 +86,12 @@ void EmitClangSACheckers(RecordKeeper &Records, raw_ostream &OS) { const Record &R = *checkers[i]; OS << "CHECKER(" << "\""; - std::string name; - if (isCheckerNamed(&R)) - name = getCheckerFullName(&R); - OS.write_escaped(name) << "\", "; + OS.write_escaped(getCheckerFullName(&R)) << "\", "; OS << R.getName() << ", "; - OS << getStringValue(R, "DescFile") << ", "; OS << "\""; - OS.write_escaped(getStringValue(R, "HelpText")) << "\", "; - // Group index - if (DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group"))) - OS << groupToSortIndex[DI->getDef()] << ", "; - else - OS << "-1, "; - // Hidden bit - if (isHidden(R)) - OS << "true"; - else - OS << "false"; + OS.write_escaped(getStringValue(R, "HelpText")) << '\"'; OS << ")\n"; } OS << "#endif // GET_CHECKERS\n\n"; - - unsigned index = 0; - for (std::map<std::string, GroupInfo>::iterator - I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I) - I->second.Index = index++; - - // Walk through the packages/groups/checkers emitting an array for each - // set of checkers and an array for each set of subpackages. - - OS << "\n#ifdef GET_MEMBER_ARRAYS\n"; - unsigned maxLen = 0; - for (std::map<std::string, GroupInfo>::iterator - I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I) { - maxLen = std::max(maxLen, (unsigned)I->first.size()); - - llvm::DenseSet<const Record *> &checkers = I->second.Checkers; - if (!checkers.empty()) { - OS << "static const short CheckerArray" << I->second.Index << "[] = { "; - // Make the output order deterministic. - std::map<int, const Record *> sorted; - for (llvm::DenseSet<const Record *>::iterator - I = checkers.begin(), E = checkers.end(); I != E; ++I) - sorted[(*I)->getID()] = *I; - - for (std::map<int, const Record *>::iterator - I = sorted.begin(), E = sorted.end(); I != E; ++I) - OS << checkerRecIndexMap[I->second] << ", "; - OS << "-1 };\n"; - } - - llvm::DenseSet<const Record *> &subGroups = I->second.SubGroups; - if (!subGroups.empty()) { - OS << "static const short SubPackageArray" << I->second.Index << "[] = { "; - // Make the output order deterministic. - std::map<int, const Record *> sorted; - for (llvm::DenseSet<const Record *>::iterator - I = subGroups.begin(), E = subGroups.end(); I != E; ++I) - sorted[(*I)->getID()] = *I; - - for (std::map<int, const Record *>::iterator - I = sorted.begin(), E = sorted.end(); I != E; ++I) { - OS << recordGroupMap[I->second]->Index << ", "; - } - OS << "-1 };\n"; - } - } - OS << "#endif // GET_MEMBER_ARRAYS\n\n"; - - OS << "\n#ifdef GET_CHECKNAME_TABLE\n"; - for (std::map<std::string, GroupInfo>::iterator - I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I) { - // Group option string. - OS << " { \""; - OS.write_escaped(I->first) << "\"," - << std::string(maxLen-I->first.size()+1, ' '); - - if (I->second.Checkers.empty()) - OS << "0, "; - else - OS << "CheckerArray" << I->second.Index << ", "; - - // Subgroups. - if (I->second.SubGroups.empty()) - OS << "0, "; - else - OS << "SubPackageArray" << I->second.Index << ", "; - - OS << (I->second.Hidden ? "true" : "false"); - - OS << " },\n"; - } - OS << "#endif // GET_CHECKNAME_TABLE\n\n"; } } // end namespace clang |