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