Repository: opencv
Issue: Add IWYU pragmas to support Clang's `misc-include-cleaner`'s findings regarding selection of `#include`s
Labels: feature,pr: Discussion Required

### Describe the feature and motivation

It would be nice if OpenCV's headers used the [IWYU pragmas](https://clangd.llvm.org/design/include-cleaner#iwyu-pragmas) that Clang's include-cleaner tool supports for identifying the correct OpenCV header to include for a given type and/or function.

My understanding of OpenCV is that the "correct" header to include for using any given type or function is the main forwarding header associated with the OpenCV package (e.g., for `cv::Mat`, don't directly include `mat.hpp`, include `core.hpp` instead since `cv::Mat` is in the `core` package). While I have not been able to find any documentation that explicitly says this, most examples I've found use the package includes. This also seems to be consistent with how the libraries are set up, where some templated implementations are not in the header that declares them, but are in other headers that are only properly reachable via the package's main forwarding header (e.g., the underlying implementation of `forEach` in the `Mat` types is not present in `mat.hpp`, nor is it transitively included by `mat.hpp`). Ensuring use of the forwarding header also ensures that all of the template specializations that are in different headers (e.g., for `cv::DataType`) from the original declaration are always available, which helps avoid ODR issues.

The current lack of the pragmas means that when code is analyzed with Clang's diagnostic tools (i.e., for [`include-cleaner`](https://clangd.llvm.org/design/include-cleaner)), it currently suggests removing the package's forwarding header in favor of the class's or function's specific header (e.g., it will suggest removing `core.hpp` and adding `mat.hpp` when a `cv::Mat` is used in external code). This suggestion seems to be counter to most examples, and can lead to breakage (in the case of `forEach` above) or maybe some ODR issues if followed.

Assuming that the forwarding headers are the intended and proper way to use OpenCV libraries, this feature request makes the following proposal:

* To support findings when OpenCV is used by external code:
  * In the forwarding headers (e.g., `core.hpp`), add [`// IWYU pragma: begin_exports`/`end_exports`](https://github.com/include-what-you-use/include-what-you-use/blob/master/docs/IWYUPragmas.md#iwyu-pragma-begin_exportsend_exports) to surround all of the headers that are intended as public exports of that main header.
  * In the non-forwarding headers (e.g., `mat.hpp`), add [`// IWYU pragma: private, include "..."`](https://github.com/include-what-you-use/include-what-you-use/blob/master/docs/IWYUPragmas.md#iwyu-pragma-private) near the top of the file so that types and functions exposed by that header provide findings that suggest the forwarding header.
* To support findings when analyzing OpenCV itself:
  * In the non-forwarding headers (e.g., `mat.hpp`), add [`// IWYU pragma: friend "..."`](https://github.com/include-what-you-use/include-what-you-use/blob/master/docs/IWYUPragmas.md#iwyu-pragma-friend) near the `private` pragma listed above so that code files within a given package are still allowed to directly include the relevant non-forwarding header without producing a `misc-include-cleaner` finding.

The first entry should provide the most help when writing new code when manually adding includes as `include-cleaner` won't try to remove them. The second entry should provide the most help when cleaning up existing code, as `include-cleaner` should try to remove the specific includes and consolidate them back to the forwarding headers. The third entry is only useful if `include-cleaner` is used on OpenCV itself to clean it its own cross-module includes.

As an example regarding other projects that use these pragmas, Eigen uses these pragmas in its code: [export example](https://gitlab.com/libeigen/eigen/-/blob/master/Eigen/Core#L165), [private example](https://gitlab.com/libeigen/eigen/-/blob/master/Eigen/src/Core/Array.h#L13).

If my understanding of the proper includes to use with OpenCV are incorrect, and the specific headers are the correct ones to use, then perhaps I should submit bugs where those specific headers do not appear to work as intended.

Thanks for your consideration!

### Additional context

_No response_