Update Clang for 3.5 rebase (r209713).
Change-Id: I8c9133b0f8f776dc915f270b60f94962e771bc83
diff --git a/utils/TableGen/ClangDiagnosticsEmitter.cpp b/utils/TableGen/ClangDiagnosticsEmitter.cpp
index 40af9f6..b4cc706 100644
--- a/utils/TableGen/ClangDiagnosticsEmitter.cpp
+++ b/utils/TableGen/ClangDiagnosticsEmitter.cpp
@@ -135,7 +135,7 @@
const Record *ExplicitDef;
- GroupInfo() : ExplicitDef(0) {}
+ GroupInfo() : ExplicitDef(nullptr) {}
};
} // end anonymous namespace.
@@ -170,7 +170,8 @@
for (unsigned i = 0, e = Diags.size(); i != e; ++i) {
const Record *R = Diags[i];
DefInit *DI = dyn_cast<DefInit>(R->getValueInit("Group"));
- if (DI == 0) continue;
+ if (!DI)
+ continue;
assert(R->getValueAsDef("Class")->getName() != "CLASS_NOTE" &&
"Note can't be in a DiagGroup");
std::string GroupName = DI->getDef()->getValueAsString("GroupName");
@@ -507,7 +508,7 @@
// Compute the set of diagnostics that are in -Wpedantic.
RecordSet DiagsInPedantic;
InferPedantic inferPedantic(DGParentMap, Diags, DiagGroups, DiagsInGroup);
- inferPedantic.compute(&DiagsInPedantic, (RecordVec*)0);
+ inferPedantic.compute(&DiagsInPedantic, (RecordVec*)nullptr);
for (unsigned i = 0, e = Diags.size(); i != e; ++i) {
const Record &R = *Diags[i];
@@ -594,16 +595,240 @@
return enumName.str();
}
+/// \brief Emit the array of diagnostic subgroups.
+///
+/// The array of diagnostic subgroups contains for each group a list of its
+/// subgroups. The individual lists are separated by '-1'. Groups with no
+/// subgroups are skipped.
+///
+/// \code
+/// static const int16_t DiagSubGroups[] = {
+/// /* Empty */ -1,
+/// /* DiagSubGroup0 */ 142, -1,
+/// /* DiagSubGroup13 */ 265, 322, 399, -1
+/// }
+/// \endcode
+///
+static void emitDiagSubGroups(std::map<std::string, GroupInfo> &DiagsInGroup,
+ RecordVec &GroupsInPedantic, raw_ostream &OS) {
+ OS << "static const int16_t DiagSubGroups[] = {\n"
+ << " /* Empty */ -1,\n";
+ for (auto const &I : DiagsInGroup) {
+ const bool IsPedantic = I.first == "pedantic";
+
+ const std::vector<std::string> &SubGroups = I.second.SubGroups;
+ if (!SubGroups.empty() || (IsPedantic && !GroupsInPedantic.empty())) {
+ OS << " /* DiagSubGroup" << I.second.IDNo << " */ ";
+ for (auto const &SubGroup : SubGroups) {
+ std::map<std::string, GroupInfo>::const_iterator RI =
+ DiagsInGroup.find(SubGroup);
+ assert(RI != DiagsInGroup.end() && "Referenced without existing?");
+ OS << RI->second.IDNo << ", ";
+ }
+ // Emit the groups implicitly in "pedantic".
+ if (IsPedantic) {
+ for (auto const &Group : GroupsInPedantic) {
+ const std::string &GroupName = Group->getValueAsString("GroupName");
+ std::map<std::string, GroupInfo>::const_iterator RI =
+ DiagsInGroup.find(GroupName);
+ assert(RI != DiagsInGroup.end() && "Referenced without existing?");
+ OS << RI->second.IDNo << ", ";
+ }
+ }
+
+ OS << "-1,\n";
+ }
+ }
+ OS << "};\n\n";
+}
+
+/// \brief Emit the list of diagnostic arrays.
+///
+/// This data structure is a large array that contains itself arrays of varying
+/// size. Each array represents a list of diagnostics. The different arrays are
+/// separated by the value '-1'.
+///
+/// \code
+/// static const int16_t DiagArrays[] = {
+/// /* Empty */ -1,
+/// /* DiagArray1 */ diag::warn_pragma_message,
+/// -1,
+/// /* DiagArray2 */ diag::warn_abs_too_small,
+/// diag::warn_unsigned_abs,
+/// diag::warn_wrong_absolute_value_type,
+/// -1
+/// };
+/// \endcode
+///
+static void emitDiagArrays(std::map<std::string, GroupInfo> &DiagsInGroup,
+ RecordVec &DiagsInPedantic, raw_ostream &OS) {
+ OS << "static const int16_t DiagArrays[] = {\n"
+ << " /* Empty */ -1,\n";
+ for (auto const &I : DiagsInGroup) {
+ const bool IsPedantic = I.first == "pedantic";
+
+ const std::vector<const Record *> &V = I.second.DiagsInGroup;
+ if (!V.empty() || (IsPedantic && !DiagsInPedantic.empty())) {
+ OS << " /* DiagArray" << I.second.IDNo << " */ ";
+ for (auto *Record : V)
+ OS << "diag::" << Record->getName() << ", ";
+ // Emit the diagnostics implicitly in "pedantic".
+ if (IsPedantic) {
+ for (auto const &Diag : DiagsInPedantic)
+ OS << "diag::" << Diag->getName() << ", ";
+ }
+ OS << "-1,\n";
+ }
+ }
+ OS << "};\n\n";
+}
+
+/// \brief Emit a list of group names.
+///
+/// This creates a long string which by itself contains a list of pascal style
+/// strings, which consist of a length byte directly followed by the string.
+///
+/// \code
+/// static const char DiagGroupNames[] = {
+/// \000\020#pragma-messages\t#warnings\020CFString-literal"
+/// };
+/// \endcode
+static void emitDiagGroupNames(StringToOffsetTable &GroupNames,
+ raw_ostream &OS) {
+ OS << "static const char DiagGroupNames[] = {\n";
+ GroupNames.EmitString(OS);
+ OS << "};\n\n";
+}
+
+/// \brief Emit diagnostic arrays and related data structures.
+///
+/// This creates the actual diagnostic array, an array of diagnostic subgroups
+/// and an array of subgroup names.
+///
+/// \code
+/// #ifdef GET_DIAG_ARRAYS
+/// static const int16_t DiagArrays[];
+/// static const int16_t DiagSubGroups[];
+/// static const char DiagGroupNames[];
+/// #endif
+/// \endcode
+static void emitAllDiagArrays(std::map<std::string, GroupInfo> &DiagsInGroup,
+ RecordVec &DiagsInPedantic,
+ RecordVec &GroupsInPedantic,
+ StringToOffsetTable &GroupNames,
+ raw_ostream &OS) {
+ OS << "\n#ifdef GET_DIAG_ARRAYS\n";
+ emitDiagArrays(DiagsInGroup, DiagsInPedantic, OS);
+ emitDiagSubGroups(DiagsInGroup, GroupsInPedantic, OS);
+ emitDiagGroupNames(GroupNames, OS);
+ OS << "#endif // GET_DIAG_ARRAYS\n\n";
+}
+
+/// \brief Emit diagnostic table.
+///
+/// The table is sorted by the name of the diagnostic group. Each element
+/// consists of the name of the diagnostic group (given as offset in the
+/// group name table), a reference to a list of diagnostics (optional) and a
+/// reference to a set of subgroups (optional).
+///
+/// \code
+/// #ifdef GET_DIAG_TABLE
+/// {/* abi */ 159, /* DiagArray11 */ 19, /* Empty */ 0},
+/// {/* aggregate-return */ 180, /* Empty */ 0, /* Empty */ 0},
+/// {/* all */ 197, /* Empty */ 0, /* DiagSubGroup13 */ 3},
+/// {/* deprecated */ 1981,/* DiagArray1 */ 348, /* DiagSubGroup3 */ 9},
+/// #endif
+/// \endcode
+static void emitDiagTable(std::map<std::string, GroupInfo> &DiagsInGroup,
+ RecordVec &DiagsInPedantic,
+ RecordVec &GroupsInPedantic,
+ StringToOffsetTable &GroupNames, raw_ostream &OS) {
+ unsigned MaxLen = 0;
+
+ for (auto const &I: DiagsInGroup)
+ MaxLen = std::max(MaxLen, (unsigned)I.first.size());
+
+ OS << "\n#ifdef GET_DIAG_TABLE\n";
+ unsigned SubGroupIndex = 1, DiagArrayIndex = 1;
+ for (auto const &I: DiagsInGroup) {
+ // Group option string.
+ OS << " { /* ";
+ if (I.first.find_first_not_of("abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789!@#$%^*-+=:?") !=
+ std::string::npos)
+ PrintFatalError("Invalid character in diagnostic group '" + I.first +
+ "'");
+ OS << I.first << " */ " << std::string(MaxLen - I.first.size(), ' ');
+ // Store a pascal-style length byte at the beginning of the string.
+ std::string Name = char(I.first.size()) + I.first;
+ OS << GroupNames.GetOrAddStringOffset(Name, false) << ", ";
+
+ // Special handling for 'pedantic'.
+ const bool IsPedantic = I.first == "pedantic";
+
+ // Diagnostics in the group.
+ const std::vector<const Record *> &V = I.second.DiagsInGroup;
+ const bool hasDiags =
+ !V.empty() || (IsPedantic && !DiagsInPedantic.empty());
+ if (hasDiags) {
+ OS << "/* DiagArray" << I.second.IDNo << " */ " << DiagArrayIndex
+ << ", ";
+ if (IsPedantic)
+ DiagArrayIndex += DiagsInPedantic.size();
+ DiagArrayIndex += V.size() + 1;
+ } else {
+ OS << "/* Empty */ 0, ";
+ }
+
+ // Subgroups.
+ const std::vector<std::string> &SubGroups = I.second.SubGroups;
+ const bool hasSubGroups =
+ !SubGroups.empty() || (IsPedantic && !GroupsInPedantic.empty());
+ if (hasSubGroups) {
+ OS << "/* DiagSubGroup" << I.second.IDNo << " */ " << SubGroupIndex;
+ if (IsPedantic)
+ SubGroupIndex += GroupsInPedantic.size();
+ SubGroupIndex += SubGroups.size() + 1;
+ } else {
+ OS << "/* Empty */ 0";
+ }
+
+ OS << " },\n";
+ }
+ OS << "#endif // GET_DIAG_TABLE\n\n";
+}
+
+/// \brief Emit the table of diagnostic categories.
+///
+/// The table has the form of macro calls that have two parameters. The
+/// category's name as well as an enum that represents the category. The
+/// table can be used by defining the macro 'CATEGORY' and including this
+/// table right after.
+///
+/// \code
+/// #ifdef GET_CATEGORY_TABLE
+/// CATEGORY("Semantic Issue", DiagCat_Semantic_Issue)
+/// CATEGORY("Lambda Issue", DiagCat_Lambda_Issue)
+/// #endif
+/// \endcode
+static void emitCategoryTable(RecordKeeper &Records, raw_ostream &OS) {
+ DiagCategoryIDMap CategoriesByID(Records);
+ OS << "\n#ifdef GET_CATEGORY_TABLE\n";
+ for (auto const &C : CategoriesByID)
+ OS << "CATEGORY(\"" << C << "\", " << getDiagCategoryEnum(C) << ")\n";
+ OS << "#endif // GET_CATEGORY_TABLE\n\n";
+}
+
namespace clang {
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 *> Diags = Records.getAllDerivedDefinitions("Diagnostic");
- std::vector<Record*> DiagGroups
- = Records.getAllDerivedDefinitions("DiagGroup");
+ std::vector<Record *> DiagGroups =
+ Records.getAllDerivedDefinitions("DiagGroup");
std::map<std::string, GroupInfo> DiagsInGroup;
groupDiagnostics(Diags, DiagGroups, DiagsInGroup);
@@ -616,135 +841,21 @@
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;
- OS << "static const int16_t DiagArrays[] = {\n"
- << " /* Empty */ -1,\n";
- for (std::map<std::string, GroupInfo>::const_iterator
- I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) {
- MaxLen = std::max(MaxLen, (unsigned)I->first.size());
- const bool IsPedantic = I->first == "pedantic";
-
- const std::vector<const Record*> &V = I->second.DiagsInGroup;
- if (!V.empty() || (IsPedantic && !DiagsInPedantic.empty())) {
- OS << " /* 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";
- }
- }
- OS << "};\n\n";
-
- OS << "static const int16_t DiagSubGroups[] = {\n"
- << " /* Empty */ -1,\n";
- for (std::map<std::string, GroupInfo>::const_iterator
- I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) {
- const bool IsPedantic = I->first == "pedantic";
-
- const std::vector<std::string> &SubGroups = I->second.SubGroups;
- if (!SubGroups.empty() || (IsPedantic && !GroupsInPedantic.empty())) {
- OS << " /* DiagSubGroup" << I->second.IDNo << " */ ";
- for (unsigned i = 0, e = SubGroups.size(); i != e; ++i) {
- std::map<std::string, GroupInfo>::const_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>::const_iterator RI =
- DiagsInGroup.find(GroupName);
- assert(RI != DiagsInGroup.end() && "Referenced without existing?");
- OS << RI->second.IDNo << ", ";
- }
- }
-
- OS << "-1,\n";
- }
- }
- OS << "};\n\n";
-
StringToOffsetTable GroupNames;
for (std::map<std::string, GroupInfo>::const_iterator
- I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) {
+ 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);
}
- OS << "static const char DiagGroupNames[] = {\n";
- GroupNames.EmitString(OS);
- OS << "};\n\n";
-
- OS << "#endif // GET_DIAG_ARRAYS\n\n";
-
- // Emit the table now.
- OS << "\n#ifdef GET_DIAG_TABLE\n";
- unsigned SubGroupIndex = 1, DiagArrayIndex = 1;
- for (std::map<std::string, GroupInfo>::const_iterator
- I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) {
- // Group option string.
- OS << " { /* ";
- if (I->first.find_first_not_of("abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "0123456789!@#$%^*-+=:?")!=std::string::npos)
- PrintFatalError("Invalid character in diagnostic group '" +
- I->first + "'");
- OS << I->first << " */ " << std::string(MaxLen-I->first.size(), ' ');
- // Store a pascal-style length byte at the beginning of the string.
- std::string Name = char(I->first.size()) + I->first;
- OS << GroupNames.GetOrAddStringOffset(Name, false) << ", ";
-
- // Special handling for 'pedantic'.
- const bool IsPedantic = I->first == "pedantic";
-
- // Diagnostics in the group.
- const std::vector<const Record*> &V = I->second.DiagsInGroup;
- const bool hasDiags = !V.empty() ||
- (IsPedantic && !DiagsInPedantic.empty());
- if (hasDiags) {
- OS << "/* DiagArray" << I->second.IDNo << " */ "
- << DiagArrayIndex << ", ";
- if (IsPedantic)
- DiagArrayIndex += DiagsInPedantic.size();
- DiagArrayIndex += V.size() + 1;
- } else {
- OS << "/* Empty */ 0, ";
- }
-
- // Subgroups.
- const std::vector<std::string> &SubGroups = I->second.SubGroups;
- const bool hasSubGroups = !SubGroups.empty() ||
- (IsPedantic && !GroupsInPedantic.empty());
- if (hasSubGroups) {
- OS << "/* DiagSubGroup" << I->second.IDNo << " */ " << SubGroupIndex;
- if (IsPedantic)
- SubGroupIndex += GroupsInPedantic.size();
- SubGroupIndex += SubGroups.size() + 1;
- } else {
- OS << "/* Empty */ 0";
- }
- 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::const_iterator I = CategoriesByID.begin(),
- E = CategoriesByID.end(); I != E; ++I)
- OS << "CATEGORY(\"" << *I << "\", " << getDiagCategoryEnum(*I) << ")\n";
- OS << "#endif // GET_CATEGORY_TABLE\n\n";
+ emitAllDiagArrays(DiagsInGroup, DiagsInPedantic, GroupsInPedantic, GroupNames,
+ OS);
+ emitDiagTable(DiagsInGroup, DiagsInPedantic, GroupsInPedantic, GroupNames,
+ OS);
+ emitCategoryTable(Records, OS);
}
} // end namespace clang