diff options
Diffstat (limited to 'clang/lib/Basic/DiagnosticIDs.cpp')
| -rw-r--r-- | clang/lib/Basic/DiagnosticIDs.cpp | 62 |
1 files changed, 46 insertions, 16 deletions
diff --git a/clang/lib/Basic/DiagnosticIDs.cpp b/clang/lib/Basic/DiagnosticIDs.cpp index 3c0216a1320..ec244ccda3c 100644 --- a/clang/lib/Basic/DiagnosticIDs.cpp +++ b/clang/lib/Basic/DiagnosticIDs.cpp @@ -58,6 +58,11 @@ struct StaticDiagInfoRec { return StringRef(DescriptionStr, DescriptionLen); } + diag::Flavor getFlavor() const { + return Class == CLASS_REMARK ? diag::Flavor::Remark + : diag::Flavor::WarningOrError; + } + bool operator<(const StaticDiagInfoRec &RHS) const { return DiagID < RHS.DiagID; } @@ -522,40 +527,57 @@ StringRef DiagnosticIDs::getWarningOptionForDiag(unsigned DiagID) { return StringRef(); } -static void getDiagnosticsInGroup(const WarningOption *Group, +/// Return \c true if any diagnostics were found in this group, even if they +/// were filtered out due to having the wrong flavor. +static bool getDiagnosticsInGroup(diag::Flavor Flavor, + const WarningOption *Group, SmallVectorImpl<diag::kind> &Diags) { + // An empty group is considered to be a warning group: we have empty groups + // for GCC compatibility, and GCC does not have remarks. + if (!Group->Members && !Group->SubGroups) + return Flavor == diag::Flavor::Remark ? true : false; + + bool NotFound = true; + // Add the members of the option diagnostic set. const int16_t *Member = DiagArrays + Group->Members; - for (; *Member != -1; ++Member) - Diags.push_back(*Member); + for (; *Member != -1; ++Member) { + if (GetDiagInfo(*Member)->getFlavor() == Flavor) { + NotFound = false; + Diags.push_back(*Member); + } + } // Add the members of the subgroups. const int16_t *SubGroups = DiagSubGroups + Group->SubGroups; for (; *SubGroups != (int16_t)-1; ++SubGroups) - getDiagnosticsInGroup(&OptionTable[(short)*SubGroups], Diags); + NotFound &= getDiagnosticsInGroup(Flavor, &OptionTable[(short)*SubGroups], + Diags); + + return NotFound; } -bool DiagnosticIDs::getDiagnosticsInGroup( - StringRef Group, - SmallVectorImpl<diag::kind> &Diags) const { - const WarningOption *Found = - std::lower_bound(OptionTable, OptionTable + OptionTableSize, Group, - WarningOptionCompare); +bool +DiagnosticIDs::getDiagnosticsInGroup(diag::Flavor Flavor, StringRef Group, + SmallVectorImpl<diag::kind> &Diags) const { + const WarningOption *Found = std::lower_bound( + OptionTable, OptionTable + OptionTableSize, Group, WarningOptionCompare); if (Found == OptionTable + OptionTableSize || Found->getName() != Group) return true; // Option not found. - ::getDiagnosticsInGroup(Found, Diags); - return false; + return ::getDiagnosticsInGroup(Flavor, Found, Diags); } -void DiagnosticIDs::getAllDiagnostics( - SmallVectorImpl<diag::kind> &Diags) const { +void DiagnosticIDs::getAllDiagnostics(diag::Flavor Flavor, + SmallVectorImpl<diag::kind> &Diags) const { for (unsigned i = 0; i != StaticDiagInfoSize; ++i) - Diags.push_back(StaticDiagInfo[i].DiagID); + if (StaticDiagInfo[i].getFlavor() == Flavor) + Diags.push_back(StaticDiagInfo[i].DiagID); } -StringRef DiagnosticIDs::getNearestWarningOption(StringRef Group) { +StringRef DiagnosticIDs::getNearestOption(diag::Flavor Flavor, + StringRef Group) { StringRef Best; unsigned BestDistance = Group.size() + 1; // Sanity threshold. for (const WarningOption *i = OptionTable, *e = OptionTable + OptionTableSize; @@ -565,6 +587,14 @@ StringRef DiagnosticIDs::getNearestWarningOption(StringRef Group) { continue; unsigned Distance = i->getName().edit_distance(Group, true, BestDistance); + if (Distance > BestDistance) + continue; + + // Don't suggest groups that are not of this kind. + llvm::SmallVector<diag::kind, 8> Diags; + if (::getDiagnosticsInGroup(Flavor, i, Diags) || Diags.empty()) + continue; + if (Distance == BestDistance) { // Two matches with the same distance, don't prefer one over the other. Best = ""; |

