[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)

2024-05-29 Thread Justin Cady via cfe-commits

justincady wrote:

@codectile `--exclude-header-filter` is used in conjunction with 
`--header-filter` to exclude certain headers from analysis. Check out the tests 
that were modified as a part of this PR for more examples, but the basic idea 
is:

```
$ clang-tidy --header-filter='.*' --exclude-header-filter='header1\.h' [...]
```

In that example all headers will be analyzed using the enabled checks _except_ 
`header1.h`.

https://github.com/llvm/llvm-project/pull/91400
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)

2024-05-14 Thread Justin Cady via cfe-commits

https://github.com/justincady closed 
https://github.com/llvm/llvm-project/pull/91400
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)

2024-05-13 Thread Justin Cady via cfe-commits

https://github.com/justincady updated 
https://github.com/llvm/llvm-project/pull/91400

>From 58d3d52c666bdaa3534cd16080bb895d49f61008 Mon Sep 17 00:00:00 2001
From: Justin Cady 
Date: Tue, 7 May 2024 16:54:35 -0400
Subject: [PATCH] Add option to exclude headers from clang-tidy analysis

This is a renewed attempt to land @toddlipcon's D34654. The comments on
that patch indicate a broad desire for some ability to ignore headers.

After considering various options, including migrating to std::regex, I
believe this is the best path forward. It's intuitive to have separate
regexes for including headers versus excluding them, and this approach
has the added benefit of being completely opt-in. No existing configs
will break, regardless of existing HeaderFilterRegex values.

This functionality is useful for improving performance when analyzing a
targeted subset of code, as well as in cases where some collection of
headers cannot be modified (third party source, for example).
---
 .../ClangTidyDiagnosticConsumer.cpp   |  28 ++-
 .../clang-tidy/ClangTidyDiagnosticConsumer.h  |   1 +
 .../clang-tidy/ClangTidyOptions.cpp   |   6 +-
 .../clang-tidy/ClangTidyOptions.h |   4 +
 .../clang-tidy/tool/ClangTidyMain.cpp |  18 ++
 .../clang-tidy/tool/run-clang-tidy.py |  13 +
 clang-tools-extra/docs/ReleaseNotes.rst   |   3 +
 clang-tools-extra/docs/clang-tidy/index.rst   | 235 +-
 .../Inputs/config-files/.clang-tidy   |   1 +
 .../Inputs/config-files/1/.clang-tidy |   1 +
 .../Inputs/config-files/3/.clang-tidy |   1 +
 .../infrastructure/config-files.cpp   |  15 +-
 .../clang-tidy/infrastructure/file-filter.cpp |   7 +
 13 files changed, 207 insertions(+), 126 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp 
