1 //===-- CoverageChecker.h - Module map coverage checker -*- 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 Definitions for CoverageChecker. 12 /// 13 //===--------------------------------------------------------------------===// 14 15 #ifndef COVERAGECHECKER_H 16 #define COVERAGECHECKER_H 17 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/StringSet.h" 29 #include "llvm/Support/Host.h" 30 #include <string> 31 #include <vector> 32 33 namespace Modularize { 34 35 /// Subclass TargetOptions so we can construct it inline with 36 /// the minimal option, the triple. 37 class ModuleMapTargetOptions : public clang::TargetOptions { 38 public: 39 ModuleMapTargetOptions() { Triple = llvm::sys::getDefaultTargetTriple(); } 40 }; 41 42 /// Module map checker class. 43 /// This is the heart of the checker. 44 /// The doChecks function does the main work. 45 /// The data members store the options and internally collected data. 46 class CoverageChecker { 47 // Checker arguments. 48 49 /// The module.modulemap file path. Can be relative or absolute. 50 llvm::StringRef ModuleMapPath; 51 /// The include paths to check for files. 52 /// (Note that other directories above these paths are ignored. 53 /// To expect all files to be accounted for from the module.modulemap 54 /// file directory on down, leave this empty.) 55 std::vector<std::string> IncludePaths; 56 /// The remaining arguments, to be passed to the front end. 57 llvm::ArrayRef<std::string> CommandLine; 58 /// The module map. 59 clang::ModuleMap *ModMap; 60 61 // Internal data. 62 63 /// Directory containing the module map. 64 /// Might be relative to the current directory, or absolute. 65 std::string ModuleMapDirectory; 66 /// Set of all the headers found in the module map. 67 llvm::StringSet<llvm::MallocAllocator> ModuleMapHeadersSet; 68 /// All the headers found in the file system starting at the 69 /// module map, or the union of those from the include paths. 70 std::vector<std::string> FileSystemHeaders; 71 /// Headers found in file system, but not in module map. 72 std::vector<std::string> UnaccountedForHeaders; 73 74 public: 75 /// Constructor. 76 /// You can use the static createCoverageChecker to create an instance 77 /// of this object. 78 /// \param ModuleMapPath The module.modulemap file path. 79 /// Can be relative or absolute. 80 /// \param IncludePaths The include paths to check for files. 81 /// (Note that other directories above these paths are ignored. 82 /// To expect all files to be accounted for from the module.modulemap 83 /// file directory on down, leave this empty.) 84 /// \param CommandLine Compile command line arguments. 85 /// \param ModuleMap The module map to check. 86 CoverageChecker(llvm::StringRef ModuleMapPath, 87 std::vector<std::string> &IncludePaths, 88 llvm::ArrayRef<std::string> CommandLine, 89 clang::ModuleMap *ModuleMap); 90 91 /// Create instance of CoverageChecker. 92 /// \param ModuleMapPath The module.modulemap file path. 93 /// Can be relative or absolute. 94 /// \param IncludePaths The include paths to check for files. 95 /// (Note that other directories above these paths are ignored. 96 /// To expect all files to be accounted for from the module.modulemap 97 /// file directory on down, leave this empty.) 98 /// \param CommandLine Compile command line arguments. 99 /// \param ModuleMap The module map to check. 100 /// \returns Initialized CoverageChecker object. 101 static CoverageChecker *createCoverageChecker( 102 llvm::StringRef ModuleMapPath, std::vector<std::string> &IncludePaths, 103 llvm::ArrayRef<std::string> CommandLine, 104 clang::ModuleMap *ModuleMap); 105 106 /// Do checks. 107 /// Starting from the directory of the module.modulemap file, 108 /// Find all header files, optionally looking only at files 109 /// covered by the include path options, and compare against 110 /// the headers referenced by the module.modulemap file. 111 /// Display warnings for unaccounted-for header files. 112 /// \returns 0 if there were no errors or warnings, 1 if there 113 /// were warnings, 2 if any other problem, such as a bad 114 /// module map path argument was specified. 115 std::error_code doChecks(); 116 117 // The following functions are called by doChecks. 118 119 /// Collect module headers. 120 /// Walks the modules and collects referenced headers into 121 /// ModuleMapHeadersSet. 122 void collectModuleHeaders(); 123 124 /// Collect referenced headers from one module. 125 /// Collects the headers referenced in the given module into 126 /// ModuleMapHeadersSet. 127 /// \param Mod The module reference. 128 /// \return True if no errors. 129 bool collectModuleHeaders(const clang::Module &Mod); 130 131 /// Collect headers from an umbrella directory. 132 /// \param UmbrellaDirName The umbrella directory name. 133 /// \return True if no errors. 134 bool collectUmbrellaHeaders(llvm::StringRef UmbrellaDirName); 135 136 /// Collect headers rferenced from an umbrella file. 137 /// \param UmbrellaHeaderName The umbrella file path. 138 /// \return True if no errors. 139 bool collectUmbrellaHeaderHeaders(llvm::StringRef UmbrellaHeaderName); 140 141 /// Called from CoverageCheckerCallbacks to track a header included 142 /// from an umbrella header. 143 /// \param HeaderName The header file path. 144 void collectUmbrellaHeaderHeader(llvm::StringRef HeaderName); 145 146 /// Collect file system header files. 147 /// This function scans the file system for header files, 148 /// starting at the directory of the module.modulemap file, 149 /// optionally filtering out all but the files covered by 150 /// the include path options. 151 /// \returns True if no errors. 152 bool collectFileSystemHeaders(); 153 154 /// Collect file system header files from the given path. 155 /// This function scans the file system for header files, 156 /// starting at the given directory, which is assumed to be 157 /// relative to the directory of the module.modulemap file. 158 /// \returns True if no errors. 159 bool collectFileSystemHeaders(llvm::StringRef IncludePath); 160 161 /// Find headers unaccounted-for in module map. 162 /// This function compares the list of collected header files 163 /// against those referenced in the module map. Display 164 /// warnings for unaccounted-for header files. 165 /// Save unaccounted-for file list for possible. 166 /// fixing action. 167 void findUnaccountedForHeaders(); 168 }; 169 170 } // end namespace Modularize 171 172 #endif // COVERAGECHECKER_H 173