1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
|
//===-- ModuleMapChecker.h - Common defs for module-map-checker -*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===--------------------------------------------------------------------===//
///
/// \file
/// \brief Common definitions for ModuleMapChecker.
///
//===--------------------------------------------------------------------===//
#ifndef MODULEMAPCHECKER_H
#define MODULEMAPCHECKER_H
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Lex/ModuleMap.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Host.h"
#include <string>
#include <vector>
/// Subclass TargetOptions so we can construct it inline with
/// the minimal option, the triple.
class ModuleMapTargetOptions : public clang::TargetOptions {
public:
ModuleMapTargetOptions() { Triple = llvm::sys::getDefaultTargetTriple(); }
};
/// Module map checker class.
/// This is the heart of the checker.
/// The doChecks function does the main work.
/// The data members store the options and internally collected data.
class ModuleMapChecker {
// Checker arguments.
/// The module.map file path. Can be relative or absolute.
llvm::StringRef ModuleMapPath;
/// The include paths to check for files.
/// (Note that other directories above these paths are ignored.
/// To expect all files to be accounted for from the module.map
/// file directory on down, leave this empty.)
std::vector<std::string> IncludePaths;
/// Flag to dump the module map information during check.
bool DumpModuleMap;
/// The remaining arguments, to be passed to the front end.
llvm::ArrayRef<std::string> CommandLine;
// Supporting objects.
/// Options controlling the language variant.
llvm::IntrusiveRefCntPtr<clang::LangOptions> LangOpts;
/// Diagnostic IDs.
const llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagIDs;
/// Options controlling the diagnostic engine.
llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagnosticOpts;
/// Diagnostic consumer.
clang::TextDiagnosticPrinter DC;
/// Diagnostic engine.
llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> Diagnostics;
/// Options controlling the target.
llvm::IntrusiveRefCntPtr<clang::TargetOptions> TargetOpts;
/// Target information.
llvm::IntrusiveRefCntPtr<clang::TargetInfo> Target;
/// Options controlling the file system manager.
clang::FileSystemOptions FileSystemOpts;
/// File system manager.
llvm::IntrusiveRefCntPtr<clang::FileManager> FileMgr;
/// Source manager.
llvm::IntrusiveRefCntPtr<clang::SourceManager> SourceMgr;
/// Options controlling the \#include directive.
llvm::IntrusiveRefCntPtr<clang::HeaderSearchOptions> HeaderSearchOpts;
/// Header search manager.
std::unique_ptr<clang::HeaderSearch> HeaderInfo;
/// The module map.
std::unique_ptr<clang::ModuleMap> ModMap;
// Internal data.
/// Directory containing the module map.
/// Might be relative to the current directory, or absolute.
std::string ModuleMapDirectory;
/// Set of all the headers found in the module map.
llvm::StringSet<llvm::MallocAllocator> ModuleMapHeadersSet;
/// All the headers found in the file system starting at the
/// module map, or the union of those from the include paths.
std::vector<std::string> FileSystemHeaders;
/// Headers found in file system, but not in module map.
std::vector<std::string> UnaccountedForHeaders;
public:
/// Constructor.
/// You can use the static createModuleMapChecker to create an instance
/// of this object.
/// \param ModuleMapPath The module.map file path.
/// Can be relative or absolute.
/// \param IncludePaths The include paths to check for files.
/// (Note that other directories above these paths are ignored.
/// To expect all files to be accounted for from the module.map
/// file directory on down, leave this empty.)
/// \param DumpModuleMap Flag to dump the module map information
/// during check.
ModuleMapChecker(llvm::StringRef ModuleMapPath,
std::vector<std::string> &IncludePaths, bool DumpModuleMap,
llvm::ArrayRef<std::string> CommandLine);
/// Create instance of ModuleMapChecker.
/// \param ModuleMapPath The module.map file path.
/// Can be relative or absolute.
/// \param IncludePaths The include paths to check for files.
/// (Note that other directories above these paths are ignored.
/// To expect all files to be accounted for from the module.map
/// file directory on down, leave this empty.)
/// \param DumpModuleMap Flag to dump the module map information
/// during check.
/// \returns Initialized ModuleMapChecker object.
static ModuleMapChecker *createModuleMapChecker(
llvm::StringRef ModuleMapPath, std::vector<std::string> &IncludePaths,
bool DumpModuleMap, llvm::ArrayRef<std::string> CommandLine);
/// Do checks.
/// Starting from the directory of the module.map file,
/// Find all header files, optionally looking only at files
/// covered by the include path options, and compare against
/// the headers referenced by the module.map file.
/// Display warnings for unaccounted-for header files.
/// \returns 0 if there were no errors or warnings, 1 if there
/// were warnings, 2 if any other problem, such as a bad
/// module map path argument was specified.
std::error_code doChecks();
// The following functions are called by doChecks.
/// Load module map.
/// \returns True if module.map file loaded successfully.
bool loadModuleMap();
/// Collect module headers.
/// Walks the modules and collects referenced headers into
/// ModuleMapHeadersSet.
void collectModuleHeaders();
/// Collect referenced headers from one module.
/// Collects the headers referenced in the given module into
/// ModuleMapHeadersSet.
/// \param Mod The module reference.
/// \return True if no errors.
bool collectModuleHeaders(const clang::Module &Mod);
/// Collect headers from an umbrella directory.
/// \param UmbrellaDirName The umbrella directory name.
/// \return True if no errors.
bool collectUmbrellaHeaders(llvm::StringRef UmbrellaDirName);
/// Collect headers rferenced from an umbrella file.
/// \param UmbrellaHeaderName The umbrella file path.
/// \return True if no errors.
bool collectUmbrellaHeaderHeaders(llvm::StringRef UmbrellaHeaderName);
/// Called from ModuleMapCheckerCallbacks to track a header included
/// from an umbrella header.
/// \param HeaderName The header file path.
void collectUmbrellaHeaderHeader(llvm::StringRef HeaderName);
/// Collect file system header files.
/// This function scans the file system for header files,
/// starting at the directory of the module.map file,
/// optionally filtering out all but the files covered by
/// the include path options.
/// \returns True if no errors.
bool collectFileSystemHeaders();
/// Collect file system header files from the given path.
/// This function scans the file system for header files,
/// starting at the given directory, which is assumed to be
/// relative to the directory of the module.map file.
/// \returns True if no errors.
bool collectFileSystemHeaders(llvm::StringRef IncludePath);
/// Find headers unaccounted-for in module map.
/// This function compares the list of collected header files
/// against those referenced in the module map. Display
/// warnings for unaccounted-for header files.
/// Save unaccounted-for file list for possible.
/// fixing action.
void findUnaccountedForHeaders();
// Utility functions.
/// Get directory path component from file path.
/// \returns the component of the given path, which will be
/// relative if the given path is relative, absolute if the
/// given path is absolute, or "." if the path has no leading
/// path component.
std::string getDirectoryFromPath(llvm::StringRef Path);
/// Convert header path to canonical form.
/// The canonical form is basically just use forward slashes,
/// and remove "./".
/// \param FilePath The file path.
/// \returns The file path in canonical form.
std::string getCanonicalPath(llvm::StringRef FilePath);
/// Check for header file extension.
/// If the file extension is .h, .inc, or missing, it's
/// assumed to be a header.
/// \param FileName The file name. Must not be a directory.
/// \returns true if it has a header extension or no extension.
bool isHeader(llvm::StringRef FileName);
};
#endif // MODULEMAPCHECKER_H
|