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