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
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
|
//===--- ModuleMap.h - Describe the layout of modules -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the ModuleMap interface, which describes the layout of a
// module as it relates to headers.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LEX_MODULEMAP_H
#define LLVM_CLANG_LEX_MODULEMAP_H
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringMap.h"
#include <string>
namespace clang {
class DirectoryEntry;
class FileEntry;
class FileManager;
class DiagnosticConsumer;
class DiagnosticsEngine;
class ModuleMapParser;
class ModuleMap {
SourceManager *SourceMgr;
IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
const LangOptions &LangOpts;
const TargetInfo *Target;
/// \brief The directory used for Clang-supplied, builtin include headers,
/// such as "stdint.h".
const DirectoryEntry *BuiltinIncludeDir;
/// \brief Language options used to parse the module map itself.
///
/// These are always simple C language options.
LangOptions MMapLangOpts;
/// \brief The top-level modules that are known.
llvm::StringMap<Module *> Modules;
/// \brief Mapping from each header to the module that owns the contents of the
/// that header.
llvm::DenseMap<const FileEntry *, Module *> Headers;
/// \brief Mapping from directories with umbrella headers to the module
/// that is generated from the umbrella header.
///
/// This mapping is used to map headers that haven't explicitly been named
/// in the module map over to the module that includes them via its umbrella
/// header.
llvm::DenseMap<const DirectoryEntry *, Module *> UmbrellaDirs;
friend class ModuleMapParser;
/// \brief Resolve the given export declaration into an actual export
/// declaration.
///
/// \param Mod The module in which we're resolving the export declaration.
///
/// \param Unresolved The export declaration to resolve.
///
/// \param Complain Whether this routine should complain about unresolvable
/// exports.
///
/// \returns The resolved export declaration, which will have a NULL pointer
/// if the export could not be resolved.
Module::ExportDecl
resolveExport(Module *Mod, const Module::UnresolvedExportDecl &Unresolved,
bool Complain);
public:
/// \brief Construct a new module map.
///
/// \param FileMgr The file manager used to find module files and headers.
/// This file manager should be shared with the header-search mechanism, since
/// they will refer to the same headers.
///
/// \param DC A diagnostic consumer that will be cloned for use in generating
/// diagnostics.
///
/// \param LangOpts Language options for this translation unit.
///
/// \param Target The target for this translation unit.
ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
const LangOptions &LangOpts, const TargetInfo *Target);
/// \brief Destroy the module map.
///
~ModuleMap();
/// \brief Set the target information.
void setTarget(const TargetInfo &Target);
/// \brief Set the directory that contains Clang-supplied include
/// files, such as our stdarg.h or tgmath.h.
void setBuiltinIncludeDir(const DirectoryEntry *Dir) {
BuiltinIncludeDir = Dir;
}
/// \brief Retrieve the module that owns the given header file, if any.
///
/// \param File The header file that is likely to be included.
///
/// \returns The module that owns the given header file, or null to indicate
/// that no module owns this header file.
Module *findModuleForHeader(const FileEntry *File);
/// \brief Determine whether the given header is part of a module
/// marked 'unavailable'.
bool isHeaderInUnavailableModule(const FileEntry *Header);
/// \brief Retrieve a module with the given name.
///
/// \param The name of the module to look up.
///
/// \returns The named module, if known; otherwise, returns null.
Module *findModule(StringRef Name);
/// \brief Retrieve a module with the given name using lexical name lookup,
/// starting at the given context.
///
/// \param The name of the module to look up.
///
/// \param Context The module context, from which we will perform lexical
/// name lookup.
///
/// \returns The named module, if known; otherwise, returns null.
Module *lookupModuleUnqualified(StringRef Name, Module *Context);
/// \brief Retrieve a module with the given name within the given context,
/// using direct (qualified) name lookup.
///
/// \param The name of the module to look up.
///
/// \param Context The module for which we will look for a submodule. If
/// null, we will look for a top-level module.
///
/// \returns The named submodule, if known; otherwose, returns null.
Module *lookupModuleQualified(StringRef Name, Module *Context);
/// \brief Find a new module or submodule, or create it if it does not already
/// exist.
///
/// \param Name The name of the module to find or create.
///
/// \param Parent The module that will act as the parent of this submodule,
/// or NULL to indicate that this is a top-level module.
///
/// \param IsFramework Whether this is a framework module.
///
/// \param IsExplicit Whether this is an explicit submodule.
///
/// \returns The found or newly-created module, along with a boolean value
/// that will be true if the module is newly-created.
std::pair<Module *, bool> findOrCreateModule(StringRef Name, Module *Parent,
bool IsFramework,
bool IsExplicit);
/// \brief Infer the contents of a framework module map from the given
/// framework directory.
Module *inferFrameworkModule(StringRef ModuleName,
const DirectoryEntry *FrameworkDir,
bool IsSystem, Module *Parent);
/// \brief Retrieve the module map file containing the definition of the given
/// module.
///
/// \param Module The module whose module map file will be returned, if known.
///
/// \returns The file entry for the module map file containing the given
/// module, or NULL if the module definition was inferred.
const FileEntry *getContainingModuleMapFile(Module *Module);
/// \brief Resolve all of the unresolved exports in the given module.
///
/// \param Mod The module whose exports should be resolved.
///
/// \param Complain Whether to emit diagnostics for failures.
///
/// \returns true if any errors were encountered while resolving exports,
/// false otherwise.
bool resolveExports(Module *Mod, bool Complain);
/// \brief Infers the (sub)module based on the given source location and
/// source manager.
///
/// \param Loc The location within the source that we are querying, along
/// with its source manager.
///
/// \returns The module that owns this source location, or null if no
/// module owns this source location.
Module *inferModuleFromLocation(FullSourceLoc Loc);
/// \brief Sets the umbrella header of the given module to the given
/// header.
void setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader);
/// \brief Sets the umbrella directory of the given module to the given
/// directory.
void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir);
/// \brief Adds this header to the given module.
void addHeader(Module *Mod, const FileEntry *Header);
/// \brief Parse the given module map file, and record any modules we
/// encounter.
///
/// \param File The file to be parsed.
///
/// \returns true if an error occurred, false otherwise.
bool parseModuleMapFile(const FileEntry *File);
/// \brief Dump the contents of the module map, for debugging purposes.
void dump();
typedef llvm::StringMap<Module *>::const_iterator module_iterator;
module_iterator module_begin() const { return Modules.begin(); }
module_iterator module_end() const { return Modules.end(); }
};
}
#endif
|