Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 1 | //===- Module.h - Describe a module -----------------------------*- 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 | /// Defines the clang::Module class, which describes a module in the |
||
11 | /// source code. |
||
12 | // |
||
13 | //===----------------------------------------------------------------------===// |
||
14 | |||
15 | #ifndef LLVM_CLANG_BASIC_MODULE_H |
||
16 | #define LLVM_CLANG_BASIC_MODULE_H |
||
17 | |||
18 | #include "clang/Basic/DirectoryEntry.h" |
||
19 | #include "clang/Basic/FileEntry.h" |
||
20 | #include "clang/Basic/SourceLocation.h" |
||
21 | #include "llvm/ADT/ArrayRef.h" |
||
22 | #include "llvm/ADT/DenseSet.h" |
||
23 | #include "llvm/ADT/PointerIntPair.h" |
||
24 | #include "llvm/ADT/STLExtras.h" |
||
25 | #include "llvm/ADT/SetVector.h" |
||
26 | #include "llvm/ADT/SmallVector.h" |
||
27 | #include "llvm/ADT/StringMap.h" |
||
28 | #include "llvm/ADT/StringRef.h" |
||
29 | #include "llvm/ADT/iterator_range.h" |
||
30 | #include <array> |
||
31 | #include <cassert> |
||
32 | #include <cstdint> |
||
33 | #include <ctime> |
||
34 | #include <iterator> |
||
35 | #include <optional> |
||
36 | #include <string> |
||
37 | #include <utility> |
||
38 | #include <vector> |
||
39 | |||
40 | namespace llvm { |
||
41 | |||
42 | class raw_ostream; |
||
43 | |||
44 | } // namespace llvm |
||
45 | |||
46 | namespace clang { |
||
47 | |||
48 | class FileManager; |
||
49 | class LangOptions; |
||
50 | class TargetInfo; |
||
51 | |||
52 | /// Describes the name of a module. |
||
53 | using ModuleId = SmallVector<std::pair<std::string, SourceLocation>, 2>; |
||
54 | |||
55 | /// The signature of a module, which is a hash of the AST content. |
||
56 | struct ASTFileSignature : std::array<uint8_t, 20> { |
||
57 | using BaseT = std::array<uint8_t, 20>; |
||
58 | |||
59 | static constexpr size_t size = std::tuple_size<BaseT>::value; |
||
60 | |||
61 | ASTFileSignature(BaseT S = {{0}}) : BaseT(std::move(S)) {} |
||
62 | |||
63 | explicit operator bool() const { return *this != BaseT({{0}}); } |
||
64 | |||
65 | /// Returns the value truncated to the size of an uint64_t. |
||
66 | uint64_t truncatedValue() const { |
||
67 | uint64_t Value = 0; |
||
68 | static_assert(sizeof(*this) >= sizeof(uint64_t), "No need to truncate."); |
||
69 | for (unsigned I = 0; I < sizeof(uint64_t); ++I) |
||
70 | Value |= static_cast<uint64_t>((*this)[I]) << (I * 8); |
||
71 | return Value; |
||
72 | } |
||
73 | |||
74 | static ASTFileSignature create(std::array<uint8_t, 20> Bytes) { |
||
75 | return ASTFileSignature(std::move(Bytes)); |
||
76 | } |
||
77 | |||
78 | static ASTFileSignature createDISentinel() { |
||
79 | ASTFileSignature Sentinel; |
||
80 | Sentinel.fill(0xFF); |
||
81 | return Sentinel; |
||
82 | } |
||
83 | |||
84 | template <typename InputIt> |
||
85 | static ASTFileSignature create(InputIt First, InputIt Last) { |
||
86 | assert(std::distance(First, Last) == size && |
||
87 | "Wrong amount of bytes to create an ASTFileSignature"); |
||
88 | |||
89 | ASTFileSignature Signature; |
||
90 | std::copy(First, Last, Signature.begin()); |
||
91 | return Signature; |
||
92 | } |
||
93 | }; |
||
94 | |||
95 | /// Describes a module or submodule. |
||
96 | /// |
||
97 | /// Aligned to 8 bytes to allow for llvm::PointerIntPair<Module *, 3>. |
||
98 | class alignas(8) Module { |
||
99 | public: |
||
100 | /// The name of this module. |
||
101 | std::string Name; |
||
102 | |||
103 | /// The location of the module definition. |
||
104 | SourceLocation DefinitionLoc; |
||
105 | |||
106 | enum ModuleKind { |
||
107 | /// This is a module that was defined by a module map and built out |
||
108 | /// of header files. |
||
109 | ModuleMapModule, |
||
110 | |||
111 | /// This is a C++20 module interface unit. |
||
112 | ModuleInterfaceUnit, |
||
113 | |||
114 | /// This is a C++ 20 header unit. |
||
115 | ModuleHeaderUnit, |
||
116 | |||
117 | /// This is a C++ 20 module partition interface. |
||
118 | ModulePartitionInterface, |
||
119 | |||
120 | /// This is a C++ 20 module partition implementation. |
||
121 | ModulePartitionImplementation, |
||
122 | |||
123 | /// This is a fragment of the global module within some C++ module. |
||
124 | GlobalModuleFragment, |
||
125 | |||
126 | /// This is the private module fragment within some C++ module. |
||
127 | PrivateModuleFragment, |
||
128 | }; |
||
129 | |||
130 | /// The kind of this module. |
||
131 | ModuleKind Kind = ModuleMapModule; |
||
132 | |||
133 | /// The parent of this module. This will be NULL for the top-level |
||
134 | /// module. |
||
135 | Module *Parent; |
||
136 | |||
137 | /// The build directory of this module. This is the directory in |
||
138 | /// which the module is notionally built, and relative to which its headers |
||
139 | /// are found. |
||
140 | const DirectoryEntry *Directory = nullptr; |
||
141 | |||
142 | /// The presumed file name for the module map defining this module. |
||
143 | /// Only non-empty when building from preprocessed source. |
||
144 | std::string PresumedModuleMapFile; |
||
145 | |||
146 | /// The umbrella header or directory. |
||
147 | llvm::PointerUnion<const FileEntryRef::MapEntry *, const DirectoryEntry *> |
||
148 | Umbrella; |
||
149 | |||
150 | /// The module signature. |
||
151 | ASTFileSignature Signature; |
||
152 | |||
153 | /// The name of the umbrella entry, as written in the module map. |
||
154 | std::string UmbrellaAsWritten; |
||
155 | |||
156 | // The path to the umbrella entry relative to the root module's \c Directory. |
||
157 | std::string UmbrellaRelativeToRootModuleDirectory; |
||
158 | |||
159 | /// The module through which entities defined in this module will |
||
160 | /// eventually be exposed, for use in "private" modules. |
||
161 | std::string ExportAsModule; |
||
162 | |||
163 | /// Does this Module scope describe part of the purview of a standard named |
||
164 | /// C++ module? |
||
165 | bool isModulePurview() const { |
||
166 | return Kind == ModuleInterfaceUnit || Kind == ModulePartitionInterface || |
||
167 | Kind == ModulePartitionImplementation || |
||
168 | Kind == PrivateModuleFragment; |
||
169 | } |
||
170 | |||
171 | /// Does this Module scope describe a fragment of the global module within |
||
172 | /// some C++ module. |
||
173 | bool isGlobalModule() const { return Kind == GlobalModuleFragment; } |
||
174 | |||
175 | bool isPrivateModule() const { return Kind == PrivateModuleFragment; } |
||
176 | |||
177 | bool isModuleMapModule() const { return Kind == ModuleMapModule; } |
||
178 | |||
179 | private: |
||
180 | /// The submodules of this module, indexed by name. |
||
181 | std::vector<Module *> SubModules; |
||
182 | |||
183 | /// A mapping from the submodule name to the index into the |
||
184 | /// \c SubModules vector at which that submodule resides. |
||
185 | llvm::StringMap<unsigned> SubModuleIndex; |
||
186 | |||
187 | /// The AST file if this is a top-level module which has a |
||
188 | /// corresponding serialized AST file, or null otherwise. |
||
189 | OptionalFileEntryRef ASTFile; |
||
190 | |||
191 | /// The top-level headers associated with this module. |
||
192 | llvm::SmallSetVector<const FileEntry *, 2> TopHeaders; |
||
193 | |||
194 | /// top-level header filenames that aren't resolved to FileEntries yet. |
||
195 | std::vector<std::string> TopHeaderNames; |
||
196 | |||
197 | /// Cache of modules visible to lookup in this module. |
||
198 | mutable llvm::DenseSet<const Module*> VisibleModulesCache; |
||
199 | |||
200 | /// The ID used when referencing this module within a VisibleModuleSet. |
||
201 | unsigned VisibilityID; |
||
202 | |||
203 | public: |
||
204 | enum HeaderKind { |
||
205 | HK_Normal, |
||
206 | HK_Textual, |
||
207 | HK_Private, |
||
208 | HK_PrivateTextual, |
||
209 | HK_Excluded |
||
210 | }; |
||
211 | static const int NumHeaderKinds = HK_Excluded + 1; |
||
212 | |||
213 | /// Information about a header directive as found in the module map |
||
214 | /// file. |
||
215 | struct Header { |
||
216 | std::string NameAsWritten; |
||
217 | std::string PathRelativeToRootModuleDirectory; |
||
218 | OptionalFileEntryRefDegradesToFileEntryPtr Entry; |
||
219 | |||
220 | explicit operator bool() { return Entry.has_value(); } |
||
221 | }; |
||
222 | |||
223 | /// Information about a directory name as found in the module map |
||
224 | /// file. |
||
225 | struct DirectoryName { |
||
226 | std::string NameAsWritten; |
||
227 | std::string PathRelativeToRootModuleDirectory; |
||
228 | const DirectoryEntry *Entry; |
||
229 | |||
230 | explicit operator bool() { return Entry; } |
||
231 | }; |
||
232 | |||
233 | /// The headers that are part of this module. |
||
234 | SmallVector<Header, 2> Headers[5]; |
||
235 | |||
236 | /// Stored information about a header directive that was found in the |
||
237 | /// module map file but has not been resolved to a file. |
||
238 | struct UnresolvedHeaderDirective { |
||
239 | HeaderKind Kind = HK_Normal; |
||
240 | SourceLocation FileNameLoc; |
||
241 | std::string FileName; |
||
242 | bool IsUmbrella = false; |
||
243 | bool HasBuiltinHeader = false; |
||
244 | std::optional<off_t> Size; |
||
245 | std::optional<time_t> ModTime; |
||
246 | }; |
||
247 | |||
248 | /// Headers that are mentioned in the module map file but that we have not |
||
249 | /// yet attempted to resolve to a file on the file system. |
||
250 | SmallVector<UnresolvedHeaderDirective, 1> UnresolvedHeaders; |
||
251 | |||
252 | /// Headers that are mentioned in the module map file but could not be |
||
253 | /// found on the file system. |
||
254 | SmallVector<UnresolvedHeaderDirective, 1> MissingHeaders; |
||
255 | |||
256 | /// An individual requirement: a feature name and a flag indicating |
||
257 | /// the required state of that feature. |
||
258 | using Requirement = std::pair<std::string, bool>; |
||
259 | |||
260 | /// The set of language features required to use this module. |
||
261 | /// |
||
262 | /// If any of these requirements are not available, the \c IsAvailable bit |
||
263 | /// will be false to indicate that this (sub)module is not available. |
||
264 | SmallVector<Requirement, 2> Requirements; |
||
265 | |||
266 | /// A module with the same name that shadows this module. |
||
267 | Module *ShadowingModule = nullptr; |
||
268 | |||
269 | /// Whether this module has declared itself unimportable, either because |
||
270 | /// it's missing a requirement from \p Requirements or because it's been |
||
271 | /// shadowed by another module. |
||
272 | unsigned IsUnimportable : 1; |
||
273 | |||
274 | /// Whether we tried and failed to load a module file for this module. |
||
275 | unsigned HasIncompatibleModuleFile : 1; |
||
276 | |||
277 | /// Whether this module is available in the current translation unit. |
||
278 | /// |
||
279 | /// If the module is missing headers or does not meet all requirements then |
||
280 | /// this bit will be 0. |
||
281 | unsigned IsAvailable : 1; |
||
282 | |||
283 | /// Whether this module was loaded from a module file. |
||
284 | unsigned IsFromModuleFile : 1; |
||
285 | |||
286 | /// Whether this is a framework module. |
||
287 | unsigned IsFramework : 1; |
||
288 | |||
289 | /// Whether this is an explicit submodule. |
||
290 | unsigned IsExplicit : 1; |
||
291 | |||
292 | /// Whether this is a "system" module (which assumes that all |
||
293 | /// headers in it are system headers). |
||
294 | unsigned IsSystem : 1; |
||
295 | |||
296 | /// Whether this is an 'extern "C"' module (which implicitly puts all |
||
297 | /// headers in it within an 'extern "C"' block, and allows the module to be |
||
298 | /// imported within such a block). |
||
299 | unsigned IsExternC : 1; |
||
300 | |||
301 | /// Whether this is an inferred submodule (module * { ... }). |
||
302 | unsigned IsInferred : 1; |
||
303 | |||
304 | /// Whether we should infer submodules for this module based on |
||
305 | /// the headers. |
||
306 | /// |
||
307 | /// Submodules can only be inferred for modules with an umbrella header. |
||
308 | unsigned InferSubmodules : 1; |
||
309 | |||
310 | /// Whether, when inferring submodules, the inferred submodules |
||
311 | /// should be explicit. |
||
312 | unsigned InferExplicitSubmodules : 1; |
||
313 | |||
314 | /// Whether, when inferring submodules, the inferr submodules should |
||
315 | /// export all modules they import (e.g., the equivalent of "export *"). |
||
316 | unsigned InferExportWildcard : 1; |
||
317 | |||
318 | /// Whether the set of configuration macros is exhaustive. |
||
319 | /// |
||
320 | /// When the set of configuration macros is exhaustive, meaning |
||
321 | /// that no identifier not in this list should affect how the module is |
||
322 | /// built. |
||
323 | unsigned ConfigMacrosExhaustive : 1; |
||
324 | |||
325 | /// Whether files in this module can only include non-modular headers |
||
326 | /// and headers from used modules. |
||
327 | unsigned NoUndeclaredIncludes : 1; |
||
328 | |||
329 | /// Whether this module came from a "private" module map, found next |
||
330 | /// to a regular (public) module map. |
||
331 | unsigned ModuleMapIsPrivate : 1; |
||
332 | |||
333 | /// Describes the visibility of the various names within a |
||
334 | /// particular module. |
||
335 | enum NameVisibilityKind { |
||
336 | /// All of the names in this module are hidden. |
||
337 | Hidden, |
||
338 | /// All of the names in this module are visible. |
||
339 | AllVisible |
||
340 | }; |
||
341 | |||
342 | /// The visibility of names within this particular module. |
||
343 | NameVisibilityKind NameVisibility; |
||
344 | |||
345 | /// The location of the inferred submodule. |
||
346 | SourceLocation InferredSubmoduleLoc; |
||
347 | |||
348 | /// The set of modules imported by this module, and on which this |
||
349 | /// module depends. |
||
350 | llvm::SmallSetVector<Module *, 2> Imports; |
||
351 | |||
352 | /// The set of top-level modules that affected the compilation of this module, |
||
353 | /// but were not imported. |
||
354 | llvm::SmallSetVector<Module *, 2> AffectingClangModules; |
||
355 | |||
356 | /// Describes an exported module. |
||
357 | /// |
||
358 | /// The pointer is the module being re-exported, while the bit will be true |
||
359 | /// to indicate that this is a wildcard export. |
||
360 | using ExportDecl = llvm::PointerIntPair<Module *, 1, bool>; |
||
361 | |||
362 | /// The set of export declarations. |
||
363 | SmallVector<ExportDecl, 2> Exports; |
||
364 | |||
365 | /// Describes an exported module that has not yet been resolved |
||
366 | /// (perhaps because the module it refers to has not yet been loaded). |
||
367 | struct UnresolvedExportDecl { |
||
368 | /// The location of the 'export' keyword in the module map file. |
||
369 | SourceLocation ExportLoc; |
||
370 | |||
371 | /// The name of the module. |
||
372 | ModuleId Id; |
||
373 | |||
374 | /// Whether this export declaration ends in a wildcard, indicating |
||
375 | /// that all of its submodules should be exported (rather than the named |
||
376 | /// module itself). |
||
377 | bool Wildcard; |
||
378 | }; |
||
379 | |||
380 | /// The set of export declarations that have yet to be resolved. |
||
381 | SmallVector<UnresolvedExportDecl, 2> UnresolvedExports; |
||
382 | |||
383 | /// The directly used modules. |
||
384 | SmallVector<Module *, 2> DirectUses; |
||
385 | |||
386 | /// The set of use declarations that have yet to be resolved. |
||
387 | SmallVector<ModuleId, 2> UnresolvedDirectUses; |
||
388 | |||
389 | /// When \c NoUndeclaredIncludes is true, the set of modules this module tried |
||
390 | /// to import but didn't because they are not direct uses. |
||
391 | llvm::SmallSetVector<const Module *, 2> UndeclaredUses; |
||
392 | |||
393 | /// A library or framework to link against when an entity from this |
||
394 | /// module is used. |
||
395 | struct LinkLibrary { |
||
396 | LinkLibrary() = default; |
||
397 | LinkLibrary(const std::string &Library, bool IsFramework) |
||
398 | : Library(Library), IsFramework(IsFramework) {} |
||
399 | |||
400 | /// The library to link against. |
||
401 | /// |
||
402 | /// This will typically be a library or framework name, but can also |
||
403 | /// be an absolute path to the library or framework. |
||
404 | std::string Library; |
||
405 | |||
406 | /// Whether this is a framework rather than a library. |
||
407 | bool IsFramework = false; |
||
408 | }; |
||
409 | |||
410 | /// The set of libraries or frameworks to link against when |
||
411 | /// an entity from this module is used. |
||
412 | llvm::SmallVector<LinkLibrary, 2> LinkLibraries; |
||
413 | |||
414 | /// Autolinking uses the framework name for linking purposes |
||
415 | /// when this is false and the export_as name otherwise. |
||
416 | bool UseExportAsModuleLinkName = false; |
||
417 | |||
418 | /// The set of "configuration macros", which are macros that |
||
419 | /// (intentionally) change how this module is built. |
||
420 | std::vector<std::string> ConfigMacros; |
||
421 | |||
422 | /// An unresolved conflict with another module. |
||
423 | struct UnresolvedConflict { |
||
424 | /// The (unresolved) module id. |
||
425 | ModuleId Id; |
||
426 | |||
427 | /// The message provided to the user when there is a conflict. |
||
428 | std::string Message; |
||
429 | }; |
||
430 | |||
431 | /// The list of conflicts for which the module-id has not yet been |
||
432 | /// resolved. |
||
433 | std::vector<UnresolvedConflict> UnresolvedConflicts; |
||
434 | |||
435 | /// A conflict between two modules. |
||
436 | struct Conflict { |
||
437 | /// The module that this module conflicts with. |
||
438 | Module *Other; |
||
439 | |||
440 | /// The message provided to the user when there is a conflict. |
||
441 | std::string Message; |
||
442 | }; |
||
443 | |||
444 | /// The list of conflicts. |
||
445 | std::vector<Conflict> Conflicts; |
||
446 | |||
447 | /// Construct a new module or submodule. |
||
448 | Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, |
||
449 | bool IsFramework, bool IsExplicit, unsigned VisibilityID); |
||
450 | |||
451 | ~Module(); |
||
452 | |||
453 | /// Determine whether this module has been declared unimportable. |
||
454 | bool isUnimportable() const { return IsUnimportable; } |
||
455 | |||
456 | /// Determine whether this module has been declared unimportable. |
||
457 | /// |
||
458 | /// \param LangOpts The language options used for the current |
||
459 | /// translation unit. |
||
460 | /// |
||
461 | /// \param Target The target options used for the current translation unit. |
||
462 | /// |
||
463 | /// \param Req If this module is unimportable because of a missing |
||
464 | /// requirement, this parameter will be set to one of the requirements that |
||
465 | /// is not met for use of this module. |
||
466 | /// |
||
467 | /// \param ShadowingModule If this module is unimportable because it is |
||
468 | /// shadowed, this parameter will be set to the shadowing module. |
||
469 | bool isUnimportable(const LangOptions &LangOpts, const TargetInfo &Target, |
||
470 | Requirement &Req, Module *&ShadowingModule) const; |
||
471 | |||
472 | /// Determine whether this module can be built in this compilation. |
||
473 | bool isForBuilding(const LangOptions &LangOpts) const; |
||
474 | |||
475 | /// Determine whether this module is available for use within the |
||
476 | /// current translation unit. |
||
477 | bool isAvailable() const { return IsAvailable; } |
||
478 | |||
479 | /// Determine whether this module is available for use within the |
||
480 | /// current translation unit. |
||
481 | /// |
||
482 | /// \param LangOpts The language options used for the current |
||
483 | /// translation unit. |
||
484 | /// |
||
485 | /// \param Target The target options used for the current translation unit. |
||
486 | /// |
||
487 | /// \param Req If this module is unavailable because of a missing requirement, |
||
488 | /// this parameter will be set to one of the requirements that is not met for |
||
489 | /// use of this module. |
||
490 | /// |
||
491 | /// \param MissingHeader If this module is unavailable because of a missing |
||
492 | /// header, this parameter will be set to one of the missing headers. |
||
493 | /// |
||
494 | /// \param ShadowingModule If this module is unavailable because it is |
||
495 | /// shadowed, this parameter will be set to the shadowing module. |
||
496 | bool isAvailable(const LangOptions &LangOpts, |
||
497 | const TargetInfo &Target, |
||
498 | Requirement &Req, |
||
499 | UnresolvedHeaderDirective &MissingHeader, |
||
500 | Module *&ShadowingModule) const; |
||
501 | |||
502 | /// Determine whether this module is a submodule. |
||
503 | bool isSubModule() const { return Parent != nullptr; } |
||
504 | |||
505 | /// Check if this module is a (possibly transitive) submodule of \p Other. |
||
506 | /// |
||
507 | /// The 'A is a submodule of B' relation is a partial order based on the |
||
508 | /// the parent-child relationship between individual modules. |
||
509 | /// |
||
510 | /// Returns \c false if \p Other is \c nullptr. |
||
511 | bool isSubModuleOf(const Module *Other) const; |
||
512 | |||
513 | /// Determine whether this module is a part of a framework, |
||
514 | /// either because it is a framework module or because it is a submodule |
||
515 | /// of a framework module. |
||
516 | bool isPartOfFramework() const { |
||
517 | for (const Module *Mod = this; Mod; Mod = Mod->Parent) |
||
518 | if (Mod->IsFramework) |
||
519 | return true; |
||
520 | |||
521 | return false; |
||
522 | } |
||
523 | |||
524 | /// Determine whether this module is a subframework of another |
||
525 | /// framework. |
||
526 | bool isSubFramework() const { |
||
527 | return IsFramework && Parent && Parent->isPartOfFramework(); |
||
528 | } |
||
529 | |||
530 | /// Set the parent of this module. This should only be used if the parent |
||
531 | /// could not be set during module creation. |
||
532 | void setParent(Module *M) { |
||
533 | assert(!Parent); |
||
534 | Parent = M; |
||
535 | Parent->SubModuleIndex[Name] = Parent->SubModules.size(); |
||
536 | Parent->SubModules.push_back(this); |
||
537 | } |
||
538 | |||
539 | /// Is this module have similar semantics as headers. |
||
540 | bool isHeaderLikeModule() const { |
||
541 | return isModuleMapModule() || isHeaderUnit(); |
||
542 | } |
||
543 | |||
544 | /// Is this a module partition. |
||
545 | bool isModulePartition() const { |
||
546 | return Kind == ModulePartitionInterface || |
||
547 | Kind == ModulePartitionImplementation; |
||
548 | } |
||
549 | |||
550 | /// Is this module a header unit. |
||
551 | bool isHeaderUnit() const { return Kind == ModuleHeaderUnit; } |
||
552 | // Is this a C++20 module interface or a partition. |
||
553 | bool isInterfaceOrPartition() const { |
||
554 | return Kind == ModuleInterfaceUnit || isModulePartition(); |
||
555 | } |
||
556 | |||
557 | bool isModuleInterfaceUnit() const { |
||
558 | return Kind == ModuleInterfaceUnit || Kind == ModulePartitionInterface; |
||
559 | } |
||
560 | |||
561 | /// Get the primary module interface name from a partition. |
||
562 | StringRef getPrimaryModuleInterfaceName() const { |
||
563 | // Technically, global module fragment belongs to global module. And global |
||
564 | // module has no name: [module.unit]p6: |
||
565 | // The global module has no name, no module interface unit, and is not |
||
566 | // introduced by any module-declaration. |
||
567 | // |
||
568 | // <global> is the default name showed in module map. |
||
569 | if (isGlobalModule()) |
||
570 | return "<global>"; |
||
571 | |||
572 | if (isModulePartition()) { |
||
573 | auto pos = Name.find(':'); |
||
574 | return StringRef(Name.data(), pos); |
||
575 | } |
||
576 | |||
577 | if (isPrivateModule()) |
||
578 | return getTopLevelModuleName(); |
||
579 | |||
580 | return Name; |
||
581 | } |
||
582 | |||
583 | /// Retrieve the full name of this module, including the path from |
||
584 | /// its top-level module. |
||
585 | /// \param AllowStringLiterals If \c true, components that might not be |
||
586 | /// lexically valid as identifiers will be emitted as string literals. |
||
587 | std::string getFullModuleName(bool AllowStringLiterals = false) const; |
||
588 | |||
589 | /// Whether the full name of this module is equal to joining |
||
590 | /// \p nameParts with "."s. |
||
591 | /// |
||
592 | /// This is more efficient than getFullModuleName(). |
||
593 | bool fullModuleNameIs(ArrayRef<StringRef> nameParts) const; |
||
594 | |||
595 | /// Retrieve the top-level module for this (sub)module, which may |
||
596 | /// be this module. |
||
597 | Module *getTopLevelModule() { |
||
598 | return const_cast<Module *>( |
||
599 | const_cast<const Module *>(this)->getTopLevelModule()); |
||
600 | } |
||
601 | |||
602 | /// Retrieve the top-level module for this (sub)module, which may |
||
603 | /// be this module. |
||
604 | const Module *getTopLevelModule() const; |
||
605 | |||
606 | /// Retrieve the name of the top-level module. |
||
607 | StringRef getTopLevelModuleName() const { |
||
608 | return getTopLevelModule()->Name; |
||
609 | } |
||
610 | |||
611 | /// The serialized AST file for this module, if one was created. |
||
612 | OptionalFileEntryRefDegradesToFileEntryPtr getASTFile() const { |
||
613 | return getTopLevelModule()->ASTFile; |
||
614 | } |
||
615 | |||
616 | /// Set the serialized AST file for the top-level module of this module. |
||
617 | void setASTFile(OptionalFileEntryRef File) { |
||
618 | assert((!getASTFile() || getASTFile() == File) && "file path changed"); |
||
619 | getTopLevelModule()->ASTFile = File; |
||
620 | } |
||
621 | |||
622 | /// Retrieve the directory for which this module serves as the |
||
623 | /// umbrella. |
||
624 | DirectoryName getUmbrellaDir() const; |
||
625 | |||
626 | /// Retrieve the header that serves as the umbrella header for this |
||
627 | /// module. |
||
628 | Header getUmbrellaHeader() const { |
||
629 | if (auto *ME = Umbrella.dyn_cast<const FileEntryRef::MapEntry *>()) |
||
630 | return Header{UmbrellaAsWritten, UmbrellaRelativeToRootModuleDirectory, |
||
631 | FileEntryRef(*ME)}; |
||
632 | return Header{}; |
||
633 | } |
||
634 | |||
635 | /// Determine whether this module has an umbrella directory that is |
||
636 | /// not based on an umbrella header. |
||
637 | bool hasUmbrellaDir() const { |
||
638 | return Umbrella && Umbrella.is<const DirectoryEntry *>(); |
||
639 | } |
||
640 | |||
641 | /// Add a top-level header associated with this module. |
||
642 | void addTopHeader(const FileEntry *File); |
||
643 | |||
644 | /// Add a top-level header filename associated with this module. |
||
645 | void addTopHeaderFilename(StringRef Filename) { |
||
646 | TopHeaderNames.push_back(std::string(Filename)); |
||
647 | } |
||
648 | |||
649 | /// The top-level headers associated with this module. |
||
650 | ArrayRef<const FileEntry *> getTopHeaders(FileManager &FileMgr); |
||
651 | |||
652 | /// Determine whether this module has declared its intention to |
||
653 | /// directly use another module. |
||
654 | bool directlyUses(const Module *Requested); |
||
655 | |||
656 | /// Add the given feature requirement to the list of features |
||
657 | /// required by this module. |
||
658 | /// |
||
659 | /// \param Feature The feature that is required by this module (and |
||
660 | /// its submodules). |
||
661 | /// |
||
662 | /// \param RequiredState The required state of this feature: \c true |
||
663 | /// if it must be present, \c false if it must be absent. |
||
664 | /// |
||
665 | /// \param LangOpts The set of language options that will be used to |
||
666 | /// evaluate the availability of this feature. |
||
667 | /// |
||
668 | /// \param Target The target options that will be used to evaluate the |
||
669 | /// availability of this feature. |
||
670 | void addRequirement(StringRef Feature, bool RequiredState, |
||
671 | const LangOptions &LangOpts, |
||
672 | const TargetInfo &Target); |
||
673 | |||
674 | /// Mark this module and all of its submodules as unavailable. |
||
675 | void markUnavailable(bool Unimportable); |
||
676 | |||
677 | /// Find the submodule with the given name. |
||
678 | /// |
||
679 | /// \returns The submodule if found, or NULL otherwise. |
||
680 | Module *findSubmodule(StringRef Name) const; |
||
681 | Module *findOrInferSubmodule(StringRef Name); |
||
682 | |||
683 | /// Get the Global Module Fragment (sub-module) for this module, it there is |
||
684 | /// one. |
||
685 | /// |
||
686 | /// \returns The GMF sub-module if found, or NULL otherwise. |
||
687 | Module *getGlobalModuleFragment() { return findSubmodule("<global>"); } |
||
688 | |||
689 | /// Get the Private Module Fragment (sub-module) for this module, it there is |
||
690 | /// one. |
||
691 | /// |
||
692 | /// \returns The PMF sub-module if found, or NULL otherwise. |
||
693 | Module *getPrivateModuleFragment() { return findSubmodule("<private>"); } |
||
694 | |||
695 | /// Determine whether the specified module would be visible to |
||
696 | /// a lookup at the end of this module. |
||
697 | /// |
||
698 | /// FIXME: This may return incorrect results for (submodules of) the |
||
699 | /// module currently being built, if it's queried before we see all |
||
700 | /// of its imports. |
||
701 | bool isModuleVisible(const Module *M) const { |
||
702 | if (VisibleModulesCache.empty()) |
||
703 | buildVisibleModulesCache(); |
||
704 | return VisibleModulesCache.count(M); |
||
705 | } |
||
706 | |||
707 | unsigned getVisibilityID() const { return VisibilityID; } |
||
708 | |||
709 | using submodule_iterator = std::vector<Module *>::iterator; |
||
710 | using submodule_const_iterator = std::vector<Module *>::const_iterator; |
||
711 | |||
712 | submodule_iterator submodule_begin() { return SubModules.begin(); } |
||
713 | submodule_const_iterator submodule_begin() const {return SubModules.begin();} |
||
714 | submodule_iterator submodule_end() { return SubModules.end(); } |
||
715 | submodule_const_iterator submodule_end() const { return SubModules.end(); } |
||
716 | |||
717 | llvm::iterator_range<submodule_iterator> submodules() { |
||
718 | return llvm::make_range(submodule_begin(), submodule_end()); |
||
719 | } |
||
720 | llvm::iterator_range<submodule_const_iterator> submodules() const { |
||
721 | return llvm::make_range(submodule_begin(), submodule_end()); |
||
722 | } |
||
723 | |||
724 | /// Appends this module's list of exported modules to \p Exported. |
||
725 | /// |
||
726 | /// This provides a subset of immediately imported modules (the ones that are |
||
727 | /// directly exported), not the complete set of exported modules. |
||
728 | void getExportedModules(SmallVectorImpl<Module *> &Exported) const; |
||
729 | |||
730 | static StringRef getModuleInputBufferName() { |
||
731 | return "<module-includes>"; |
||
732 | } |
||
733 | |||
734 | /// Print the module map for this module to the given stream. |
||
735 | void print(raw_ostream &OS, unsigned Indent = 0, bool Dump = false) const; |
||
736 | |||
737 | /// Dump the contents of this module to the given output stream. |
||
738 | void dump() const; |
||
739 | |||
740 | private: |
||
741 | void buildVisibleModulesCache() const; |
||
742 | }; |
||
743 | |||
744 | /// A set of visible modules. |
||
745 | class VisibleModuleSet { |
||
746 | public: |
||
747 | VisibleModuleSet() = default; |
||
748 | VisibleModuleSet(VisibleModuleSet &&O) |
||
749 | : ImportLocs(std::move(O.ImportLocs)), Generation(O.Generation ? 1 : 0) { |
||
750 | O.ImportLocs.clear(); |
||
751 | ++O.Generation; |
||
752 | } |
||
753 | |||
754 | /// Move from another visible modules set. Guaranteed to leave the source |
||
755 | /// empty and bump the generation on both. |
||
756 | VisibleModuleSet &operator=(VisibleModuleSet &&O) { |
||
757 | ImportLocs = std::move(O.ImportLocs); |
||
758 | O.ImportLocs.clear(); |
||
759 | ++O.Generation; |
||
760 | ++Generation; |
||
761 | return *this; |
||
762 | } |
||
763 | |||
764 | /// Get the current visibility generation. Incremented each time the |
||
765 | /// set of visible modules changes in any way. |
||
766 | unsigned getGeneration() const { return Generation; } |
||
767 | |||
768 | /// Determine whether a module is visible. |
||
769 | bool isVisible(const Module *M) const { |
||
770 | return getImportLoc(M).isValid(); |
||
771 | } |
||
772 | |||
773 | /// Get the location at which the import of a module was triggered. |
||
774 | SourceLocation getImportLoc(const Module *M) const { |
||
775 | return M->getVisibilityID() < ImportLocs.size() |
||
776 | ? ImportLocs[M->getVisibilityID()] |
||
777 | : SourceLocation(); |
||
778 | } |
||
779 | |||
780 | /// A callback to call when a module is made visible (directly or |
||
781 | /// indirectly) by a call to \ref setVisible. |
||
782 | using VisibleCallback = llvm::function_ref<void(Module *M)>; |
||
783 | |||
784 | /// A callback to call when a module conflict is found. \p Path |
||
785 | /// consists of a sequence of modules from the conflicting module to the one |
||
786 | /// made visible, where each was exported by the next. |
||
787 | using ConflictCallback = |
||
788 | llvm::function_ref<void(ArrayRef<Module *> Path, Module *Conflict, |
||
789 | StringRef Message)>; |
||
790 | |||
791 | /// Make a specific module visible. |
||
792 | void setVisible(Module *M, SourceLocation Loc, |
||
793 | VisibleCallback Vis = [](Module *) {}, |
||
794 | ConflictCallback Cb = [](ArrayRef<Module *>, Module *, |
||
795 | StringRef) {}); |
||
796 | |||
797 | private: |
||
798 | /// Import locations for each visible module. Indexed by the module's |
||
799 | /// VisibilityID. |
||
800 | std::vector<SourceLocation> ImportLocs; |
||
801 | |||
802 | /// Visibility generation, bumped every time the visibility state changes. |
||
803 | unsigned Generation = 0; |
||
804 | }; |
||
805 | |||
806 | /// Abstracts clang modules and precompiled header files and holds |
||
807 | /// everything needed to generate debug info for an imported module |
||
808 | /// or PCH. |
||
809 | class ASTSourceDescriptor { |
||
810 | StringRef PCHModuleName; |
||
811 | StringRef Path; |
||
812 | StringRef ASTFile; |
||
813 | ASTFileSignature Signature; |
||
814 | Module *ClangModule = nullptr; |
||
815 | |||
816 | public: |
||
817 | ASTSourceDescriptor() = default; |
||
818 | ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile, |
||
819 | ASTFileSignature Signature) |
||
820 | : PCHModuleName(std::move(Name)), Path(std::move(Path)), |
||
821 | ASTFile(std::move(ASTFile)), Signature(Signature) {} |
||
822 | ASTSourceDescriptor(Module &M); |
||
823 | |||
824 | std::string getModuleName() const; |
||
825 | StringRef getPath() const { return Path; } |
||
826 | StringRef getASTFile() const { return ASTFile; } |
||
827 | ASTFileSignature getSignature() const { return Signature; } |
||
828 | Module *getModuleOrNull() const { return ClangModule; } |
||
829 | }; |
||
830 | |||
831 | |||
832 | } // namespace clang |
||
833 | |||
834 | #endif // LLVM_CLANG_BASIC_MODULE_H |