1 //=====-- ModularizeUtilities.h - Utilities for modularize -*- 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 /// \brief ModularizeUtilities class definition.
11 ///
12 //===--------------------------------------------------------------------===//
13 
14 #ifndef MODULARIZEUTILITIES_H
15 #define MODULARIZEUTILITIES_H
16 
17 #include "Modularize.h"
18 #include "clang/Basic/Diagnostic.h"
19 #include "clang/Basic/FileManager.h"
20 #include "clang/Basic/LangOptions.h"
21 #include "clang/Basic/TargetInfo.h"
22 #include "clang/Basic/TargetOptions.h"
23 #include "clang/Frontend/TextDiagnosticPrinter.h"
24 #include "clang/Lex/HeaderSearch.h"
25 #include "clang/Lex/HeaderSearchOptions.h"
26 #include "clang/Lex/ModuleMap.h"
27 #include "clang/Lex/Preprocessor.h"
28 #include "llvm/ADT/SmallVector.h"
29 #include "llvm/ADT/StringSet.h"
30 #include <string>
31 #include <vector>
32 
33 namespace Modularize {
34 
35 /// Modularize utilities class.
36 /// Support functions and data for modularize.
37 class ModularizeUtilities {
38 public:
39   // Input arguments.
40 
41   /// The input file paths.
42   std::vector<std::string> InputFilePaths;
43   /// The header prefix.
44   llvm::StringRef HeaderPrefix;
45   /// The path of problem files list file.
46   llvm::StringRef ProblemFilesPath;
47 
48   // Output data.
49 
50   /// List of top-level header files.
51   llvm::SmallVector<std::string, 32> HeaderFileNames;
52   /// Map of top-level header file dependencies.
53   DependencyMap Dependencies;
54   /// True if we have module maps.
55   bool HasModuleMap;
56   /// Missing header count.
57   int MissingHeaderCount;
58   /// List of header files with no problems during the first pass,
59   /// that is, no compile errors.
60   llvm::SmallVector<std::string, 32> GoodFileNames;
61   /// List of header files with problems.
62   llvm::SmallVector<std::string, 32> ProblemFileNames;
63 
64   // Functions.
65 
66   /// Constructor.
67   /// You can use the static createModularizeUtilities to create an instance
68   /// of this object.
69   /// \param InputPaths The input file paths.
70   /// \param Prefix The headear path prefix.
71   /// \param ProblemFilesListPath The problem header list path.
72   ModularizeUtilities(std::vector<std::string> &InputPaths,
73                       llvm::StringRef Prefix,
74                       llvm::StringRef ProblemFilesListPath);
75 
76   /// Create instance of ModularizeUtilities.
77   /// \param InputPaths The input file paths.
78   /// \param Prefix The headear path prefix.
79   /// \param ProblemFilesListPath The problem header list path.
80   /// \returns Initialized ModularizeUtilities object.
81   static ModularizeUtilities *createModularizeUtilities(
82       std::vector<std::string> &InputPaths,
83       llvm::StringRef Prefix,
84       llvm::StringRef ProblemFilesListPath);
85 
86   /// Load header list and dependencies.
87   /// \returns std::error_code.
88   std::error_code loadAllHeaderListsAndDependencies();
89 
90   /// Do coverage checks.
91   /// For each loaded module map, do header coverage check.
92   /// Starting from the directory of the module.map file,
93   /// Find all header files, optionally looking only at files
94   /// covered by the include path options, and compare against
95   /// the headers referenced by the module.map file.
96   /// Display warnings for unaccounted-for header files.
97   /// \param IncludePaths The include paths to check for files.
98   ///   (Note that other directories above these paths are ignored.
99   ///   To expect all files to be accounted for from the module.modulemap
100   ///   file directory on down, leave this empty.)
101   /// \param CommandLine Compile command line arguments.
102   /// \returns 0 if there were no errors or warnings, 1 if there
103   ///   were warnings, 2 if any other problem, such as a bad
104   ///   module map path argument was specified.
105   std::error_code doCoverageCheck(std::vector<std::string> &IncludePaths,
106                                   llvm::ArrayRef<std::string> CommandLine);
107 
108   /// Add unique problem file.
109   /// Also standardizes the path.
110   /// \param FilePath Problem file path.
111   void addUniqueProblemFile(std::string FilePath);
112 
113   /// Add file with no compile errors.
114   /// Also standardizes the path.
115   /// \param FilePath Problem file path.
116   void addNoCompileErrorsFile(std::string FilePath);
117 
118   /// List problem files.
119   void displayProblemFiles();
120 
121   /// List files with no problems.
122   void displayGoodFiles();
123 
124   /// List files with problem files commented out.
125   void displayCombinedFiles();
126 
127   // Internal.
128 
129 protected:
130 
131   /// Load single header list and dependencies.
132   /// \param InputPath The input file path.
133   /// \returns std::error_code.
134   std::error_code loadSingleHeaderListsAndDependencies(
135       llvm::StringRef InputPath);
136 
137   /// Load problem header list.
138   /// \param InputPath The input file path.
139   /// \returns std::error_code.
140   std::error_code loadProblemHeaderList(
141     llvm::StringRef InputPath);
142 
143   /// Load single module map and extract header file list.
144   /// \param InputPath The input file path.
145   /// \returns std::error_code.
146   std::error_code loadModuleMap(
147     llvm::StringRef InputPath);
148 
149   /// Collect module Map headers.
150   /// Walks the modules and collects referenced headers into
151   /// HeaderFileNames.
152   /// \param ModMap A loaded module map object.
153   /// \return True if no errors.
154   bool collectModuleMapHeaders(clang::ModuleMap *ModMap);
155 
156   /// Collect referenced headers from one module.
157   /// Collects the headers referenced in the given module into
158   /// HeaderFileNames.
159   /// \param Mod The module reference.
160   /// \return True if no errors.
161   bool collectModuleHeaders(const clang::Module &Mod);
162 
163   /// Collect headers from an umbrella directory.
164   /// \param UmbrellaDirName The umbrella directory name.
165   /// \return True if no errors.
166   bool collectUmbrellaHeaders(llvm::StringRef UmbrellaDirName,
167     DependentsVector &Dependents);
168 
169 public:
170 
171   // Utility functions.
172 
173   /// Convert header path to canonical form.
174   /// The canonical form is basically just use forward slashes,
175   /// and remove "./".
176   /// \param FilePath The file path.
177   /// \returns The file path in canonical form.
178   static std::string getCanonicalPath(llvm::StringRef FilePath);
179 
180   /// Check for header file extension.
181   /// If the file extension is .h, .inc, or missing, it's
182   /// assumed to be a header.
183   /// \param FileName The file name.  Must not be a directory.
184   /// \returns true if it has a header extension or no extension.
185   static bool isHeader(llvm::StringRef FileName);
186 
187   /// Get directory path component from file path.
188   /// \returns the component of the given path, which will be
189   /// relative if the given path is relative, absolute if the
190   /// given path is absolute, or "." if the path has no leading
191   /// path component.
192   static std::string getDirectoryFromPath(llvm::StringRef Path);
193 
194   // Internal data.
195 
196   /// Options controlling the language variant.
197   std::shared_ptr<clang::LangOptions> LangOpts;
198   /// Diagnostic IDs.
199   const llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagIDs;
200   /// Options controlling the diagnostic engine.
201   llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagnosticOpts;
202   /// Diagnostic consumer.
203   clang::TextDiagnosticPrinter DC;
204   /// Diagnostic engine.
205   llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> Diagnostics;
206   /// Options controlling the target.
207   std::shared_ptr<clang::TargetOptions> TargetOpts;
208   /// Target information.
209   llvm::IntrusiveRefCntPtr<clang::TargetInfo> Target;
210   /// Options controlling the file system manager.
211   clang::FileSystemOptions FileSystemOpts;
212   /// File system manager.
213   llvm::IntrusiveRefCntPtr<clang::FileManager> FileMgr;
214   /// Source manager.
215   llvm::IntrusiveRefCntPtr<clang::SourceManager> SourceMgr;
216   /// Header search manager.
217   std::unique_ptr<clang::HeaderSearch> HeaderInfo;
218   // The loaded module map objects.
219   std::vector<std::unique_ptr<clang::ModuleMap>> ModuleMaps;
220 };
221 
222 } // end namespace Modularize
223 
224 #endif // MODULARIZEUTILITIES_H
225