void EmitClangDiagGroups(RecordKeeper &Records, raw_ostream &OS) { // Compute a mapping from a DiagGroup to all of its parents. DiagGroupParentMap DGParentMap(Records); std::vector<Record *> Diags = Records.getAllDerivedDefinitions("Diagnostic"); std::vector<Record *> DiagGroups = Records.getAllDerivedDefinitions("DiagGroup"); std::map<std::string, GroupInfo> DiagsInGroup; groupDiagnostics(Diags, DiagGroups, DiagsInGroup); // All extensions are implicitly in the "pedantic" group. Record the // implicit set of groups in the "pedantic" group, and use this information // later when emitting the group information for Pedantic. RecordVec DiagsInPedantic; RecordVec GroupsInPedantic; InferPedantic inferPedantic(DGParentMap, Diags, DiagGroups, DiagsInGroup); inferPedantic.compute(&DiagsInPedantic, &GroupsInPedantic); StringToOffsetTable GroupNames; for (std::map<std::string, GroupInfo>::const_iterator I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) { // Store a pascal-style length byte at the beginning of the string. std::string Name = char(I->first.size()) + I->first; GroupNames.GetOrAddStringOffset(Name, false); } emitAllDiagArrays(DiagsInGroup, DiagsInPedantic, GroupsInPedantic, GroupNames, OS); emitDiagTable(DiagsInGroup, DiagsInPedantic, GroupsInPedantic, GroupNames, OS); emitCategoryTable(Records, OS); }
void EmitClangDiagGroups(RecordKeeper &Records, raw_ostream &OS) { // Compute a mapping from a DiagGroup to all of its parents. DiagGroupParentMap DGParentMap(Records); std::vector<Record*> Diags = Records.getAllDerivedDefinitions("Diagnostic"); std::vector<Record*> DiagGroups = Records.getAllDerivedDefinitions("DiagGroup"); std::map<std::string, GroupInfo> DiagsInGroup; groupDiagnostics(Diags, DiagGroups, DiagsInGroup); // All extensions are implicitly in the "pedantic" group. Record the // implicit set of groups in the "pedantic" group, and use this information // later when emitting the group information for Pedantic. RecordVec DiagsInPedantic; RecordVec GroupsInPedantic; InferPedantic inferPedantic(DGParentMap, Diags, DiagGroups, DiagsInGroup); inferPedantic.compute(&DiagsInPedantic, &GroupsInPedantic); // Walk through the groups emitting an array for each diagnostic of the diags // that are mapped to. OS << "\n#ifdef GET_DIAG_ARRAYS\n"; unsigned MaxLen = 0; for (std::map<std::string, GroupInfo>::iterator I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) { MaxLen = std::max(MaxLen, (unsigned)I->first.size()); const bool IsPedantic = I->first == "pedantic"; std::vector<const Record*> &V = I->second.DiagsInGroup; if (!V.empty() || (IsPedantic && !DiagsInPedantic.empty())) { OS << "static const short DiagArray" << I->second.IDNo << "[] = { "; for (unsigned i = 0, e = V.size(); i != e; ++i) OS << "diag::" << V[i]->getName() << ", "; // Emit the diagnostics implicitly in "pedantic". if (IsPedantic) { for (unsigned i = 0, e = DiagsInPedantic.size(); i != e; ++i) OS << "diag::" << DiagsInPedantic[i]->getName() << ", "; } OS << "-1 };\n"; } const std::vector<std::string> &SubGroups = I->second.SubGroups; if (!SubGroups.empty() || (IsPedantic && !GroupsInPedantic.empty())) { OS << "static const short DiagSubGroup" << I->second.IDNo << "[] = { "; for (unsigned i = 0, e = SubGroups.size(); i != e; ++i) { std::map<std::string, GroupInfo>::iterator RI = DiagsInGroup.find(SubGroups[i]); assert(RI != DiagsInGroup.end() && "Referenced without existing?"); OS << RI->second.IDNo << ", "; } // Emit the groups implicitly in "pedantic". if (IsPedantic) { for (unsigned i = 0, e = GroupsInPedantic.size(); i != e; ++i) { const std::string &GroupName = GroupsInPedantic[i]->getValueAsString("GroupName"); std::map<std::string, GroupInfo>::iterator RI = DiagsInGroup.find(GroupName); assert(RI != DiagsInGroup.end() && "Referenced without existing?"); OS << RI->second.IDNo << ", "; } } OS << "-1 };\n"; } } OS << "#endif // GET_DIAG_ARRAYS\n\n"; // Emit the table now. OS << "\n#ifdef GET_DIAG_TABLE\n"; for (std::map<std::string, GroupInfo>::iterator I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) { // Group option string. OS << " { "; OS << I->first.size() << ", "; OS << "\""; if (I->first.find_first_not_of("abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789!@#$%^*-+=:?")!=std::string::npos) PrintFatalError("Invalid character in diagnostic group '" + I->first + "'"); OS.write_escaped(I->first) << "\"," << std::string(MaxLen-I->first.size()+1, ' '); // Special handling for 'pedantic'. const bool IsPedantic = I->first == "pedantic"; // Diagnostics in the group. const bool hasDiags = !I->second.DiagsInGroup.empty() || (IsPedantic && !DiagsInPedantic.empty()); if (!hasDiags) OS << "0, "; else OS << "DiagArray" << I->second.IDNo << ", "; // Subgroups. const bool hasSubGroups = !I->second.SubGroups.empty() || (IsPedantic && !GroupsInPedantic.empty()); if (!hasSubGroups) OS << 0; else OS << "DiagSubGroup" << I->second.IDNo; OS << " },\n"; } OS << "#endif // GET_DIAG_TABLE\n\n"; // Emit the category table next. DiagCategoryIDMap CategoriesByID(Records); OS << "\n#ifdef GET_CATEGORY_TABLE\n"; for (DiagCategoryIDMap::iterator I = CategoriesByID.begin(), E = CategoriesByID.end(); I != E; ++I) OS << "CATEGORY(\"" << *I << "\", " << getDiagCategoryEnum(*I) << ")\n"; OS << "#endif // GET_CATEGORY_TABLE\n\n"; }
void EmitClangDiagsDefs(RecordKeeper &Records, raw_ostream &OS, const std::string &Component) { // Write the #if guard if (!Component.empty()) { std::string ComponentName = StringRef(Component).upper(); OS << "#ifdef " << ComponentName << "START\n"; OS << "__" << ComponentName << "START = DIAG_START_" << ComponentName << ",\n"; OS << "#undef " << ComponentName << "START\n"; OS << "#endif\n\n"; } const std::vector<Record*> &Diags = Records.getAllDerivedDefinitions("Diagnostic"); std::vector<Record*> DiagGroups = Records.getAllDerivedDefinitions("DiagGroup"); std::map<std::string, GroupInfo> DiagsInGroup; groupDiagnostics(Diags, DiagGroups, DiagsInGroup); DiagCategoryIDMap CategoryIDs(Records); DiagGroupParentMap DGParentMap(Records); // Compute the set of diagnostics that are in -Wpedantic. RecordSet DiagsInPedantic; InferPedantic inferPedantic(DGParentMap, Diags, DiagGroups, DiagsInGroup); inferPedantic.compute(&DiagsInPedantic, (RecordVec*)nullptr); for (unsigned i = 0, e = Diags.size(); i != e; ++i) { const Record &R = *Diags[i]; // Check if this is an error that is accidentally in a warning // group. if (isError(R)) { if (DefInit *Group = dyn_cast<DefInit>(R.getValueInit("Group"))) { const Record *GroupRec = Group->getDef(); const std::string &GroupName = GroupRec->getValueAsString("GroupName"); PrintFatalError(R.getLoc(), "Error " + R.getName() + " cannot be in a warning group [" + GroupName + "]"); } } // Check that all remarks have an associated diagnostic group. if (isRemark(R)) { if (!isa<DefInit>(R.getValueInit("Group"))) { PrintFatalError(R.getLoc(), "Error " + R.getName() + " not in any diagnostic group"); } } // Filter by component. if (!Component.empty() && Component != R.getValueAsString("Component")) continue; OS << "DIAG(" << R.getName() << ", "; OS << R.getValueAsDef("Class")->getName(); OS << ", diag::" << R.getValueAsDef("DefaultMapping")->getName(); // Description string. OS << ", \""; OS.write_escaped(R.getValueAsString("Text")) << '"'; // Warning associated with the diagnostic. This is stored as an index into // the alphabetically sorted warning table. if (DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group"))) { std::map<std::string, GroupInfo>::iterator I = DiagsInGroup.find(DI->getDef()->getValueAsString("GroupName")); assert(I != DiagsInGroup.end()); OS << ", " << I->second.IDNo; } else if (DiagsInPedantic.count(&R)) { std::map<std::string, GroupInfo>::iterator I = DiagsInGroup.find("pedantic"); assert(I != DiagsInGroup.end() && "pedantic group not defined"); OS << ", " << I->second.IDNo; } else { OS << ", 0"; } // SFINAE response. OS << ", " << R.getValueAsDef("SFINAE")->getName(); // Default warning has no Werror bit. if (R.getValueAsBit("WarningNoWerror")) OS << ", true"; else OS << ", false"; // Default warning show in system header bit. if (R.getValueAsBit("WarningShowInSystemHeader")) OS << ", true"; else OS << ", false"; // Category number. OS << ", " << CategoryIDs.getID(getDiagnosticCategory(&R, DGParentMap)); OS << ")\n"; } }
void EmitClangDiagsDefs(RecordKeeper &Records, raw_ostream &OS, const std::string &Component) { // Write the #if guard if (!Component.empty()) { std::string ComponentName = StringRef(Component).upper(); OS << "#ifdef " << ComponentName << "START\n"; OS << "__" << ComponentName << "START = DIAG_START_" << ComponentName << ",\n"; OS << "#undef " << ComponentName << "START\n"; OS << "#endif\n\n"; } const std::vector<Record*> &Diags = Records.getAllDerivedDefinitions("Diagnostic"); std::vector<Record*> DiagGroups = Records.getAllDerivedDefinitions("DiagGroup"); std::map<std::string, GroupInfo> DiagsInGroup; groupDiagnostics(Diags, DiagGroups, DiagsInGroup); DiagCategoryIDMap CategoryIDs(Records); DiagGroupParentMap DGParentMap(Records); // Compute the set of diagnostics that are in -Wpedantic. RecordSet DiagsInPedantic; InferPedantic inferPedantic(DGParentMap, Diags, DiagGroups, DiagsInGroup); inferPedantic.compute(&DiagsInPedantic, (RecordVec*)0); for (unsigned i = 0, e = Diags.size(); i != e; ++i) { const Record &R = *Diags[i]; // Filter by component. if (!Component.empty() && Component != R.getValueAsString("Component")) continue; OS << "DIAG(" << R.getName() << ", "; OS << R.getValueAsDef("Class")->getName(); OS << ", diag::" << R.getValueAsDef("DefaultMapping")->getName(); // Description string. OS << ", \""; OS.write_escaped(R.getValueAsString("Text")) << '"'; // Warning associated with the diagnostic. This is stored as an index into // the alphabetically sorted warning table. if (DefInit *DI = dynamic_cast<DefInit*>(R.getValueInit("Group"))) { std::map<std::string, GroupInfo>::iterator I = DiagsInGroup.find(DI->getDef()->getValueAsString("GroupName")); assert(I != DiagsInGroup.end()); OS << ", " << I->second.IDNo; } else if (DiagsInPedantic.count(&R)) { std::map<std::string, GroupInfo>::iterator I = DiagsInGroup.find("pedantic"); assert(I != DiagsInGroup.end() && "pedantic group not defined"); OS << ", " << I->second.IDNo; } else { OS << ", 0"; } // SFINAE bit if (R.getValueAsBit("SFINAE")) OS << ", true"; else OS << ", false"; // Access control bit if (R.getValueAsBit("AccessControl")) OS << ", true"; else OS << ", false"; // FIXME: This condition is just to avoid temporary revlock, it can be // removed. if (R.getValue("WarningNoWerror")) { // Default warning has no Werror bit. if (R.getValueAsBit("WarningNoWerror")) OS << ", true"; else OS << ", false"; // Default warning show in system header bit. if (R.getValueAsBit("WarningShowInSystemHeader")) OS << ", true"; else OS << ", false"; } // Category number. OS << ", " << CategoryIDs.getID(getDiagnosticCategory(&R, DGParentMap)); OS << ")\n"; } }