xref: /llvm-project/clang-tools-extra/modularize/CoverageChecker.h (revision d768bf994f508d7eaf9541a568be3d71096febf5)
1 //===-- CoverageChecker.h - Module map coverage checker -*- C++ -*-------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===--------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// Definitions for CoverageChecker.
11 ///
12 //===--------------------------------------------------------------------===//
13 
14 #ifndef COVERAGECHECKER_H
15 #define COVERAGECHECKER_H
16 
17 #include "clang/Basic/Diagnostic.h"
18 #include "clang/Basic/FileManager.h"
19 #include "clang/Basic/LangOptions.h"
20 #include "clang/Basic/TargetInfo.h"
21 #include "clang/Basic/TargetOptions.h"
22 #include "clang/Frontend/TextDiagnosticPrinter.h"
23 #include "clang/Lex/HeaderSearch.h"
24 #include "clang/Lex/HeaderSearchOptions.h"
25 #include "clang/Lex/ModuleMap.h"
26 #include "clang/Lex/Preprocessor.h"
27 #include "llvm/ADT/StringSet.h"
28 #include "llvm/TargetParser/Host.h"
29 #include <string>
30 #include <vector>
31 
32 namespace Modularize {
33 
34 /// Module map checker class.
35 /// This is the heart of the checker.
36 /// The doChecks function does the main work.
37 /// The data members store the options and internally collected data.
38 class CoverageChecker {
39   // Checker arguments.
40 
41   /// The module.modulemap file path. Can be relative or absolute.
42   llvm::StringRef ModuleMapPath;
43   /// The include paths to check for files.
44   /// (Note that other directories above these paths are ignored.
45   /// To expect all files to be accounted for from the module.modulemap
46   /// file directory on down, leave this empty.)
47   std::vector<std::string> IncludePaths;
48   /// The remaining arguments, to be passed to the front end.
49   llvm::ArrayRef<std::string> CommandLine;
50   /// The module map.
51   clang::ModuleMap *ModMap;
52 
53   // Internal data.
54 
55   /// Directory containing the module map.
56   /// Might be relative to the current directory, or absolute.
57   std::string ModuleMapDirectory;
58   /// Set of all the headers found in the module map.
59   llvm::StringSet<llvm::MallocAllocator> ModuleMapHeadersSet;
60   /// All the headers found in the file system starting at the
61   /// module map, or the union of those from the include paths.
62   std::vector<std::string> FileSystemHeaders;
63   /// Headers found in file system, but not in module map.
64   std::vector<std::string> UnaccountedForHeaders;
65 
66 public:
67   /// Constructor.
68   /// You can use the static createCoverageChecker to create an instance
69   /// of this object.
70   /// \param ModuleMapPath The module.modulemap file path.
71   ///   Can be relative or absolute.
72   /// \param IncludePaths The include paths to check for files.
73   ///   (Note that other directories above these paths are ignored.
74   ///   To expect all files to be accounted for from the module.modulemap
75   ///   file directory on down, leave this empty.)
76   /// \param CommandLine Compile command line arguments.
77   /// \param ModuleMap The module map to check.
78   CoverageChecker(llvm::StringRef ModuleMapPath,
79     std::vector<std::string> &IncludePaths,
80     llvm::ArrayRef<std::string> CommandLine,
81     clang::ModuleMap *ModuleMap);
82 
83   /// Create instance of CoverageChecker.
84   /// \param ModuleMapPath The module.modulemap file path.
85   ///   Can be relative or absolute.
86   /// \param IncludePaths The include paths to check for files.
87   ///   (Note that other directories above these paths are ignored.
88   ///   To expect all files to be accounted for from the module.modulemap
89   ///   file directory on down, leave this empty.)
90   /// \param CommandLine Compile command line arguments.
91   /// \param ModuleMap The module map to check.
92   /// \returns Initialized CoverageChecker object.
93   static std::unique_ptr<CoverageChecker> createCoverageChecker(
94       llvm::StringRef ModuleMapPath, std::vector<std::string> &IncludePaths,
95       llvm::ArrayRef<std::string> CommandLine, clang::ModuleMap *ModuleMap);
96 
97   /// Do checks.
98   /// Starting from the directory of the module.modulemap file,
99   /// Find all header files, optionally looking only at files
100   /// covered by the include path options, and compare against
101   /// the headers referenced by the module.modulemap file.
102   /// Display warnings for unaccounted-for header files.
103   /// \returns 0 if there were no errors or warnings, 1 if there
104   ///   were warnings, 2 if any other problem, such as a bad
105   ///   module map path argument was specified.
106   std::error_code doChecks();
107 
108   // The following functions are called by doChecks.
109 
110   /// Collect module headers.
111   /// Walks the modules and collects referenced headers into
112   /// ModuleMapHeadersSet.
113   void collectModuleHeaders();
114 
115   /// Collect referenced headers from one module.
116   /// Collects the headers referenced in the given module into
117   /// ModuleMapHeadersSet.
118   /// \param Mod The module reference.
119   /// \return True if no errors.
120   bool collectModuleHeaders(const clang::Module &Mod);
121 
122   /// Collect headers from an umbrella directory.
123   /// \param UmbrellaDirName The umbrella directory name.
124   /// \return True if no errors.
125   bool collectUmbrellaHeaders(llvm::StringRef UmbrellaDirName);
126 
127   /// Collect headers referenced from an umbrella file.
128   /// \param UmbrellaHeaderName The umbrella file path.
129   /// \return True if no errors.
130   bool collectUmbrellaHeaderHeaders(llvm::StringRef UmbrellaHeaderName);
131 
132   /// Called from CoverageCheckerCallbacks to track a header included
133   /// from an umbrella header.
134   /// \param HeaderName The header file path.
135   void collectUmbrellaHeaderHeader(llvm::StringRef HeaderName);
136 
137   /// Collect file system header files.
138   /// This function scans the file system for header files,
139   /// starting at the directory of the module.modulemap file,
140   /// optionally filtering out all but the files covered by
141   /// the include path options.
142   /// \returns True if no errors.
143   bool collectFileSystemHeaders();
144 
145   /// Collect file system header files from the given path.
146   /// This function scans the file system for header files,
147   /// starting at the given directory, which is assumed to be
148   /// relative to the directory of the module.modulemap file.
149   /// \returns True if no errors.
150   bool collectFileSystemHeaders(llvm::StringRef IncludePath);
151 
152   /// Find headers unaccounted-for in module map.
153   /// This function compares the list of collected header files
154   /// against those referenced in the module map.  Display
155   /// warnings for unaccounted-for header files.
156   /// Save unaccounted-for file list for possible.
157   /// fixing action.
158   void findUnaccountedForHeaders();
159 };
160 
161 } // end namespace Modularize
162 
163 #endif // COVERAGECHECKER_H
164