b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
index de2a3b51422a5..200bb87a5ac3c 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -311,7 +311,18 @@ ClangTidyDiagnosticConsumer::ClangTidyDiagnosticConsumer(
 : Context(Ctx), ExternalDiagEngine(ExternalDiagEngine),
   RemoveIncompatibleErrors(RemoveIncompatibleErrors),
   GetFixesFromNotes(GetFixesFromNotes),
-  EnableNolintBlocks(EnableNolintBlocks) {}
+  EnableNolintBlocks(EnableNolintBlocks) {
+
+  if (Context.getOptions().HeaderFilterRegex &&
+  !Context.getOptions().HeaderFilterRegex->empty())
+HeaderFilter =
+std::make_unique(*Context.getOptions().HeaderFilterRegex);
+
+  if (Context.getOptions().ExcludeHeaderFilterRegex &&
+  !Context.getOptions().ExcludeHeaderFilterRegex->empty())
+ExcludeHeaderFilter = std::make_unique(
+*Context.getOptions().ExcludeHeaderFilterRegex);
+}
 
 void ClangTidyDiagnosticConsumer::finalizeLastError() {
   if (!Errors.empty()) {
@@ -562,22 +573,17 @@ void 
ClangTidyDiagnosticConsumer::checkFilters(SourceLocation Location,
   }
 
   StringRef FileName(File->getName());
-  LastErrorRelatesToUserCode = LastErrorRelatesToUserCode ||
-   Sources.isInMainFile(Location) ||
-   getHeaderFilter()->match(FileName);
+  LastErrorRelatesToUserCode =
+  LastErrorRelatesToUserCode || Sources.isInMainFile(Location) ||
+  (HeaderFilter &&
+   (HeaderFilter->match(FileName) &&
+!(ExcludeHeaderFilter && ExcludeHeaderFilter->match(FileName;
 
   unsigned LineNumber = Sources.getExpansionLineNumber(Location);
   LastErrorPassesLineFilter =
   LastErrorPassesLineFilter || passesLineFilter(FileName, LineNumber);
 }
 
-llvm::Regex *ClangTidyDiagnosticConsumer::getHeaderFilter() {
-  if (!HeaderFilter)
-HeaderFilter =
-std::make_unique(*Context.getOptions().HeaderFilterRegex);
-  return HeaderFilter.get();
-}
-
 void ClangTidyDiagnosticConsumer::removeIncompatibleErrors() {
   // Each error is modelled as the set of intervals in which it applies
   // replacements. To detect overlapping replacements, we use a sweep line
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h 
b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
index 9280eb1e1f218..97e16a12febd0 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
@@ -313,6 +313,7 @@ class ClangTidyDiagnosticConsumer : public 
DiagnosticConsumer {
   bool EnableNolintBlocks;
   std::vector Errors;
   std::unique_ptr HeaderFilter;
+  std::unique_ptr ExcludeHeaderFilter;
   bool LastErrorRelatesToUserCode = false;
   bool LastErrorPassesLineFilter = false;
   bool LastErrorWasIgnored = false;
diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp 
b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
index cbf21a0e2ae34..445c7f85c900c 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
+++ 

[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)

2024-05-13 Thread Justin Cady via cfe-commits

https://github.com/justincady updated 
https://github.com/llvm/llvm-project/pull/91400

>From e65bd48ef896f3327a1397a1b2f6f0a34e3711d2 Mon Sep 17 00:00:00 2001
From: Justin Cady 
Date: Tue, 7 May 2024 16:54:35 -0400
Subject: [PATCH 1/3] Add option to exclude headers from clang-tidy analysis

This is a renewed attempt to land @toddlipcon's D34654. The comments on
that patch indicate a broad desire for some ability to ignore headers.

After considering various options, including migrating to std::regex, I
believe this is the best path forward. It's intuitive to have separate
regexes for including headers versus excluding them, and this approach
has the added benefit of being completely opt-in. No existing configs
will break, regardless of existing HeaderFilterRegex values.

This functionality is useful for improving performance when analyzing a
targeted subset of code, as well as in cases where some collection of
headers cannot be modified (third party source, for example).
---
 .../ClangTidyDiagnosticConsumer.cpp   |  28 ++-
 .../clang-tidy/ClangTidyDiagnosticConsumer.h  |   1 +
 .../clang-tidy/ClangTidyOptions.cpp   |   6 +-
 .../clang-tidy/ClangTidyOptions.h |   4 +
 .../clang-tidy/tool/ClangTidyMain.cpp |  18 ++
 .../clang-tidy/tool/run-clang-tidy.py |  13 +
 clang-tools-extra/docs/ReleaseNotes.rst   |   2 +
 clang-tools-extra/docs/clang-tidy/index.rst   | 235 +-
 .../Inputs/config-files/.clang-tidy   |   1 +
 .../Inputs/config-files/1/.clang-tidy |   1 +
 .../Inputs/config-files/3/.clang-tidy |   1 +
 .../infrastructure/config-files.cpp   |  15 +-
 .../clang-tidy/infrastructure/file-filter.cpp |   7 +
 13 files changed, 206 insertions(+), 126 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp 
b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
index de2a3b51422a5..200bb87a5ac3c 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -311,7 +311,18 @@ ClangTidyDiagnosticConsumer::ClangTidyDiagnosticConsumer(
 : Context(Ctx), ExternalDiagEngine(ExternalDiagEngine),
   RemoveIncompatibleErrors(RemoveIncompatibleErrors),
   GetFixesFromNotes(GetFixesFromNotes),
-  EnableNolintBlocks(EnableNolintBlocks) {}
+  EnableNolintBlocks(EnableNolintBlocks) {
+
+  if (Context.getOptions().HeaderFilterRegex &&
+  !Context.getOptions().HeaderFilterRegex->empty())
+HeaderFilter =
+std::make_unique(*Context.getOptions().HeaderFilterRegex);
+
+  if (Context.getOptions().ExcludeHeaderFilterRegex &&
+  !Context.getOptions().ExcludeHeaderFilterRegex->empty())
+ExcludeHeaderFilter = std::make_unique(
+*Context.getOptions().ExcludeHeaderFilterRegex);
+}
 
 void ClangTidyDiagnosticConsumer::finalizeLastError() {
   if (!Errors.empty()) {
@@ -562,22 +573,17 @@ void 
ClangTidyDiagnosticConsumer::checkFilters(SourceLocation Location,
   }
 
   StringRef FileName(File->getName());
-  LastErrorRelatesToUserCode = LastErrorRelatesToUserCode ||
-   Sources.isInMainFile(Location) ||
-   getHeaderFilter()->match(FileName);
+  LastErrorRelatesToUserCode =
+  LastErrorRelatesToUserCode || Sources.isInMainFile(Location) ||
+  (HeaderFilter &&
+   (HeaderFilter->match(FileName) &&
+!(ExcludeHeaderFilter && ExcludeHeaderFilter->match(FileName;
 
   unsigned LineNumber = Sources.getExpansionLineNumber(Location);
   LastErrorPassesLineFilter =
   LastErrorPassesLineFilter || passesLineFilter(FileName, LineNumber);
 }
 
-llvm::Regex *ClangTidyDiagnosticConsumer::getHeaderFilter() {
-  if (!HeaderFilter)
-HeaderFilter =
-std::make_unique(*Context.getOptions().HeaderFilterRegex);
-  return HeaderFilter.get();
-}
-
 void ClangTidyDiagnosticConsumer::removeIncompatibleErrors() {
   // Each error is modelled as the set of intervals in which it applies
   // replacements. To detect overlapping replacements, we use a sweep line
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h 
b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
index 9280eb1e1f218..97e16a12febd0 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
@@ -313,6 +313,7 @@ class ClangTidyDiagnosticConsumer : public 
DiagnosticConsumer {
   bool EnableNolintBlocks;
   std::vector Errors;
   std::unique_ptr HeaderFilter;
+  std::unique_ptr ExcludeHeaderFilter;
   bool LastErrorRelatesToUserCode = false;
   bool LastErrorPassesLineFilter = false;
   bool LastErrorWasIgnored = false;
diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp 
b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
index cbf21a0e2ae34..445c7f85c900c 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
+++ 

[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)

2024-05-13 Thread Justin Cady via cfe-commits

https://github.com/justincady updated 
https://github.com/llvm/llvm-project/pull/91400

>From e65bd48ef896f3327a1397a1b2f6f0a34e3711d2 Mon Sep 17 00:00:00 2001
From: Justin Cady 
Date: Tue, 7 May 2024 16:54:35 -0400
Subject: [PATCH 1/2] Add option to exclude headers from clang-tidy analysis

This is a renewed attempt to land @toddlipcon's D34654. The comments on
that patch indicate a broad desire for some ability to ignore headers.

After considering various options, including migrating to std::regex, I
believe this is the best path forward. It's intuitive to have separate
regexes for including headers versus excluding them, and this approach
has the added benefit of being completely opt-in. No existing configs
will break, regardless of existing HeaderFilterRegex values.

This functionality is useful for improving performance when analyzing a
targeted subset of code, as well as in cases where some collection of
headers cannot be modified (third party source, for example).
---
 .../ClangTidyDiagnosticConsumer.cpp   |  28 ++-
 .../clang-tidy/ClangTidyDiagnosticConsumer.h  |   1 +
 .../clang-tidy/ClangTidyOptions.cpp   |   6 +-
 .../clang-tidy/ClangTidyOptions.h |   4 +
 .../clang-tidy/tool/ClangTidyMain.cpp |  18 ++
 .../clang-tidy/tool/run-clang-tidy.py |  13 +
 clang-tools-extra/docs/ReleaseNotes.rst   |   2 +
 clang-tools-extra/docs/clang-tidy/index.rst   | 235 +-
 .../Inputs/config-files/.clang-tidy   |   1 +
 .../Inputs/config-files/1/.clang-tidy |   1 +
 .../Inputs/config-files/3/.clang-tidy |   1 +
 .../infrastructure/config-files.cpp   |  15 +-
 .../clang-tidy/infrastructure/file-filter.cpp |   7 +
 13 files changed, 206 insertions(+), 126 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp 
b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
index de2a3b51422a5..200bb87a5ac3c 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -311,7 +311,18 @@ ClangTidyDiagnosticConsumer::ClangTidyDiagnosticConsumer(
 : Context(Ctx), ExternalDiagEngine(ExternalDiagEngine),
   RemoveIncompatibleErrors(RemoveIncompatibleErrors),
   GetFixesFromNotes(GetFixesFromNotes),
-  EnableNolintBlocks(EnableNolintBlocks) {}
+  EnableNolintBlocks(EnableNolintBlocks) {
+
+  if (Context.getOptions().HeaderFilterRegex &&
+  !Context.getOptions().HeaderFilterRegex->empty())
+HeaderFilter =
+std::make_unique(*Context.getOptions().HeaderFilterRegex);
+
+  if (Context.getOptions().ExcludeHeaderFilterRegex &&
+  !Context.getOptions().ExcludeHeaderFilterRegex->empty())
+ExcludeHeaderFilter = std::make_unique(
+*Context.getOptions().ExcludeHeaderFilterRegex);
+}
 
 void ClangTidyDiagnosticConsumer::finalizeLastError() {
   if (!Errors.empty()) {
@@ -562,22 +573,17 @@ void 
ClangTidyDiagnosticConsumer::checkFilters(SourceLocation Location,
   }
 
   StringRef FileName(File->getName());
-  LastErrorRelatesToUserCode = LastErrorRelatesToUserCode ||
-   Sources.isInMainFile(Location) ||
-   getHeaderFilter()->match(FileName);
+  LastErrorRelatesToUserCode =
+  LastErrorRelatesToUserCode || Sources.isInMainFile(Location) ||
+  (HeaderFilter &&
+   (HeaderFilter->match(FileName) &&
+!(ExcludeHeaderFilter && ExcludeHeaderFilter->match(FileName;
 
   unsigned LineNumber = Sources.getExpansionLineNumber(Location);
   LastErrorPassesLineFilter =
   LastErrorPassesLineFilter || passesLineFilter(FileName, LineNumber);
 }
 
-llvm::Regex *ClangTidyDiagnosticConsumer::getHeaderFilter() {
-  if (!HeaderFilter)
-HeaderFilter =
-std::make_unique(*Context.getOptions().HeaderFilterRegex);
-  return HeaderFilter.get();
-}
-
 void ClangTidyDiagnosticConsumer::removeIncompatibleErrors() {
   // Each error is modelled as the set of intervals in which it applies
   // replacements. To detect overlapping replacements, we use a sweep line
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h 
b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
index 9280eb1e1f218..97e16a12febd0 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
@@ -313,6 +313,7 @@ class ClangTidyDiagnosticConsumer : public 
DiagnosticConsumer {
   bool EnableNolintBlocks;
   std::vector Errors;
   std::unique_ptr HeaderFilter;
+  std::unique_ptr ExcludeHeaderFilter;
   bool LastErrorRelatesToUserCode = false;
   bool LastErrorPassesLineFilter = false;
   bool LastErrorWasIgnored = false;
diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp 
b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
index cbf21a0e2ae34..445c7f85c900c 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
+++ 

[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)

2024-05-13 Thread Justin Cady via cfe-commits

https://github.com/justincady updated 
https://github.com/llvm/llvm-project/pull/91400

>From e65bd48ef896f3327a1397a1b2f6f0a34e3711d2 Mon Sep 17 00:00:00 2001
From: Justin Cady 
Date: Tue, 7 May 2024 16:54:35 -0400
Subject: [PATCH] Add option to exclude headers from clang-tidy analysis

This is a renewed attempt to land @toddlipcon's D34654. The comments on
that patch indicate a broad desire for some ability to ignore headers.

After considering various options, including migrating to std::regex, I
believe this is the best path forward. It's intuitive to have separate
regexes for including headers versus excluding them, and this approach
has the added benefit of being completely opt-in. No existing configs
will break, regardless of existing HeaderFilterRegex values.

This functionality is useful for improving performance when analyzing a
targeted subset of code, as well as in cases where some collection of
headers cannot be modified (third party source, for example).
---
 .../ClangTidyDiagnosticConsumer.cpp   |  28 ++-
 .../clang-tidy/ClangTidyDiagnosticConsumer.h  |   1 +
 .../clang-tidy/ClangTidyOptions.cpp   |   6 +-
 .../clang-tidy/ClangTidyOptions.h |   4 +
 .../clang-tidy/tool/ClangTidyMain.cpp |  18 ++
 .../clang-tidy/tool/run-clang-tidy.py |  13 +
 clang-tools-extra/docs/ReleaseNotes.rst   |   2 +
 clang-tools-extra/docs/clang-tidy/index.rst   | 235 +-
 .../Inputs/config-files/.clang-tidy   |   1 +
 .../Inputs/config-files/1/.clang-tidy |   1 +
 .../Inputs/config-files/3/.clang-tidy |   1 +
 .../infrastructure/config-files.cpp   |  15 +-
 .../clang-tidy/infrastructure/file-filter.cpp |   7 +
 13 files changed, 206 insertions(+), 126 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp 
b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
index de2a3b51422a5..200bb87a5ac3c 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -311,7 +311,18 @@ ClangTidyDiagnosticConsumer::ClangTidyDiagnosticConsumer(
 : Context(Ctx), ExternalDiagEngine(ExternalDiagEngine),
   RemoveIncompatibleErrors(RemoveIncompatibleErrors),
   GetFixesFromNotes(GetFixesFromNotes),
-  EnableNolintBlocks(EnableNolintBlocks) {}
+  EnableNolintBlocks(EnableNolintBlocks) {
+
+  if (Context.getOptions().HeaderFilterRegex &&
+  !Context.getOptions().HeaderFilterRegex->empty())
+HeaderFilter =
+std::make_unique(*Context.getOptions().HeaderFilterRegex);
+
+  if (Context.getOptions().ExcludeHeaderFilterRegex &&
+  !Context.getOptions().ExcludeHeaderFilterRegex->empty())
+ExcludeHeaderFilter = std::make_unique(
+*Context.getOptions().ExcludeHeaderFilterRegex);
+}
 
 void ClangTidyDiagnosticConsumer::finalizeLastError() {
   if (!Errors.empty()) {
@@ -562,22 +573,17 @@ void 
ClangTidyDiagnosticConsumer::checkFilters(SourceLocation Location,
   }
 
   StringRef FileName(File->getName());
-  LastErrorRelatesToUserCode = LastErrorRelatesToUserCode ||
-   Sources.isInMainFile(Location) ||
-   getHeaderFilter()->match(FileName);
+  LastErrorRelatesToUserCode =
+  LastErrorRelatesToUserCode || Sources.isInMainFile(Location) ||
+  (HeaderFilter &&
+   (HeaderFilter->match(FileName) &&
+!(ExcludeHeaderFilter && ExcludeHeaderFilter->match(FileName;
 
   unsigned LineNumber = Sources.getExpansionLineNumber(Location);
   LastErrorPassesLineFilter =
   LastErrorPassesLineFilter || passesLineFilter(FileName, LineNumber);
 }
 
-llvm::Regex *ClangTidyDiagnosticConsumer::getHeaderFilter() {
-  if (!HeaderFilter)
-HeaderFilter =
-std::make_unique(*Context.getOptions().HeaderFilterRegex);
-  return HeaderFilter.get();
-}
-
 void ClangTidyDiagnosticConsumer::removeIncompatibleErrors() {
   // Each error is modelled as the set of intervals in which it applies
   // replacements. To detect overlapping replacements, we use a sweep line
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h 
b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
index 9280eb1e1f218..97e16a12febd0 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
@@ -313,6 +313,7 @@ class ClangTidyDiagnosticConsumer : public 
DiagnosticConsumer {
   bool EnableNolintBlocks;
   std::vector Errors;
   std::unique_ptr HeaderFilter;
+  std::unique_ptr ExcludeHeaderFilter;
   bool LastErrorRelatesToUserCode = false;
   bool LastErrorPassesLineFilter = false;
   bool LastErrorWasIgnored = false;
diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp 
b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
index cbf21a0e2ae34..445c7f85c900c 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
+++ 

[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)

2024-05-10 Thread Justin Cady via cfe-commits


@@ -311,7 +311,12 @@ ClangTidyDiagnosticConsumer::ClangTidyDiagnosticConsumer(
 : Context(Ctx), ExternalDiagEngine(ExternalDiagEngine),
   RemoveIncompatibleErrors(RemoveIncompatibleErrors),
   GetFixesFromNotes(GetFixesFromNotes),
-  EnableNolintBlocks(EnableNolintBlocks) {}
+  EnableNolintBlocks(EnableNolintBlocks) {
+
+  if (Context.getOptions().ExcludeHeaderFilterRegex)
+ExcludeHeaderFilter = std::make_unique(
+*Context.getOptions().ExcludeHeaderFilterRegex);
+}

justincady wrote:

The change to make `HeaderFilter` mirror `ExcludeHeaderFilter` was not too bad, 
so I went ahead with it. I thought it might actually be better to do now while 
everything is fresh in my mind.  

https://github.com/llvm/llvm-project/pull/91400
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)

2024-05-10 Thread Justin Cady via cfe-commits


@@ -311,7 +311,12 @@ ClangTidyDiagnosticConsumer::ClangTidyDiagnosticConsumer(
 : Context(Ctx), ExternalDiagEngine(ExternalDiagEngine),
   RemoveIncompatibleErrors(RemoveIncompatibleErrors),
   GetFixesFromNotes(GetFixesFromNotes),
-  EnableNolintBlocks(EnableNolintBlocks) {}
+  EnableNolintBlocks(EnableNolintBlocks) {
+
+  if (Context.getOptions().ExcludeHeaderFilterRegex)
+ExcludeHeaderFilter = std::make_unique(
+*Context.getOptions().ExcludeHeaderFilterRegex);

justincady wrote:

After further testing I came to understand what you meant and made this 
adjustment as suggested.

https://github.com/llvm/llvm-project/pull/91400
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)

2024-05-10 Thread Justin Cady via cfe-commits

https://github.com/justincady updated 
https://github.com/llvm/llvm-project/pull/91400

>From a5de583aa94ef794a083c8b27df6dc6fc0762cb7 Mon Sep 17 00:00:00 2001
From: Justin Cady 
Date: Tue, 7 May 2024 16:54:35 -0400
Subject: [PATCH 1/5] Add option to exclude headers from clang-tidy analysis

This is a renewed attempt to land @toddlipcon's D34654. The comments on
that patch indicate a broad desire for some ability to ignore headers.

After considering various options, including migrating to std::regex, I
believe this is the best path forward. It's intuitive to have separate
regexes for including headers versus excluding them, and this approach
has the added benefit of being completely opt-in. No existing configs
will break, regardless of existing HeaderFilterRegex values.

This functionality is useful for improving performance when analyzing a
targeted subset of code, as well as in cases where some collection of
headers cannot be modified (third party source, for example).
---
 .../clang-tidy/ClangTidyDiagnosticConsumer.cpp   | 10 +-
 .../clang-tidy/ClangTidyDiagnosticConsumer.h |  5 +
 .../clang-tidy/ClangTidyOptions.cpp  |  4 
 clang-tools-extra/clang-tidy/ClangTidyOptions.h  |  4 
 .../clang-tidy/tool/ClangTidyMain.cpp| 16 
 .../clang-tidy/infrastructure/file-filter.cpp|  7 +++
 6 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp 
b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
index de2a3b51422a5..3cde0d2d68874 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -564,7 +564,8 @@ void 
ClangTidyDiagnosticConsumer::checkFilters(SourceLocation Location,
   StringRef FileName(File->getName());
   LastErrorRelatesToUserCode = LastErrorRelatesToUserCode ||
Sources.isInMainFile(Location) ||
-   getHeaderFilter()->match(FileName);
+   (getHeaderFilter()->match(FileName) &&
+!getExcludeHeaderFilter()->match(FileName));
 
   unsigned LineNumber = Sources.getExpansionLineNumber(Location);
   LastErrorPassesLineFilter =
@@ -578,6 +579,13 @@ llvm::Regex 
*ClangTidyDiagnosticConsumer::getHeaderFilter() {
   return HeaderFilter.get();
 }
 
+llvm::Regex *ClangTidyDiagnosticConsumer::getExcludeHeaderFilter() {
+  if (!ExcludeHeaderFilter)
+ExcludeHeaderFilter = std::make_unique(
+*Context.getOptions().ExcludeHeaderFilterRegex);
+  return ExcludeHeaderFilter.get();
+}
+
 void ClangTidyDiagnosticConsumer::removeIncompatibleErrors() {
   // Each error is modelled as the set of intervals in which it applies
   // replacements. To detect overlapping replacements, we use a sweep line
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h 
b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
index 9280eb1e1f218..a3add5d52778d 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
@@ -299,6 +299,10 @@ class ClangTidyDiagnosticConsumer : public 
DiagnosticConsumer {
   /// context.
   llvm::Regex *getHeaderFilter();
 
+  /// \brief Returns the \c ExcludeHeaderFilter constructed for the options set
+  /// in the context.
+  llvm::Regex *getExcludeHeaderFilter();
+
   /// Updates \c LastErrorRelatesToUserCode and LastErrorPassesLineFilter
   /// according to the diagnostic \p Location.
   void checkFilters(SourceLocation Location, const SourceManager );
@@ -313,6 +317,7 @@ class ClangTidyDiagnosticConsumer : public 
DiagnosticConsumer {
   bool EnableNolintBlocks;
   std::vector Errors;
   std::unique_ptr HeaderFilter;
+  std::unique_ptr ExcludeHeaderFilter;
   bool LastErrorRelatesToUserCode = false;
   bool LastErrorPassesLineFilter = false;
   bool LastErrorWasIgnored = false;
diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp 
b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
index cbf21a0e2ae34..254ce7fc60fc9 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
@@ -170,6 +170,8 @@ template <> struct MappingTraits {
 IO.mapOptional("ImplementationFileExtensions",
Options.ImplementationFileExtensions);
 IO.mapOptional("HeaderFilterRegex", Options.HeaderFilterRegex);
+IO.mapOptional("ExcludeHeaderFilterRegex",
+   Options.ExcludeHeaderFilterRegex);
 IO.mapOptional("FormatStyle", Options.FormatStyle);
 IO.mapOptional("User", Options.User);
 IO.mapOptional("CheckOptions", Options.CheckOptions);
@@ -192,6 +194,7 @@ ClangTidyOptions ClangTidyOptions::getDefaults() {
   Options.HeaderFileExtensions = {"", "h", "hh", "hpp", "hxx"};
   Options.ImplementationFileExtensions = {"c", "cc", "cpp", "cxx"};
   

[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)

2024-05-09 Thread Justin Cady via cfe-commits


@@ -311,7 +311,12 @@ ClangTidyDiagnosticConsumer::ClangTidyDiagnosticConsumer(
 : Context(Ctx), ExternalDiagEngine(ExternalDiagEngine),
   RemoveIncompatibleErrors(RemoveIncompatibleErrors),
   GetFixesFromNotes(GetFixesFromNotes),
-  EnableNolintBlocks(EnableNolintBlocks) {}
+  EnableNolintBlocks(EnableNolintBlocks) {
+
+  if (Context.getOptions().ExcludeHeaderFilterRegex)
+ExcludeHeaderFilter = std::make_unique(
+*Context.getOptions().ExcludeHeaderFilterRegex);

justincady wrote:

What makes you suspect it doesn't work? I did some testing by placing `abort()` 
in an else clause and it caused many unit tests to crash. That leads me to 
believe it remains `std::nullopt` when the option is not specified.

I will do some more thorough testing to confirm.

https://github.com/llvm/llvm-project/pull/91400
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)

2024-05-09 Thread Justin Cady via cfe-commits


@@ -311,7 +311,12 @@ ClangTidyDiagnosticConsumer::ClangTidyDiagnosticConsumer(
 : Context(Ctx), ExternalDiagEngine(ExternalDiagEngine),
   RemoveIncompatibleErrors(RemoveIncompatibleErrors),
   GetFixesFromNotes(GetFixesFromNotes),
-  EnableNolintBlocks(EnableNolintBlocks) {}
+  EnableNolintBlocks(EnableNolintBlocks) {
+
+  if (Context.getOptions().ExcludeHeaderFilterRegex)
+ExcludeHeaderFilter = std::make_unique(
+*Context.getOptions().ExcludeHeaderFilterRegex);
+}

justincady wrote:

Well, in the initial PR `ExcludeHeaderFilter` mirrored `HeaderFilter` behavior 
exactly. I changed it because @PiotrZSL made a nearly identical comment to 
yours about saving the call to `match` on an empty regex (which I think is 
handled in the latest revision).

I _could_ migrate `HeaderFilter` to mirror the new and improved 
`ExcludeHeaderFilter`...though I worry a bit about this change growing larger 
and larger. What do you think?

https://github.com/llvm/llvm-project/pull/91400
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)

2024-05-09 Thread Justin Cady via cfe-commits


@@ -562,9 +567,10 @@ void 
ClangTidyDiagnosticConsumer::checkFilters(SourceLocation Location,
   }
 
   StringRef FileName(File->getName());
-  LastErrorRelatesToUserCode = LastErrorRelatesToUserCode ||
-   Sources.isInMainFile(Location) ||
-   getHeaderFilter()->match(FileName);
+  LastErrorRelatesToUserCode =
+  LastErrorRelatesToUserCode || Sources.isInMainFile(Location) ||
+  (getHeaderFilter()->match(FileName) &&
+   (ExcludeHeaderFilter ? !ExcludeHeaderFilter->match(FileName) : true));

justincady wrote:

Thank you! Simplified that snippet and added the tests as suggested.

https://github.com/llvm/llvm-project/pull/91400
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)

2024-05-09 Thread Justin Cady via cfe-commits

https://github.com/justincady updated 
https://github.com/llvm/llvm-project/pull/91400

>From a5de583aa94ef794a083c8b27df6dc6fc0762cb7 Mon Sep 17 00:00:00 2001
From: Justin Cady 
Date: Tue, 7 May 2024 16:54:35 -0400
Subject: [PATCH 1/3] Add option to exclude headers from clang-tidy analysis

This is a renewed attempt to land @toddlipcon's D34654. The comments on
that patch indicate a broad desire for some ability to ignore headers.

After considering various options, including migrating to std::regex, I
believe this is the best path forward. It's intuitive to have separate
regexes for including headers versus excluding them, and this approach
has the added benefit of being completely opt-in. No existing configs
will break, regardless of existing HeaderFilterRegex values.

This functionality is useful for improving performance when analyzing a
targeted subset of code, as well as in cases where some collection of
headers cannot be modified (third party source, for example).
---
 .../clang-tidy/ClangTidyDiagnosticConsumer.cpp   | 10 +-
 .../clang-tidy/ClangTidyDiagnosticConsumer.h |  5 +
 .../clang-tidy/ClangTidyOptions.cpp  |  4 
 clang-tools-extra/clang-tidy/ClangTidyOptions.h  |  4 
 .../clang-tidy/tool/ClangTidyMain.cpp| 16 
 .../clang-tidy/infrastructure/file-filter.cpp|  7 +++
 6 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp 
b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
index de2a3b51422a5..3cde0d2d68874 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -564,7 +564,8 @@ void 
ClangTidyDiagnosticConsumer::checkFilters(SourceLocation Location,
   StringRef FileName(File->getName());
   LastErrorRelatesToUserCode = LastErrorRelatesToUserCode ||
Sources.isInMainFile(Location) ||
-   getHeaderFilter()->match(FileName);
+   (getHeaderFilter()->match(FileName) &&
+!getExcludeHeaderFilter()->match(FileName));
 
   unsigned LineNumber = Sources.getExpansionLineNumber(Location);
   LastErrorPassesLineFilter =
@@ -578,6 +579,13 @@ llvm::Regex 
*ClangTidyDiagnosticConsumer::getHeaderFilter() {
   return HeaderFilter.get();
 }
 
+llvm::Regex *ClangTidyDiagnosticConsumer::getExcludeHeaderFilter() {
+  if (!ExcludeHeaderFilter)
+ExcludeHeaderFilter = std::make_unique(
+*Context.getOptions().ExcludeHeaderFilterRegex);
+  return ExcludeHeaderFilter.get();
+}
+
 void ClangTidyDiagnosticConsumer::removeIncompatibleErrors() {
   // Each error is modelled as the set of intervals in which it applies
   // replacements. To detect overlapping replacements, we use a sweep line
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h 
b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
index 9280eb1e1f218..a3add5d52778d 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
@@ -299,6 +299,10 @@ class ClangTidyDiagnosticConsumer : public 
DiagnosticConsumer {
   /// context.
   llvm::Regex *getHeaderFilter();
 
+  /// \brief Returns the \c ExcludeHeaderFilter constructed for the options set
+  /// in the context.
+  llvm::Regex *getExcludeHeaderFilter();
+
   /// Updates \c LastErrorRelatesToUserCode and LastErrorPassesLineFilter
   /// according to the diagnostic \p Location.
   void checkFilters(SourceLocation Location, const SourceManager );
@@ -313,6 +317,7 @@ class ClangTidyDiagnosticConsumer : public 
DiagnosticConsumer {
   bool EnableNolintBlocks;
   std::vector Errors;
   std::unique_ptr HeaderFilter;
+  std::unique_ptr ExcludeHeaderFilter;
   bool LastErrorRelatesToUserCode = false;
   bool LastErrorPassesLineFilter = false;
   bool LastErrorWasIgnored = false;
diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp 
b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
index cbf21a0e2ae34..254ce7fc60fc9 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
@@ -170,6 +170,8 @@ template <> struct MappingTraits {
 IO.mapOptional("ImplementationFileExtensions",
Options.ImplementationFileExtensions);
 IO.mapOptional("HeaderFilterRegex", Options.HeaderFilterRegex);
+IO.mapOptional("ExcludeHeaderFilterRegex",
+   Options.ExcludeHeaderFilterRegex);
 IO.mapOptional("FormatStyle", Options.FormatStyle);
 IO.mapOptional("User", Options.User);
 IO.mapOptional("CheckOptions", Options.CheckOptions);
@@ -192,6 +194,7 @@ ClangTidyOptions ClangTidyOptions::getDefaults() {
   Options.HeaderFileExtensions = {"", "h", "hh", "hpp", "hxx"};
   Options.ImplementationFileExtensions = {"c", "cc", "cpp", "cxx"};
   

[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)

2024-05-08 Thread Justin Cady via cfe-commits


@@ -578,6 +579,13 @@ llvm::Regex 
*ClangTidyDiagnosticConsumer::getHeaderFilter() {
   return HeaderFilter.get();
 }
 
+llvm::Regex *ClangTidyDiagnosticConsumer::getExcludeHeaderFilter() {
+  if (!ExcludeHeaderFilter)
+ExcludeHeaderFilter = std::make_unique(
+*Context.getOptions().ExcludeHeaderFilterRegex);

justincady wrote:

I just pushed a commit that omits the check when `ExcludeHeaderFilter` is not 
set by the user. Please let me know if this aligns with your idea.

https://github.com/llvm/llvm-project/pull/91400
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)

2024-05-08 Thread Justin Cady via cfe-commits

https://github.com/justincady updated 
https://github.com/llvm/llvm-project/pull/91400

>From a5de583aa94ef794a083c8b27df6dc6fc0762cb7 Mon Sep 17 00:00:00 2001
From: Justin Cady 
Date: Tue, 7 May 2024 16:54:35 -0400
Subject: [PATCH 1/2] Add option to exclude headers from clang-tidy analysis

This is a renewed attempt to land @toddlipcon's D34654. The comments on
that patch indicate a broad desire for some ability to ignore headers.

After considering various options, including migrating to std::regex, I
believe this is the best path forward. It's intuitive to have separate
regexes for including headers versus excluding them, and this approach
has the added benefit of being completely opt-in. No existing configs
will break, regardless of existing HeaderFilterRegex values.

This functionality is useful for improving performance when analyzing a
targeted subset of code, as well as in cases where some collection of
headers cannot be modified (third party source, for example).
---
 .../clang-tidy/ClangTidyDiagnosticConsumer.cpp   | 10 +-
 .../clang-tidy/ClangTidyDiagnosticConsumer.h |  5 +
 .../clang-tidy/ClangTidyOptions.cpp  |  4 
 clang-tools-extra/clang-tidy/ClangTidyOptions.h  |  4 
 .../clang-tidy/tool/ClangTidyMain.cpp| 16 
 .../clang-tidy/infrastructure/file-filter.cpp|  7 +++
 6 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp 
b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
index de2a3b51422a5..3cde0d2d68874 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -564,7 +564,8 @@ void 
ClangTidyDiagnosticConsumer::checkFilters(SourceLocation Location,
   StringRef FileName(File->getName());
   LastErrorRelatesToUserCode = LastErrorRelatesToUserCode ||
Sources.isInMainFile(Location) ||
-   getHeaderFilter()->match(FileName);
+   (getHeaderFilter()->match(FileName) &&
+!getExcludeHeaderFilter()->match(FileName));
 
   unsigned LineNumber = Sources.getExpansionLineNumber(Location);
   LastErrorPassesLineFilter =
@@ -578,6 +579,13 @@ llvm::Regex 
*ClangTidyDiagnosticConsumer::getHeaderFilter() {
   return HeaderFilter.get();
 }
 
+llvm::Regex *ClangTidyDiagnosticConsumer::getExcludeHeaderFilter() {
+  if (!ExcludeHeaderFilter)
+ExcludeHeaderFilter = std::make_unique(
+*Context.getOptions().ExcludeHeaderFilterRegex);
+  return ExcludeHeaderFilter.get();
+}
+
 void ClangTidyDiagnosticConsumer::removeIncompatibleErrors() {
   // Each error is modelled as the set of intervals in which it applies
   // replacements. To detect overlapping replacements, we use a sweep line
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h 
b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
index 9280eb1e1f218..a3add5d52778d 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
@@ -299,6 +299,10 @@ class ClangTidyDiagnosticConsumer : public 
DiagnosticConsumer {
   /// context.
   llvm::Regex *getHeaderFilter();
 
+  /// \brief Returns the \c ExcludeHeaderFilter constructed for the options set
+  /// in the context.
+  llvm::Regex *getExcludeHeaderFilter();
+
   /// Updates \c LastErrorRelatesToUserCode and LastErrorPassesLineFilter
   /// according to the diagnostic \p Location.
   void checkFilters(SourceLocation Location, const SourceManager );
@@ -313,6 +317,7 @@ class ClangTidyDiagnosticConsumer : public 
DiagnosticConsumer {
   bool EnableNolintBlocks;
   std::vector Errors;
   std::unique_ptr HeaderFilter;
+  std::unique_ptr ExcludeHeaderFilter;
   bool LastErrorRelatesToUserCode = false;
   bool LastErrorPassesLineFilter = false;
   bool LastErrorWasIgnored = false;
diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp 
b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
index cbf21a0e2ae34..254ce7fc60fc9 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
@@ -170,6 +170,8 @@ template <> struct MappingTraits {
 IO.mapOptional("ImplementationFileExtensions",
Options.ImplementationFileExtensions);
 IO.mapOptional("HeaderFilterRegex", Options.HeaderFilterRegex);
+IO.mapOptional("ExcludeHeaderFilterRegex",
+   Options.ExcludeHeaderFilterRegex);
 IO.mapOptional("FormatStyle", Options.FormatStyle);
 IO.mapOptional("User", Options.User);
 IO.mapOptional("CheckOptions", Options.CheckOptions);
@@ -192,6 +194,7 @@ ClangTidyOptions ClangTidyOptions::getDefaults() {
   Options.HeaderFileExtensions = {"", "h", "hh", "hpp", "hxx"};
   Options.ImplementationFileExtensions = {"c", "cc", "cpp", "cxx"};
   

[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)

2024-05-08 Thread Justin Cady via cfe-commits


@@ -578,6 +579,13 @@ llvm::Regex 
*ClangTidyDiagnosticConsumer::getHeaderFilter() {
   return HeaderFilter.get();
 }
 
+llvm::Regex *ClangTidyDiagnosticConsumer::getExcludeHeaderFilter() {
+  if (!ExcludeHeaderFilter)
+ExcludeHeaderFilter = std::make_unique(
+*Context.getOptions().ExcludeHeaderFilterRegex);

justincady wrote:

Ok, thanks for clarifying. I will look into this.

https://github.com/llvm/llvm-project/pull/91400
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)

2024-05-08 Thread Justin Cady via cfe-commits


@@ -578,6 +579,13 @@ llvm::Regex 
*ClangTidyDiagnosticConsumer::getHeaderFilter() {
   return HeaderFilter.get();
 }
 
+llvm::Regex *ClangTidyDiagnosticConsumer::getExcludeHeaderFilter() {
+  if (!ExcludeHeaderFilter)
+ExcludeHeaderFilter = std::make_unique(
+*Context.getOptions().ExcludeHeaderFilterRegex);

justincady wrote:

I'm not sure I follow here. If `ExcludeHeaderFilterRegex` isn't set via the 
command line or config, it will be initialized to an empty string. Then the 
`llvm::Regex` will be constructed with that empty string.

Is that different than what you mean?

https://github.com/llvm/llvm-project/pull/91400
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)

2024-05-08 Thread Justin Cady via cfe-commits

justincady wrote:

> I wonder what is the target scenario for this feature.

This PR addresses clang-tidy's lack of ability to ignore some set of headers 
when analyzing a file (most commonly third party code that cannot be modified).

>  I remember regex can excluding some pattern, the we can exclude header file 
> in `HeaderFilterRegex`.

The underlying regex implementation for `HeaderFilterRegex` is `llvm::Regex` 
which does not support negative lookahead. See:

- https://reviews.llvm.org/D34654
- https://lists.llvm.org/pipermail/cfe-dev/2015-November/046203.html
- https://github.com/llvm/llvm-project/issues/25590

As I mentioned in the description, one option to allow exclusion of headers 
would be migrating to `std::regex`. But I think that has the potential to break 
existing configs, which is why reviving/reimplementing D34654 seems like the 
best path forward to me.

https://github.com/llvm/llvm-project/pull/91400
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)

2024-05-07 Thread Justin Cady via cfe-commits

https://github.com/justincady created 
https://github.com/llvm/llvm-project/pull/91400

This is a renewed attempt to land @toddlipcon's D34654. The comments on
that patch indicate a broad desire for some ability to ignore headers.

After considering various options, including migrating to std::regex, I
believe this is the best path forward. It's intuitive to have separate
regexes for including headers versus excluding them, and this approach
has the added benefit of being completely opt-in. No existing configs
will break, regardless of existing HeaderFilterRegex values.

This functionality is useful for improving performance when analyzing a
targeted subset of code, as well as in cases where some collection of
headers cannot be modified (third party source, for example).


>From a5de583aa94ef794a083c8b27df6dc6fc0762cb7 Mon Sep 17 00:00:00 2001
From: Justin Cady 
Date: Tue, 7 May 2024 16:54:35 -0400
Subject: [PATCH] Add option to exclude headers from clang-tidy analysis

This is a renewed attempt to land @toddlipcon's D34654. The comments on
that patch indicate a broad desire for some ability to ignore headers.

After considering various options, including migrating to std::regex, I
believe this is the best path forward. It's intuitive to have separate
regexes for including headers versus excluding them, and this approach
has the added benefit of being completely opt-in. No existing configs
will break, regardless of existing HeaderFilterRegex values.

This functionality is useful for improving performance when analyzing a
targeted subset of code, as well as in cases where some collection of
headers cannot be modified (third party source, for example).
---
 .../clang-tidy/ClangTidyDiagnosticConsumer.cpp   | 10 +-
 .../clang-tidy/ClangTidyDiagnosticConsumer.h |  5 +
 .../clang-tidy/ClangTidyOptions.cpp  |  4 
 clang-tools-extra/clang-tidy/ClangTidyOptions.h  |  4 
 .../clang-tidy/tool/ClangTidyMain.cpp| 16 
 .../clang-tidy/infrastructure/file-filter.cpp|  7 +++
 6 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp 
b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
index de2a3b51422a5..3cde0d2d68874 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -564,7 +564,8 @@ void 
ClangTidyDiagnosticConsumer::checkFilters(SourceLocation Location,
   StringRef FileName(File->getName());
   LastErrorRelatesToUserCode = LastErrorRelatesToUserCode ||
Sources.isInMainFile(Location) ||
-   getHeaderFilter()->match(FileName);
+   (getHeaderFilter()->match(FileName) &&
+!getExcludeHeaderFilter()->match(FileName));
 
   unsigned LineNumber = Sources.getExpansionLineNumber(Location);
   LastErrorPassesLineFilter =
@@ -578,6 +579,13 @@ llvm::Regex 
*ClangTidyDiagnosticConsumer::getHeaderFilter() {
   return HeaderFilter.get();
 }
 
+llvm::Regex *ClangTidyDiagnosticConsumer::getExcludeHeaderFilter() {
+  if (!ExcludeHeaderFilter)
+ExcludeHeaderFilter = std::make_unique(
+*Context.getOptions().ExcludeHeaderFilterRegex);
+  return ExcludeHeaderFilter.get();
+}
+
 void ClangTidyDiagnosticConsumer::removeIncompatibleErrors() {
   // Each error is modelled as the set of intervals in which it applies
   // replacements. To detect overlapping replacements, we use a sweep line
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h 
b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
index 9280eb1e1f218..a3add5d52778d 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
@@ -299,6 +299,10 @@ class ClangTidyDiagnosticConsumer : public 
DiagnosticConsumer {
   /// context.
   llvm::Regex *getHeaderFilter();
 
+  /// \brief Returns the \c ExcludeHeaderFilter constructed for the options set
+  /// in the context.
+  llvm::Regex *getExcludeHeaderFilter();
+
   /// Updates \c LastErrorRelatesToUserCode and LastErrorPassesLineFilter
   /// according to the diagnostic \p Location.
   void checkFilters(SourceLocation Location, const SourceManager );
@@ -313,6 +317,7 @@ class ClangTidyDiagnosticConsumer : public 
DiagnosticConsumer {
   bool EnableNolintBlocks;
   std::vector Errors;
   std::unique_ptr HeaderFilter;
+  std::unique_ptr ExcludeHeaderFilter;
   bool LastErrorRelatesToUserCode = false;
   bool LastErrorPassesLineFilter = false;
   bool LastErrorWasIgnored = false;
diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp 
b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
index cbf21a0e2ae34..254ce7fc60fc9 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
@@ -170,6 +170,8 @@ 

[clang-tools-extra] [clang-tidy] Fix false-positives in readability-container-size-empty (PR #74140)

2024-01-12 Thread Justin Cady via cfe-commits

https://github.com/justincady approved this pull request.

[Context](https://github.com/llvm/llvm-project/pull/77203#pullrequestreview-1818501835).

LGTM.

https://github.com/llvm/llvm-project/pull/74140
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Fix false-positives in misc-static-assert caused by non-constexpr variables (PR #77203)

2024-01-12 Thread Justin Cady via cfe-commits

https://github.com/justincady approved this pull request.

Context: I have limited experience writing AST matchers, but I saw [the request 
for 
reviewers](https://discourse.llvm.org/t/clang-tidy-18-reviewers-wanted/76108). 
I'm basing this review on that limited experience and the tests put in place 
with this diff.

On those grounds, these changes LGTM.

https://github.com/llvm/llvm-project/pull/77203
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang codegen][regression] Add dso_local/hidden/etc. markings to VTT definitions and declarations (PR #72452)

2023-11-21 Thread Justin Cady via cfe-commits

https://github.com/justincady commented:

LGTM as well, as the original fix remains in place.

https://github.com/llvm/llvm-project/pull/72452
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits