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 
47   // Output data.
48 
49   /// List of top-level header files.
50   llvm::SmallVector<std::string, 32> HeaderFileNames;
51   /// Map of top-level header file dependencies.
52   DependencyMap Dependencies;
53   /// True if we have module maps.
54   bool HasModuleMap;
55 
56   // Functions.
57 
58   /// Constructor.
59   /// You can use the static createModularizeUtilities to create an instance
60   /// of this object.
61   /// \param InputPaths The input file paths.
62   /// \param Prefix The headear path prefix.
63   ModularizeUtilities(std::vector<std::string> &InputPaths,
64                       llvm::StringRef Prefix);
65 
66   /// Create instance of ModularizeUtilities.
67   /// \param InputPaths The input file paths.
68   /// \param Prefix The headear path prefix.
69   /// \returns Initialized ModularizeUtilities object.
70   static ModularizeUtilities *createModularizeUtilities(
71       std::vector<std::string> &InputPaths,
72       llvm::StringRef Prefix);
73 
74   /// Load header list and dependencies.
75   /// \returns std::error_code.
76   std::error_code loadAllHeaderListsAndDependencies();
77 
78   /// Do coverage checks.
79   /// For each loaded module map, do header coverage check.
80   /// Starting from the directory of the module.map file,
81   /// Find all header files, optionally looking only at files
82   /// covered by the include path options, and compare against
83   /// the headers referenced by the module.map file.
84   /// Display warnings for unaccounted-for header files.
85   /// \param IncludePaths The include paths to check for files.
86   ///   (Note that other directories above these paths are ignored.
87   ///   To expect all files to be accounted for from the module.modulemap
88   ///   file directory on down, leave this empty.)
89   /// \param CommandLine Compile command line arguments.
90   /// \returns 0 if there were no errors or warnings, 1 if there
91   ///   were warnings, 2 if any other problem, such as a bad
92   ///   module map path argument was specified.
93   std::error_code doCoverageCheck(std::vector<std::string> &IncludePaths,
94                                   llvm::ArrayRef<std::string> CommandLine);
95 
96   // Internal.
97 
98 protected:
99 
100   /// Load single header list and dependencies.
101   /// \param InputPath The input file path.
102   /// \returns std::error_code.
103   std::error_code loadSingleHeaderListsAndDependencies(
104       llvm::StringRef InputPath);
105 
106   /// Load single module map and extract header file list.
107   /// \param InputPath The input file path.
108   /// \returns std::error_code.
109   std::error_code loadModuleMap(
110     llvm::StringRef InputPath);
111 
112   /// Collect module Map headers.
113   /// Walks the modules and collects referenced headers into
114   /// HeaderFileNames.
115   /// \param ModMap A loaded module map object.
116   /// \return True if no errors.
117   bool collectModuleMapHeaders(clang::ModuleMap *ModMap);
118 
119   /// Collect referenced headers from one module.
120   /// Collects the headers referenced in the given module into
121   /// HeaderFileNames.
122   /// \param Mod The module reference.
123   /// \return True if no errors.
124   bool collectModuleHeaders(const clang::Module &Mod);
125 
126   /// Collect headers from an umbrella directory.
127   /// \param UmbrellaDirName The umbrella directory name.
128   /// \return True if no errors.
129   bool collectUmbrellaHeaders(llvm::StringRef UmbrellaDirName,
130     DependentsVector &Dependents);
131 
132 public:
133 
134   // Utility functions.
135 
136   /// Convert header path to canonical form.
137   /// The canonical form is basically just use forward slashes,
138   /// and remove "./".
139   /// \param FilePath The file path.
140   /// \returns The file path in canonical form.
141   static std::string getCanonicalPath(llvm::StringRef FilePath);
142 
143   /// Check for header file extension.
144   /// If the file extension is .h, .inc, or missing, it's
145   /// assumed to be a header.
146   /// \param FileName The file name.  Must not be a directory.
147   /// \returns true if it has a header extension or no extension.
148   static bool isHeader(llvm::StringRef FileName);
149 
150   /// Get directory path component from file path.
151   /// \returns the component of the given path, which will be
152   /// relative if the given path is relative, absolute if the
153   /// given path is absolute, or "." if the path has no leading
154   /// path component.
155   static std::string getDirectoryFromPath(llvm::StringRef Path);
156 
157   // Internal data.
158 
159   /// Options controlling the language variant.
160   std::shared_ptr<clang::LangOptions> LangOpts;
161   /// Diagnostic IDs.
162   const llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagIDs;
163   /// Options controlling the diagnostic engine.
164   llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagnosticOpts;
165   /// Diagnostic consumer.
166   clang::TextDiagnosticPrinter DC;
167   /// Diagnostic engine.
168   llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> Diagnostics;
169   /// Options controlling the target.
170   std::shared_ptr<clang::TargetOptions> TargetOpts;
171   /// Target information.
172   llvm::IntrusiveRefCntPtr<clang::TargetInfo> Target;
173   /// Options controlling the file system manager.
174   clang::FileSystemOptions FileSystemOpts;
175   /// File system manager.
176   llvm::IntrusiveRefCntPtr<clang::FileManager> FileMgr;
177   /// Source manager.
178   llvm::IntrusiveRefCntPtr<clang::SourceManager> SourceMgr;
179   /// Options controlling the \#include directive.
180   llvm::IntrusiveRefCntPtr<clang::HeaderSearchOptions> HeaderSearchOpts;
181   /// Header search manager.
182   std::unique_ptr<clang::HeaderSearch> HeaderInfo;
183   // The loaded module map objects.
184   std::vector<std::unique_ptr<clang::ModuleMap>> ModuleMaps;
185 };
186 
187 } // end namespace Modularize
188 
189 #endif // MODULARIZEUTILITIES_H
190