[clang] [clang-tools-extra] [llvm] [clang] Introduce diagnostics suppression mappings (PR #112517)
kadir çetinkaya via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 7 05:26:24 PST 2024
================
@@ -477,6 +486,109 @@ void DiagnosticsEngine::setSeverityForAll(diag::Flavor Flavor,
setSeverity(Diag, Map, Loc);
}
+namespace {
+class WarningsSpecialCaseList : public llvm::SpecialCaseList {
+public:
+ static std::unique_ptr<WarningsSpecialCaseList>
+ create(const llvm::MemoryBuffer &MB, std::string &Err) {
+ auto SCL = std::make_unique<WarningsSpecialCaseList>();
+ if (!SCL->createInternal(&MB, Err))
+ return nullptr;
+ return SCL;
+ }
+
+ // Section names refer to diagnostic groups, which cover multiple individual
+ // diagnostics. Expand diagnostic groups here to individual diagnostics.
+ // A diagnostic can have multiple diagnostic groups associated with it, we let
+ // the last section take precedence in such cases.
+ void processSections(DiagnosticsEngine &Diags) {
+ // Drop the default section introduced by special case list, we only support
+ // exact diagnostic group names.
+ Sections.erase("*");
+ // Make sure we iterate sections by their line numbers.
+ std::vector<std::pair<unsigned, const llvm::StringMapEntry<Section> *>>
+ LineAndSectionEntry;
+ LineAndSectionEntry.reserve(Sections.size());
+ for (const auto &Entry : Sections) {
+ LineAndSectionEntry.emplace_back(
+ Entry.second.SectionMatcher->Globs.at(Entry.first()).second, &Entry);
+ }
+ llvm::sort(LineAndSectionEntry);
+ static constexpr auto kFlavor = clang::diag::Flavor::WarningOrError;
+ for (const auto &[_, SectionEntry] : LineAndSectionEntry) {
+ SmallVector<diag::kind, 256> GroupDiags;
+ llvm::StringRef DiagGroup = SectionEntry->getKey();
+ if (Diags.getDiagnosticIDs()->getDiagnosticsInGroup(kFlavor, DiagGroup,
+ GroupDiags)) {
+ StringRef Suggestion =
+ DiagnosticIDs::getNearestOption(kFlavor, DiagGroup);
+ Diags.Report(diag::warn_unknown_diag_option)
+ << static_cast<unsigned>(kFlavor) << DiagGroup
+ << !Suggestion.empty() << Suggestion;
+ continue;
+ }
+ for (diag::kind D : GroupDiags)
+ DiagToSection[D] = &SectionEntry->getValue();
+ }
+ }
+
+ bool isDiagSuppressed(diag::kind DiagId, llvm::StringRef FilePath) const {
+ auto Section = DiagToSection.find(DiagId);
+ if (Section == DiagToSection.end())
+ return false;
+ auto &DiagEntries = Section->second->Entries;
+ auto SrcEntries = DiagEntries.find("src");
+ if (SrcEntries == DiagEntries.end())
+ return false;
+ return globsMatches(SrcEntries->second, FilePath);
+ }
+
+private:
+ // Find the longest glob pattern that matches FilePath amongst
+ // CategoriesToMatchers, return true iff the match exists and belongs to a
+ // positive category.
+ bool globsMatches(llvm::StringMap<Matcher> CategoriesToMatchers,
+ llvm::StringRef FilePath) const {
+ llvm::StringRef LongestMatch;
+ bool LongestIsPositive = false;
+ for (const auto &[Category, Matcher] : CategoriesToMatchers) {
+ bool IsPositive = Category != "emit";
+ for (const auto &[Pattern, Glob] : Matcher.Globs) {
----------------
kadircet wrote:
> Sure, I didn't mean to suggest we should do it for other SpecialCaseList users.
> We can limit sorting to this use case.
I am skeptical of that being a net-positive even for warning-suppression-mappings. In the common path, compiler doesn't emit warnings. Hence most of the compilations will just end up sorting this list, and never query it afterwards.
> I wonder if it is required to have a different matching behavior or we could match by order so that users would just put their patterns in the order they want them to be matched.
I'd rather give users less ways to misconfigure this infrastructure. but by the nature of the current behavior, users can get the exact same end result by just ensuring a subdirectory is mentioned before its parents in the list, eg:
```
foo/bar/*=emit
foo/*
```
> If in other use cases the matching is by order, and we could have a pattern wider than another (foo/* wider than foo/bar/*), why is this use case different?
other use cases only allow inclusion, they don't allow exclusions.
https://github.com/llvm/llvm-project/pull/112517
More information about the llvm-commits
mailing list