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