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