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