151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne//=- ClangSACheckersEmitter.cpp - Generate Clang SA checkers tables -*- C++ -*- 251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// 351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// The LLVM Compiler Infrastructure 451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// 551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// This file is distributed under the University of Illinois Open Source 651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// License. See LICENSE.TXT for details. 751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// 851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne//===----------------------------------------------------------------------===// 951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// 1051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// This tablegen backend emits Clang Static Analyzer checkers tables. 1151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// 1251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne//===----------------------------------------------------------------------===// 1351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 1451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne#include "llvm/ADT/DenseSet.h" 1538859ee4a3c1253d5a45ed3f6b52e77702bfd913Joerg Sonnenberger#include "llvm/TableGen/Error.h" 163cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen#include "llvm/TableGen/Record.h" 173cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen#include "llvm/TableGen/TableGenBackend.h" 1851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne#include <map> 1951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne#include <string> 2051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourneusing namespace llvm; 2151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 2251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne//===----------------------------------------------------------------------===// 2351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// Static Analyzer Checkers Tables generation 2451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne//===----------------------------------------------------------------------===// 2551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 2651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// \brief True if it is specified hidden or a parent package is specified 2751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// as hidden, otherwise false. 2851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic bool isHidden(const Record &R) { 2951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (R.getValueAsBit("Hidden")) 3051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return true; 3151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Not declared as hidden, check the parent package if it is hidden. 321ab46323089f9a836a510521aab55ff958b67150Sean Silva if (DefInit *DI = dyn_cast<DefInit>(R.getValueInit("ParentPackage"))) 3351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return isHidden(*DI->getDef()); 3451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 3551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return false; 3651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 3751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 3851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic bool isCheckerNamed(const Record *R) { 3951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return !R->getValueAsString("CheckerName").empty(); 4051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 4151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 4251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic std::string getPackageFullName(const Record *R); 4351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 4451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic std::string getParentPackageFullName(const Record *R) { 4551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string name; 461ab46323089f9a836a510521aab55ff958b67150Sean Silva if (DefInit *DI = dyn_cast<DefInit>(R->getValueInit("ParentPackage"))) 4751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne name = getPackageFullName(DI->getDef()); 4851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return name; 4951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 5051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 5151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic std::string getPackageFullName(const Record *R) { 5251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string name = getParentPackageFullName(R); 5351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (!name.empty()) name += "."; 5451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return name + R->getValueAsString("PackageName"); 5551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 5651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 5751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic std::string getCheckerFullName(const Record *R) { 5851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string name = getParentPackageFullName(R); 5951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (isCheckerNamed(R)) { 6051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (!name.empty()) name += "."; 6151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne name += R->getValueAsString("CheckerName"); 6251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 6351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return name; 6451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 6551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 6651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic std::string getStringValue(const Record &R, StringRef field) { 671ab46323089f9a836a510521aab55ff958b67150Sean Silva if (StringInit *SI = dyn_cast<StringInit>(R.getValueInit(field))) 6851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return SI->getValue(); 6951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return std::string(); 7051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 7151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 7251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournenamespace { 7351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestruct GroupInfo { 7451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne llvm::DenseSet<const Record*> Checkers; 7551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne llvm::DenseSet<const Record *> SubGroups; 7651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool Hidden; 7751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne unsigned Index; 7851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 7951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne GroupInfo() : Hidden(false) { } 8051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne}; 8151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 8251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 8351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic void addPackageToCheckerGroup(const Record *package, const Record *group, 8451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne llvm::DenseMap<const Record *, GroupInfo *> &recordGroupMap) { 8551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne llvm::DenseSet<const Record *> &checkers = recordGroupMap[package]->Checkers; 8651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (llvm::DenseSet<const Record *>::iterator 8751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne I = checkers.begin(), E = checkers.end(); I != E; ++I) 8851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne recordGroupMap[group]->Checkers.insert(*I); 8951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 9051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne llvm::DenseSet<const Record *> &subGroups = recordGroupMap[package]->SubGroups; 9151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (llvm::DenseSet<const Record *>::iterator 9251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne I = subGroups.begin(), E = subGroups.end(); I != E; ++I) 9351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne addPackageToCheckerGroup(*I, group, recordGroupMap); 9451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 9551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 963cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesennamespace clang { 973cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenvoid EmitClangSACheckers(RecordKeeper &Records, raw_ostream &OS) { 9851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Record*> checkers = Records.getAllDerivedDefinitions("Checker"); 9951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne llvm::DenseMap<const Record *, unsigned> checkerRecIndexMap; 10051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0, e = checkers.size(); i != e; ++i) 10151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne checkerRecIndexMap[checkers[i]] = i; 10251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 10351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Invert the mapping of checkers to package/group into a one to many 10451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // mapping of packages/groups to checkers. 10551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::map<std::string, GroupInfo> groupInfoByName; 10651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne llvm::DenseMap<const Record *, GroupInfo *> recordGroupMap; 10751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 10851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Record*> packages = Records.getAllDerivedDefinitions("Package"); 10951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0, e = packages.size(); i != e; ++i) { 11051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record *R = packages[i]; 11151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string fullName = getPackageFullName(R); 11251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (!fullName.empty()) { 11351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne GroupInfo &info = groupInfoByName[fullName]; 11451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne info.Hidden = isHidden(*R); 11551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne recordGroupMap[R] = &info; 11651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 11751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 11851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 11951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Record*> 12051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne checkerGroups = Records.getAllDerivedDefinitions("CheckerGroup"); 12151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0, e = checkerGroups.size(); i != e; ++i) { 12251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record *R = checkerGroups[i]; 12351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string name = R->getValueAsString("GroupName"); 12451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (!name.empty()) { 12551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne GroupInfo &info = groupInfoByName[name]; 12651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne recordGroupMap[R] = &info; 12751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 12851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 12951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 13051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0, e = checkers.size(); i != e; ++i) { 13151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record *R = checkers[i]; 1326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Record *package = nullptr; 13351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (DefInit * 1341ab46323089f9a836a510521aab55ff958b67150Sean Silva DI = dyn_cast<DefInit>(R->getValueInit("ParentPackage"))) 13551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne package = DI->getDef(); 13651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (!isCheckerNamed(R) && !package) 13738859ee4a3c1253d5a45ed3f6b52e77702bfd913Joerg Sonnenberger PrintFatalError(R->getLoc(), "Checker '" + R->getName() + 13838859ee4a3c1253d5a45ed3f6b52e77702bfd913Joerg Sonnenberger "' is neither named, nor in a package!"); 13951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 14051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (isCheckerNamed(R)) { 14151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Create a pseudo-group to hold this checker. 14251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string fullName = getCheckerFullName(R); 14351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne GroupInfo &info = groupInfoByName[fullName]; 14451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne info.Hidden = R->getValueAsBit("Hidden"); 14551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne recordGroupMap[R] = &info; 14651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne info.Checkers.insert(R); 14751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } else { 14851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne recordGroupMap[package]->Checkers.insert(R); 14951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 15051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 15151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record *currR = isCheckerNamed(R) ? R : package; 15251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Insert the checker and its parent packages into the subgroups set of 15351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // the corresponding parent package. 15451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne while (DefInit *DI 1551ab46323089f9a836a510521aab55ff958b67150Sean Silva = dyn_cast<DefInit>(currR->getValueInit("ParentPackage"))) { 15651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record *parentPackage = DI->getDef(); 15751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne recordGroupMap[parentPackage]->SubGroups.insert(currR); 15851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne currR = parentPackage; 15951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 16051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Insert the checker into the set of its group. 1611ab46323089f9a836a510521aab55ff958b67150Sean Silva if (DefInit *DI = dyn_cast<DefInit>(R->getValueInit("Group"))) 16251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne recordGroupMap[DI->getDef()]->Checkers.insert(R); 16351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 16451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 16551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // If a package is in group, add all its checkers and its sub-packages 16651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // checkers into the group. 16751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0, e = packages.size(); i != e; ++i) 1681ab46323089f9a836a510521aab55ff958b67150Sean Silva if (DefInit *DI = dyn_cast<DefInit>(packages[i]->getValueInit("Group"))) 16951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne addPackageToCheckerGroup(packages[i], DI->getDef(), recordGroupMap); 17051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 17151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne typedef std::map<std::string, const Record *> SortedRecords; 17251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne typedef llvm::DenseMap<const Record *, unsigned> RecToSortIndex; 17351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 17451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne SortedRecords sortedGroups; 17551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne RecToSortIndex groupToSortIndex; 17651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "\n#ifdef GET_GROUPS\n"; 17751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne { 17851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0, e = checkerGroups.size(); i != e; ++i) 17951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne sortedGroups[checkerGroups[i]->getValueAsString("GroupName")] 18051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne = checkerGroups[i]; 18151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 18251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne unsigned sortIndex = 0; 18351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (SortedRecords::iterator 18451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne I = sortedGroups.begin(), E = sortedGroups.end(); I != E; ++I) { 18551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne const Record *R = I->second; 18651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 18751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "GROUP(" << "\""; 18851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS.write_escaped(R->getValueAsString("GroupName")) << "\""; 18951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << ")\n"; 19051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 19151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne groupToSortIndex[R] = sortIndex++; 19251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 19351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 19451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#endif // GET_GROUPS\n\n"; 19551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 19651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "\n#ifdef GET_PACKAGES\n"; 19751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne { 19851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne SortedRecords sortedPackages; 19951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0, e = packages.size(); i != e; ++i) 20051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne sortedPackages[getPackageFullName(packages[i])] = packages[i]; 20151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 20251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (SortedRecords::iterator 20351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne I = sortedPackages.begin(), E = sortedPackages.end(); I != E; ++I) { 20451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne const Record &R = *I->second; 20551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 20651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "PACKAGE(" << "\""; 20751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS.write_escaped(getPackageFullName(&R)) << "\", "; 20851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Group index 2091ab46323089f9a836a510521aab55ff958b67150Sean Silva if (DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group"))) 21051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << groupToSortIndex[DI->getDef()] << ", "; 21151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else 21251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "-1, "; 21351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Hidden bit 21451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (isHidden(R)) 21551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "true"; 21651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else 21751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "false"; 21851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << ")\n"; 21951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 22051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 22151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#endif // GET_PACKAGES\n\n"; 22251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 22351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "\n#ifdef GET_CHECKERS\n"; 22451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0, e = checkers.size(); i != e; ++i) { 22551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne const Record &R = *checkers[i]; 22651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 22751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "CHECKER(" << "\""; 22851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string name; 22951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (isCheckerNamed(&R)) 23051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne name = getCheckerFullName(&R); 23151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS.write_escaped(name) << "\", "; 23251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << R.getName() << ", "; 23351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << getStringValue(R, "DescFile") << ", "; 23451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "\""; 23551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS.write_escaped(getStringValue(R, "HelpText")) << "\", "; 23651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Group index 2371ab46323089f9a836a510521aab55ff958b67150Sean Silva if (DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group"))) 23851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << groupToSortIndex[DI->getDef()] << ", "; 23951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else 24051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "-1, "; 24151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Hidden bit 24251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (isHidden(R)) 24351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "true"; 24451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else 24551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "false"; 24651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << ")\n"; 24751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 24851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#endif // GET_CHECKERS\n\n"; 24951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 25051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne unsigned index = 0; 25151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (std::map<std::string, GroupInfo>::iterator 25251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I) 25351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne I->second.Index = index++; 25451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 25551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Walk through the packages/groups/checkers emitting an array for each 25651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // set of checkers and an array for each set of subpackages. 25751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 25851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "\n#ifdef GET_MEMBER_ARRAYS\n"; 25951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne unsigned maxLen = 0; 26051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (std::map<std::string, GroupInfo>::iterator 26151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I) { 26251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne maxLen = std::max(maxLen, (unsigned)I->first.size()); 26351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 26451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne llvm::DenseSet<const Record *> &checkers = I->second.Checkers; 26551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (!checkers.empty()) { 26651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "static const short CheckerArray" << I->second.Index << "[] = { "; 26751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Make the output order deterministic. 26851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::map<int, const Record *> sorted; 26951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (llvm::DenseSet<const Record *>::iterator 27051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne I = checkers.begin(), E = checkers.end(); I != E; ++I) 27151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne sorted[(*I)->getID()] = *I; 27251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 27351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (std::map<int, const Record *>::iterator 27451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne I = sorted.begin(), E = sorted.end(); I != E; ++I) 27551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << checkerRecIndexMap[I->second] << ", "; 27651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "-1 };\n"; 27751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 27851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 27951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne llvm::DenseSet<const Record *> &subGroups = I->second.SubGroups; 28051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (!subGroups.empty()) { 28151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "static const short SubPackageArray" << I->second.Index << "[] = { "; 28251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Make the output order deterministic. 28351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::map<int, const Record *> sorted; 28451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (llvm::DenseSet<const Record *>::iterator 28551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne I = subGroups.begin(), E = subGroups.end(); I != E; ++I) 28651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne sorted[(*I)->getID()] = *I; 28751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 28851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (std::map<int, const Record *>::iterator 28951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne I = sorted.begin(), E = sorted.end(); I != E; ++I) { 29051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << recordGroupMap[I->second]->Index << ", "; 29151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 29251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "-1 };\n"; 29351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 29451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 29551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#endif // GET_MEMBER_ARRAYS\n\n"; 29651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 29751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "\n#ifdef GET_CHECKNAME_TABLE\n"; 29851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (std::map<std::string, GroupInfo>::iterator 29951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I) { 30051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Group option string. 30151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " { \""; 30251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS.write_escaped(I->first) << "\"," 30351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << std::string(maxLen-I->first.size()+1, ' '); 30451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 30551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (I->second.Checkers.empty()) 30651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "0, "; 30751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else 30851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "CheckerArray" << I->second.Index << ", "; 30951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 31051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Subgroups. 31151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (I->second.SubGroups.empty()) 31251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "0, "; 31351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else 31451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "SubPackageArray" << I->second.Index << ", "; 31551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 31651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << (I->second.Hidden ? "true" : "false"); 31751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 31851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " },\n"; 31951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 32051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#endif // GET_CHECKNAME_TABLE\n\n"; 32151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 3223cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen} // end namespace clang 323