151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne//=- ClangDiagnosticsEmitter.cpp - Generate Clang diagnostics 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// These tablegen backends emit Clang diagnostics tables. 1151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// 1251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne//===----------------------------------------------------------------------===// 1351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 14e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek#include "llvm/ADT/PointerUnion.h" 1551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne#include "llvm/ADT/DenseSet.h" 1651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne#include "llvm/ADT/SmallString.h" 173cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen#include "llvm/ADT/StringMap.h" 18e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek#include "llvm/ADT/Optional.h" 193cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen#include "llvm/Support/Compiler.h" 203cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen#include "llvm/Support/Debug.h" 213cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen#include "llvm/TableGen/Record.h" 223cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen#include "llvm/TableGen/TableGenBackend.h" 2351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne#include <algorithm> 247094dee95f8c915d27097ac18b47d1ef31fd72edJoerg Sonnenberger#include <cctype> 2551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne#include <functional> 263cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen#include <map> 27d49cb20288b2dbc222aaf5673c1a4738c151b7bfBenjamin Kramer#include <set> 2851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourneusing namespace llvm; 2951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 3051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne//===----------------------------------------------------------------------===// 3151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// Diagnostic category computation code. 3251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne//===----------------------------------------------------------------------===// 3351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 3451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournenamespace { 3551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourneclass DiagGroupParentMap { 3651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne RecordKeeper &Records; 3751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::map<const Record*, std::vector<Record*> > Mapping; 3851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournepublic: 3951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne DiagGroupParentMap(RecordKeeper &records) : Records(records) { 4051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Record*> DiagGroups 4151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne = Records.getAllDerivedDefinitions("DiagGroup"); 4251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0, e = DiagGroups.size(); i != e; ++i) { 4351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Record*> SubGroups = 4451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne DiagGroups[i]->getValueAsListOfDefs("SubGroups"); 4551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned j = 0, e = SubGroups.size(); j != e; ++j) 4651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Mapping[SubGroups[j]].push_back(DiagGroups[i]); 4751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 4851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 4951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 5051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne const std::vector<Record*> &getParents(const Record *Group) { 5151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return Mapping[Group]; 5251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 5351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne}; 5451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} // end anonymous namespace. 5551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 5651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic std::string 5751d7777a21b9706d503496c650af06f80d278c1aPeter CollingbournegetCategoryFromDiagGroup(const Record *Group, 5851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne DiagGroupParentMap &DiagGroupParents) { 5951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // If the DiagGroup has a category, return it. 6051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string CatName = Group->getValueAsString("CategoryName"); 6151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (!CatName.empty()) return CatName; 6251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 6351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // The diag group may the subgroup of one or more other diagnostic groups, 6451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // check these for a category as well. 6551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne const std::vector<Record*> &Parents = DiagGroupParents.getParents(Group); 6651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0, e = Parents.size(); i != e; ++i) { 6751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne CatName = getCategoryFromDiagGroup(Parents[i], DiagGroupParents); 6851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (!CatName.empty()) return CatName; 6951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 7051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return ""; 7151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 7251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 7351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// getDiagnosticCategory - Return the category that the specified diagnostic 7451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// lives in. 7551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic std::string getDiagnosticCategory(const Record *R, 7651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne DiagGroupParentMap &DiagGroupParents) { 7751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // If the diagnostic is in a group, and that group has a category, use it. 7851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (DefInit *Group = dynamic_cast<DefInit*>(R->getValueInit("Group"))) { 7951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Check the diagnostic's diag group for a category. 8051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string CatName = getCategoryFromDiagGroup(Group->getDef(), 8151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne DiagGroupParents); 8251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (!CatName.empty()) return CatName; 8351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 84e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 8551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // If the diagnostic itself has a category, get it. 8651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return R->getValueAsString("CategoryName"); 8751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 8851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 8951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournenamespace { 9051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne class DiagCategoryIDMap { 9151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne RecordKeeper &Records; 9251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne StringMap<unsigned> CategoryIDs; 9351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<std::string> CategoryStrings; 9451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne public: 9551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne DiagCategoryIDMap(RecordKeeper &records) : Records(records) { 9651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne DiagGroupParentMap ParentInfo(Records); 9751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 9851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // The zero'th category is "". 9951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne CategoryStrings.push_back(""); 10051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne CategoryIDs[""] = 0; 10151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 10251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Record*> Diags = 10351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Records.getAllDerivedDefinitions("Diagnostic"); 10451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0, e = Diags.size(); i != e; ++i) { 10551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string Category = getDiagnosticCategory(Diags[i], ParentInfo); 10651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (Category.empty()) continue; // Skip diags with no category. 10751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 10851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne unsigned &ID = CategoryIDs[Category]; 10951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (ID != 0) continue; // Already seen. 11051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 11151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ID = CategoryStrings.size(); 11251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne CategoryStrings.push_back(Category); 11351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 11451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 11551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 11651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne unsigned getID(StringRef CategoryString) { 11751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return CategoryIDs[CategoryString]; 11851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 11951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 12051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne typedef std::vector<std::string>::iterator iterator; 12151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne iterator begin() { return CategoryStrings.begin(); } 12251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne iterator end() { return CategoryStrings.end(); } 12351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne }; 124d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis 125d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis struct GroupInfo { 126d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis std::vector<const Record*> DiagsInGroup; 127d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis std::vector<std::string> SubGroups; 128d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis unsigned IDNo; 129d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis }; 13051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} // end anonymous namespace. 13151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 132d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis/// \brief Invert the 1-[0/1] mapping of diags to group into a one to many 133d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis/// mapping of groups to diags in the group. 134d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidisstatic void groupDiagnostics(const std::vector<Record*> &Diags, 135d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis const std::vector<Record*> &DiagGroups, 136d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis std::map<std::string, GroupInfo> &DiagsInGroup) { 137d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis for (unsigned i = 0, e = Diags.size(); i != e; ++i) { 138d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis const Record *R = Diags[i]; 139d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis DefInit *DI = dynamic_cast<DefInit*>(R->getValueInit("Group")); 140d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis if (DI == 0) continue; 14146484770fe264fba24f7a9f608a3b7c3342690aaRichard Smith assert(R->getValueAsDef("Class")->getName() != "CLASS_NOTE" && 14246484770fe264fba24f7a9f608a3b7c3342690aaRichard Smith "Note can't be in a DiagGroup"); 143d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis std::string GroupName = DI->getDef()->getValueAsString("GroupName"); 144d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis DiagsInGroup[GroupName].DiagsInGroup.push_back(R); 145d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis } 146d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis 147d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis // Add all DiagGroup's to the DiagsInGroup list to make sure we pick up empty 148d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis // groups (these are warnings that GCC supports that clang never produces). 149d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis for (unsigned i = 0, e = DiagGroups.size(); i != e; ++i) { 150d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis Record *Group = DiagGroups[i]; 151d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis GroupInfo &GI = DiagsInGroup[Group->getValueAsString("GroupName")]; 152d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis 153d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis std::vector<Record*> SubGroups = Group->getValueAsListOfDefs("SubGroups"); 154d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis for (unsigned j = 0, e = SubGroups.size(); j != e; ++j) 155d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis GI.SubGroups.push_back(SubGroups[j]->getValueAsString("GroupName")); 156d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis } 157d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis 158d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis // Assign unique ID numbers to the groups. 159d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis unsigned IDNo = 0; 160d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis for (std::map<std::string, GroupInfo>::iterator 161d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I, ++IDNo) 162d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis I->second.IDNo = IDNo; 163d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis} 16451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 16551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne//===----------------------------------------------------------------------===// 166e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek// Infer members of -Wpedantic. 167e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek//===----------------------------------------------------------------------===// 168e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 169e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenektypedef std::vector<const Record *> RecordVec; 170e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenektypedef llvm::DenseSet<const Record *> RecordSet; 171e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenektypedef llvm::PointerUnion<RecordVec*, RecordSet*> VecOrSet; 172e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 173e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremeneknamespace { 174e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenekclass InferPedantic { 175e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek typedef llvm::DenseMap<const Record*, 176e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek std::pair<unsigned, llvm::Optional<unsigned> > > GMap; 177e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 178e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek DiagGroupParentMap &DiagGroupParents; 179e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek const std::vector<Record*> &Diags; 180e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek const std::vector<Record*> DiagGroups; 181e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek std::map<std::string, GroupInfo> &DiagsInGroup; 182e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek llvm::DenseSet<const Record*> DiagsSet; 183e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek GMap GroupCount; 184e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenekpublic: 185e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek InferPedantic(DiagGroupParentMap &DiagGroupParents, 186e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek const std::vector<Record*> &Diags, 187e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek const std::vector<Record*> &DiagGroups, 188e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek std::map<std::string, GroupInfo> &DiagsInGroup) 189e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek : DiagGroupParents(DiagGroupParents), 190e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek Diags(Diags), 191e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek DiagGroups(DiagGroups), 192e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek DiagsInGroup(DiagsInGroup) {} 193e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 194e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek /// Compute the set of diagnostics and groups that are immediately 195e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek /// in -Wpedantic. 196e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek void compute(VecOrSet DiagsInPedantic, 197e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek VecOrSet GroupsInPedantic); 198e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 199e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenekprivate: 200e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek /// Determine whether a group is a subgroup of another group. 201e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek bool isSubGroupOfGroup(const Record *Group, 202e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek llvm::StringRef RootGroupName); 203e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 204e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek /// Determine if the diagnostic is an extension. 205e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek bool isExtension(const Record *Diag); 206e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 207bb5185c0ca3de4e7d91d011a83c902d7b02a2a1aTed Kremenek /// Determine if the diagnostic is off by default. 208bb5185c0ca3de4e7d91d011a83c902d7b02a2a1aTed Kremenek bool isOffByDefault(const Record *Diag); 209bb5185c0ca3de4e7d91d011a83c902d7b02a2a1aTed Kremenek 210e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek /// Increment the count for a group, and transitively marked 211e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek /// parent groups when appropriate. 212e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek void markGroup(const Record *Group); 213e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 214e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek /// Return true if the diagnostic is in a pedantic group. 215e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek bool groupInPedantic(const Record *Group, bool increment = false); 216e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek}; 217e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek} // end anonymous namespace 218e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 219e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenekbool InferPedantic::isSubGroupOfGroup(const Record *Group, 220e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek llvm::StringRef GName) { 221e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 222e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek const std::string &GroupName = Group->getValueAsString("GroupName"); 223e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek if (GName == GroupName) 224e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek return true; 225e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 226e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek const std::vector<Record*> &Parents = DiagGroupParents.getParents(Group); 227e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek for (unsigned i = 0, e = Parents.size(); i != e; ++i) 228e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek if (isSubGroupOfGroup(Parents[i], GName)) 229e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek return true; 230e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 231e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek return false; 232e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek} 233e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 234e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek/// Determine if the diagnostic is an extension. 235e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenekbool InferPedantic::isExtension(const Record *Diag) { 236e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek const std::string &ClsName = Diag->getValueAsDef("Class")->getName(); 237e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek return ClsName == "CLASS_EXTENSION"; 238e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek} 239e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 240bb5185c0ca3de4e7d91d011a83c902d7b02a2a1aTed Kremenekbool InferPedantic::isOffByDefault(const Record *Diag) { 241bb5185c0ca3de4e7d91d011a83c902d7b02a2a1aTed Kremenek const std::string &DefMap = Diag->getValueAsDef("DefaultMapping")->getName(); 242bb5185c0ca3de4e7d91d011a83c902d7b02a2a1aTed Kremenek return DefMap == "MAP_IGNORE"; 243bb5185c0ca3de4e7d91d011a83c902d7b02a2a1aTed Kremenek} 244bb5185c0ca3de4e7d91d011a83c902d7b02a2a1aTed Kremenek 245e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenekbool InferPedantic::groupInPedantic(const Record *Group, bool increment) { 246e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek GMap::mapped_type &V = GroupCount[Group]; 247e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // Lazily compute the threshold value for the group count. 248e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek if (!V.second.hasValue()) { 249e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek const GroupInfo &GI = DiagsInGroup[Group->getValueAsString("GroupName")]; 250e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek V.second = GI.SubGroups.size() + GI.DiagsInGroup.size(); 251e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek } 252e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 253e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek if (increment) 254e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek ++V.first; 255e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 256e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // Consider a group in -Wpendatic IFF if has at least one diagnostic 257e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // or subgroup AND all of those diagnostics and subgroups are covered 258e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // by -Wpedantic via our computation. 259e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek return V.first != 0 && V.first == V.second.getValue(); 260e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek} 261e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 262e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenekvoid InferPedantic::markGroup(const Record *Group) { 263e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // If all the diagnostics and subgroups have been marked as being 264e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // covered by -Wpedantic, increment the count of parent groups. Once the 265e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // group's count is equal to the number of subgroups and diagnostics in 266e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // that group, we can safely add this group to -Wpedantic. 267e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek if (groupInPedantic(Group, /* increment */ true)) { 268e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek const std::vector<Record*> &Parents = DiagGroupParents.getParents(Group); 269e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek for (unsigned i = 0, e = Parents.size(); i != e; ++i) 270e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek markGroup(Parents[i]); 271e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek } 272e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek} 273e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 274e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenekvoid InferPedantic::compute(VecOrSet DiagsInPedantic, 275e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek VecOrSet GroupsInPedantic) { 276bb5185c0ca3de4e7d91d011a83c902d7b02a2a1aTed Kremenek // All extensions that are not on by default are implicitly in the 277bb5185c0ca3de4e7d91d011a83c902d7b02a2a1aTed Kremenek // "pedantic" group. For those that aren't explicitly included in -Wpedantic, 278bb5185c0ca3de4e7d91d011a83c902d7b02a2a1aTed Kremenek // mark them for consideration to be included in -Wpedantic directly. 279e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek for (unsigned i = 0, e = Diags.size(); i != e; ++i) { 280e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek Record *R = Diags[i]; 281bb5185c0ca3de4e7d91d011a83c902d7b02a2a1aTed Kremenek if (isExtension(R) && isOffByDefault(R)) { 282e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek DiagsSet.insert(R); 283e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek if (DefInit *Group = dynamic_cast<DefInit*>(R->getValueInit("Group"))) { 284e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek const Record *GroupRec = Group->getDef(); 285e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek if (!isSubGroupOfGroup(GroupRec, "pedantic")) { 286e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek markGroup(GroupRec); 287e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek } 288e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek } 289e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek } 290e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek } 291e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 292e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // Compute the set of diagnostics that are directly in -Wpedantic. We 293e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // march through Diags a second time to ensure the results are emitted 294e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // in deterministic order. 295e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek for (unsigned i = 0, e = Diags.size(); i != e; ++i) { 296e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek Record *R = Diags[i]; 297e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek if (!DiagsSet.count(R)) 298e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek continue; 299e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // Check if the group is implicitly in -Wpedantic. If so, 300e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // the diagnostic should not be directly included in the -Wpedantic 301e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // diagnostic group. 302e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek if (DefInit *Group = dynamic_cast<DefInit*>(R->getValueInit("Group"))) 303e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek if (groupInPedantic(Group->getDef())) 304e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek continue; 305e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 306e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // The diagnostic is not included in a group that is (transitively) in 307e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // -Wpedantic. Include it in -Wpedantic directly. 308e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek if (RecordVec *V = DiagsInPedantic.dyn_cast<RecordVec*>()) 309e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek V->push_back(R); 310e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek else { 311e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek DiagsInPedantic.get<RecordSet*>()->insert(R); 312e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek } 313e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek } 314e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 315e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek if (!GroupsInPedantic) 316e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek return; 317e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 318e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // Compute the set of groups that are directly in -Wpedantic. We 319e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // march through the groups to ensure the results are emitted 320e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek /// in a deterministc order. 321e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek for (unsigned i = 0, ei = DiagGroups.size(); i != ei; ++i) { 322e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek Record *Group = DiagGroups[i]; 323e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek if (!groupInPedantic(Group)) 324e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek continue; 325e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 326e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek unsigned ParentsInPedantic = 0; 327e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek const std::vector<Record*> &Parents = DiagGroupParents.getParents(Group); 328e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek for (unsigned j = 0, ej = Parents.size(); j != ej; ++j) { 329e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek if (groupInPedantic(Parents[j])) 330e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek ++ParentsInPedantic; 331e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek } 332e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // If all the parents are in -Wpedantic, this means that this diagnostic 333e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // group will be indirectly included by -Wpedantic already. In that 334e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // case, do not add it directly to -Wpedantic. If the group has no 335e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // parents, obviously it should go into -Wpedantic. 336e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek if (Parents.size() > 0 && ParentsInPedantic == Parents.size()) 337e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek continue; 338e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 339e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek if (RecordVec *V = GroupsInPedantic.dyn_cast<RecordVec*>()) 340e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek V->push_back(Group); 341e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek else { 342e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek GroupsInPedantic.get<RecordSet*>()->insert(Group); 343e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek } 344e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek } 345e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek} 346e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 347e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek//===----------------------------------------------------------------------===// 34851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// Warning Tables (.inc file) generation. 34951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne//===----------------------------------------------------------------------===// 35051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 3514a535368eb4fca10b05c442e04725747dbf76081Ted Kremenekstatic bool isError(const Record &Diag) { 3524a535368eb4fca10b05c442e04725747dbf76081Ted Kremenek const std::string &ClsName = Diag.getValueAsDef("Class")->getName(); 3534a535368eb4fca10b05c442e04725747dbf76081Ted Kremenek return ClsName == "CLASS_ERROR"; 3544a535368eb4fca10b05c442e04725747dbf76081Ted Kremenek} 3554a535368eb4fca10b05c442e04725747dbf76081Ted Kremenek 3563cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen/// ClangDiagsDefsEmitter - The top-level class emits .def files containing 3573cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen/// declarations of Clang diagnostics. 3583cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesennamespace clang { 3593cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenvoid EmitClangDiagsDefs(RecordKeeper &Records, raw_ostream &OS, 3603cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen const std::string &Component) { 36151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Write the #if guard 36251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (!Component.empty()) { 36390c7892b699c5405a81bcc339432ba2f4b50e0d6Benjamin Kramer std::string ComponentName = StringRef(Component).upper(); 36451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#ifdef " << ComponentName << "START\n"; 36551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "__" << ComponentName << "START = DIAG_START_" << ComponentName 36651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << ",\n"; 36751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#undef " << ComponentName << "START\n"; 36851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#endif\n\n"; 36951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 37051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 37151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne const std::vector<Record*> &Diags = 37251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Records.getAllDerivedDefinitions("Diagnostic"); 373d49cb20288b2dbc222aaf5673c1a4738c151b7bfBenjamin Kramer 374d49cb20288b2dbc222aaf5673c1a4738c151b7bfBenjamin Kramer std::vector<Record*> DiagGroups 375d49cb20288b2dbc222aaf5673c1a4738c151b7bfBenjamin Kramer = Records.getAllDerivedDefinitions("DiagGroup"); 376d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis 377d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis std::map<std::string, GroupInfo> DiagsInGroup; 378d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis groupDiagnostics(Diags, DiagGroups, DiagsInGroup); 379d49cb20288b2dbc222aaf5673c1a4738c151b7bfBenjamin Kramer 38051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne DiagCategoryIDMap CategoryIDs(Records); 38151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne DiagGroupParentMap DGParentMap(Records); 38251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 383e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // Compute the set of diagnostics that are in -Wpedantic. 384e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek RecordSet DiagsInPedantic; 385e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek InferPedantic inferPedantic(DGParentMap, Diags, DiagGroups, DiagsInGroup); 386e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek inferPedantic.compute(&DiagsInPedantic, (RecordVec*)0); 387e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 38851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0, e = Diags.size(); i != e; ++i) { 38951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne const Record &R = *Diags[i]; 3904a535368eb4fca10b05c442e04725747dbf76081Ted Kremenek 3914a535368eb4fca10b05c442e04725747dbf76081Ted Kremenek // Check if this is an error that is accidentally in a warning 3924a535368eb4fca10b05c442e04725747dbf76081Ted Kremenek // group. 3934a535368eb4fca10b05c442e04725747dbf76081Ted Kremenek if (isError(R)) { 3944a535368eb4fca10b05c442e04725747dbf76081Ted Kremenek if (DefInit *Group = dynamic_cast<DefInit*>(R.getValueInit("Group"))) { 3954a535368eb4fca10b05c442e04725747dbf76081Ted Kremenek const Record *GroupRec = Group->getDef(); 3964a535368eb4fca10b05c442e04725747dbf76081Ted Kremenek const std::string &GroupName = GroupRec->getValueAsString("GroupName"); 3974a535368eb4fca10b05c442e04725747dbf76081Ted Kremenek throw "Error " + R.getName() + " cannot be in a warning group [" + 3984a535368eb4fca10b05c442e04725747dbf76081Ted Kremenek GroupName + "]"; 3994a535368eb4fca10b05c442e04725747dbf76081Ted Kremenek } 4004a535368eb4fca10b05c442e04725747dbf76081Ted Kremenek } 4014a535368eb4fca10b05c442e04725747dbf76081Ted Kremenek 40251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Filter by component. 40351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (!Component.empty() && Component != R.getValueAsString("Component")) 40451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne continue; 40551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 40651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "DIAG(" << R.getName() << ", "; 40751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << R.getValueAsDef("Class")->getName(); 40851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << ", diag::" << R.getValueAsDef("DefaultMapping")->getName(); 40951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 41051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Description string. 41151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << ", \""; 41251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS.write_escaped(R.getValueAsString("Text")) << '"'; 41351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 414d49cb20288b2dbc222aaf5673c1a4738c151b7bfBenjamin Kramer // Warning associated with the diagnostic. This is stored as an index into 415d49cb20288b2dbc222aaf5673c1a4738c151b7bfBenjamin Kramer // the alphabetically sorted warning table. 41651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (DefInit *DI = dynamic_cast<DefInit*>(R.getValueInit("Group"))) { 417d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis std::map<std::string, GroupInfo>::iterator I = 418d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis DiagsInGroup.find(DI->getDef()->getValueAsString("GroupName")); 419d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis assert(I != DiagsInGroup.end()); 420d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis OS << ", " << I->second.IDNo; 421e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek } else if (DiagsInPedantic.count(&R)) { 422e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek std::map<std::string, GroupInfo>::iterator I = 423e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek DiagsInGroup.find("pedantic"); 424e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek assert(I != DiagsInGroup.end() && "pedantic group not defined"); 425e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek OS << ", " << I->second.IDNo; 42651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } else { 427d49cb20288b2dbc222aaf5673c1a4738c151b7bfBenjamin Kramer OS << ", 0"; 42851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 42951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 43051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // SFINAE bit 43151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (R.getValueAsBit("SFINAE")) 43251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << ", true"; 43351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else 43451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << ", false"; 43551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 43651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Access control bit 43751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (R.getValueAsBit("AccessControl")) 43851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << ", true"; 43951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else 44051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << ", false"; 44151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 44251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // FIXME: This condition is just to avoid temporary revlock, it can be 44351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // removed. 44451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (R.getValue("WarningNoWerror")) { 44551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Default warning has no Werror bit. 44651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (R.getValueAsBit("WarningNoWerror")) 44751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << ", true"; 44851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else 44951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << ", false"; 45051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 45151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Default warning show in system header bit. 45251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (R.getValueAsBit("WarningShowInSystemHeader")) 45351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << ", true"; 45451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else 45551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << ", false"; 45651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 45751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 45851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Category number. 45951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << ", " << CategoryIDs.getID(getDiagnosticCategory(&R, DGParentMap)); 46051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << ")\n"; 46151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 46251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 4633cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen} // end namespace clang 46451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 46551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne//===----------------------------------------------------------------------===// 46651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// Warning Group Tables generation 46751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne//===----------------------------------------------------------------------===// 46851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 46951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic std::string getDiagCategoryEnum(llvm::StringRef name) { 47051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (name.empty()) 47151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return "DiagCat_None"; 47236d592718ff342f762e32cbde73d1113f88cb275Dylan Noblesmith SmallString<256> enumName = llvm::StringRef("DiagCat_"); 47351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (llvm::StringRef::iterator I = name.begin(), E = name.end(); I != E; ++I) 47451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne enumName += isalnum(*I) ? *I : '_'; 47551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return enumName.str(); 47651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 477e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 4783cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesennamespace clang { 4793cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenvoid EmitClangDiagGroups(RecordKeeper &Records, raw_ostream &OS) { 48051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Compute a mapping from a DiagGroup to all of its parents. 48151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne DiagGroupParentMap DGParentMap(Records); 482e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 48351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Record*> Diags = 48451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Records.getAllDerivedDefinitions("Diagnostic"); 48551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 48651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Record*> DiagGroups 48751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne = Records.getAllDerivedDefinitions("DiagGroup"); 488d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis 489d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis std::map<std::string, GroupInfo> DiagsInGroup; 490d42236e9d5aa8881bee103d923475daffc791f38Argyrios Kyrtzidis groupDiagnostics(Diags, DiagGroups, DiagsInGroup); 491e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 492e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // All extensions are implicitly in the "pedantic" group. Record the 493e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // implicit set of groups in the "pedantic" group, and use this information 494e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // later when emitting the group information for Pedantic. 495e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek RecordVec DiagsInPedantic; 496e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek RecordVec GroupsInPedantic; 497e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek InferPedantic inferPedantic(DGParentMap, Diags, DiagGroups, DiagsInGroup); 498e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek inferPedantic.compute(&DiagsInPedantic, &GroupsInPedantic); 499e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 50051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Walk through the groups emitting an array for each diagnostic of the diags 50151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // that are mapped to. 50251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "\n#ifdef GET_DIAG_ARRAYS\n"; 50351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne unsigned MaxLen = 0; 50451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (std::map<std::string, GroupInfo>::iterator 50551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) { 50651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne MaxLen = std::max(MaxLen, (unsigned)I->first.size()); 507e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek const bool IsPedantic = I->first == "pedantic"; 508e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 50951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<const Record*> &V = I->second.DiagsInGroup; 510e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek if (!V.empty() || (IsPedantic && !DiagsInPedantic.empty())) { 51151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "static const short DiagArray" << I->second.IDNo << "[] = { "; 51251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0, e = V.size(); i != e; ++i) 51351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "diag::" << V[i]->getName() << ", "; 514e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // Emit the diagnostics implicitly in "pedantic". 515e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek if (IsPedantic) { 516e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek for (unsigned i = 0, e = DiagsInPedantic.size(); i != e; ++i) 517e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek OS << "diag::" << DiagsInPedantic[i]->getName() << ", "; 518e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek } 51951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "-1 };\n"; 52051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 52151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 52251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne const std::vector<std::string> &SubGroups = I->second.SubGroups; 523e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek if (!SubGroups.empty() || (IsPedantic && !GroupsInPedantic.empty())) { 52451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "static const short DiagSubGroup" << I->second.IDNo << "[] = { "; 52551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0, e = SubGroups.size(); i != e; ++i) { 52651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::map<std::string, GroupInfo>::iterator RI = 52751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne DiagsInGroup.find(SubGroups[i]); 52851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne assert(RI != DiagsInGroup.end() && "Referenced without existing?"); 52951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << RI->second.IDNo << ", "; 53051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 531e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // Emit the groups implicitly in "pedantic". 532e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek if (IsPedantic) { 533e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek for (unsigned i = 0, e = GroupsInPedantic.size(); i != e; ++i) { 534e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek const std::string &GroupName = 535e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek GroupsInPedantic[i]->getValueAsString("GroupName"); 536e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek std::map<std::string, GroupInfo>::iterator RI = 537e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek DiagsInGroup.find(GroupName); 538e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek assert(RI != DiagsInGroup.end() && "Referenced without existing?"); 539e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek OS << RI->second.IDNo << ", "; 540e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek } 541e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek } 542e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 54351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "-1 };\n"; 54451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 54551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 54651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#endif // GET_DIAG_ARRAYS\n\n"; 54751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 54851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Emit the table now. 54951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "\n#ifdef GET_DIAG_TABLE\n"; 55051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (std::map<std::string, GroupInfo>::iterator 55151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) { 55251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Group option string. 55351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " { "; 55451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << I->first.size() << ", "; 55551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "\""; 556037ad1b8f00b80aa76e73e3118133e9a59fd177eBenjamin Kramer if (I->first.find_first_not_of("abcdefghijklmnopqrstuvwxyz" 557037ad1b8f00b80aa76e73e3118133e9a59fd177eBenjamin Kramer "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 558037ad1b8f00b80aa76e73e3118133e9a59fd177eBenjamin Kramer "0123456789!@#$%^*-+=:?")!=std::string::npos) 559037ad1b8f00b80aa76e73e3118133e9a59fd177eBenjamin Kramer throw "Invalid character in diagnostic group '" + I->first + "'"; 56051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS.write_escaped(I->first) << "\"," 56151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << std::string(MaxLen-I->first.size()+1, ' '); 562e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 563e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek // Special handling for 'pedantic'. 564e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek const bool IsPedantic = I->first == "pedantic"; 565e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek 56651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Diagnostics in the group. 567e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek const bool hasDiags = !I->second.DiagsInGroup.empty() || 568e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek (IsPedantic && !DiagsInPedantic.empty()); 569e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek if (!hasDiags) 57051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "0, "; 57151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else 57251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "DiagArray" << I->second.IDNo << ", "; 57351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 57451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Subgroups. 575e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek const bool hasSubGroups = !I->second.SubGroups.empty() || 576e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek (IsPedantic && !GroupsInPedantic.empty()); 577e8cf7d143446c45568bb7c9a6fbd8f32ca6ae93eTed Kremenek if (!hasSubGroups) 57851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << 0; 57951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else 58051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "DiagSubGroup" << I->second.IDNo; 58151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " },\n"; 58251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 58351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#endif // GET_DIAG_TABLE\n\n"; 58451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 58551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Emit the category table next. 58651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne DiagCategoryIDMap CategoriesByID(Records); 58751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "\n#ifdef GET_CATEGORY_TABLE\n"; 58851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (DiagCategoryIDMap::iterator I = CategoriesByID.begin(), 58951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne E = CategoriesByID.end(); I != E; ++I) 59051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "CATEGORY(\"" << *I << "\", " << getDiagCategoryEnum(*I) << ")\n"; 59151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#endif // GET_CATEGORY_TABLE\n\n"; 59251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 5933cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen} // end namespace clang 59451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 59551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne//===----------------------------------------------------------------------===// 59651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// Diagnostic name index generation 59751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne//===----------------------------------------------------------------------===// 59851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 59951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournenamespace { 60051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestruct RecordIndexElement 60151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne{ 60251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne RecordIndexElement() {} 60351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne explicit RecordIndexElement(Record const &R): 60451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Name(R.getName()) {} 60551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 60651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string Name; 60751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne}; 60851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 60951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestruct RecordIndexElementSorter : 61051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne public std::binary_function<RecordIndexElement, RecordIndexElement, bool> { 61151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 61251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool operator()(RecordIndexElement const &Lhs, 61351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne RecordIndexElement const &Rhs) const { 61451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return Lhs.Name < Rhs.Name; 61551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 61651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 61751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne}; 61851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 61951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} // end anonymous namespace. 62051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 6213cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesennamespace clang { 6223cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenvoid EmitClangDiagsIndexName(RecordKeeper &Records, raw_ostream &OS) { 62351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne const std::vector<Record*> &Diags = 62451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Records.getAllDerivedDefinitions("Diagnostic"); 62551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 62651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<RecordIndexElement> Index; 62751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Index.reserve(Diags.size()); 62851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0, e = Diags.size(); i != e; ++i) { 62951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne const Record &R = *(Diags[i]); 63051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Index.push_back(RecordIndexElement(R)); 63151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 63251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 63351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::sort(Index.begin(), Index.end(), RecordIndexElementSorter()); 63451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 63551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0, e = Index.size(); i != e; ++i) { 63651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne const RecordIndexElement &R = Index[i]; 63751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 63851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "DIAG_NAME_INDEX(" << R.Name << ")\n"; 63951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 64051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 6413cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen} // end namespace clang 642