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