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