1 | //===- ModuleMap.h - Describe the layout of modules -------------*- 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 | // This file defines the ModuleMap interface, which describes the layout of a |
10 | // module as it relates to headers. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_CLANG_LEX_MODULEMAP_H |
15 | #define LLVM_CLANG_LEX_MODULEMAP_H |
16 | |
17 | #include "clang/Basic/IdentifierTable.h" |
18 | #include "clang/Basic/LangOptions.h" |
19 | #include "clang/Basic/Module.h" |
20 | #include "clang/Basic/SourceLocation.h" |
21 | #include "llvm/ADT/ArrayRef.h" |
22 | #include "llvm/ADT/DenseMap.h" |
23 | #include "llvm/ADT/DenseSet.h" |
24 | #include "llvm/ADT/PointerIntPair.h" |
25 | #include "llvm/ADT/SmallVector.h" |
26 | #include "llvm/ADT/StringMap.h" |
27 | #include "llvm/ADT/StringRef.h" |
28 | #include "llvm/ADT/StringSet.h" |
29 | #include "llvm/ADT/TinyPtrVector.h" |
30 | #include "llvm/ADT/Twine.h" |
31 | #include <ctime> |
32 | #include <memory> |
33 | #include <optional> |
34 | #include <string> |
35 | #include <utility> |
36 | |
37 | namespace clang { |
38 | |
39 | class DiagnosticsEngine; |
40 | class DirectoryEntry; |
41 | class FileEntry; |
42 | class FileManager; |
43 | class ; |
44 | class SourceManager; |
45 | |
46 | /// A mechanism to observe the actions of the module map parser as it |
47 | /// reads module map files. |
48 | class ModuleMapCallbacks { |
49 | virtual void anchor(); |
50 | |
51 | public: |
52 | virtual ~ModuleMapCallbacks() = default; |
53 | |
54 | /// Called when a module map file has been read. |
55 | /// |
56 | /// \param FileStart A SourceLocation referring to the start of the file's |
57 | /// contents. |
58 | /// \param File The file itself. |
59 | /// \param IsSystem Whether this is a module map from a system include path. |
60 | virtual void moduleMapFileRead(SourceLocation FileStart, FileEntryRef File, |
61 | bool IsSystem) {} |
62 | |
63 | /// Called when a header is added during module map parsing. |
64 | /// |
65 | /// \param Filename The header file itself. |
66 | virtual void (StringRef Filename) {} |
67 | |
68 | /// Called when an umbrella header is added during module map parsing. |
69 | /// |
70 | /// \param Header The umbrella header to collect. |
71 | virtual void (FileEntryRef ) {} |
72 | }; |
73 | |
74 | class ModuleMap { |
75 | SourceManager &SourceMgr; |
76 | DiagnosticsEngine &Diags; |
77 | const LangOptions &LangOpts; |
78 | const TargetInfo *Target; |
79 | HeaderSearch &; |
80 | |
81 | llvm::SmallVector<std::unique_ptr<ModuleMapCallbacks>, 1> Callbacks; |
82 | |
83 | /// The directory used for Clang-supplied, builtin include headers, |
84 | /// such as "stdint.h". |
85 | OptionalDirectoryEntryRef BuiltinIncludeDir; |
86 | |
87 | /// Language options used to parse the module map itself. |
88 | /// |
89 | /// These are always simple C language options. |
90 | LangOptions MMapLangOpts; |
91 | |
92 | /// The module that the main source file is associated with (the module |
93 | /// named LangOpts::CurrentModule, if we've loaded it). |
94 | Module *SourceModule = nullptr; |
95 | |
96 | /// Submodules of the current module that have not yet been attached to it. |
97 | /// (Ownership is transferred if/when we create an enclosing module.) |
98 | llvm::SmallVector<std::unique_ptr<Module>, 8> PendingSubmodules; |
99 | |
100 | /// The top-level modules that are known. |
101 | llvm::StringMap<Module *> Modules; |
102 | |
103 | /// Module loading cache that includes submodules, indexed by IdentifierInfo. |
104 | /// nullptr is stored for modules that are known to fail to load. |
105 | llvm::DenseMap<const IdentifierInfo *, Module *> CachedModuleLoads; |
106 | |
107 | /// Shadow modules created while building this module map. |
108 | llvm::SmallVector<Module*, 2> ShadowModules; |
109 | |
110 | /// The number of modules we have created in total. |
111 | unsigned NumCreatedModules = 0; |
112 | |
113 | /// In case a module has a export_as entry, it might have a pending link |
114 | /// name to be determined if that module is imported. |
115 | llvm::StringMap<llvm::StringSet<>> PendingLinkAsModule; |
116 | |
117 | public: |
118 | /// Use PendingLinkAsModule information to mark top level link names that |
119 | /// are going to be replaced by export_as aliases. |
120 | void resolveLinkAsDependencies(Module *Mod); |
121 | |
122 | /// Make module to use export_as as the link dependency name if enough |
123 | /// information is available or add it to a pending list otherwise. |
124 | void addLinkAsDependency(Module *Mod); |
125 | |
126 | /// Flags describing the role of a module header. |
127 | enum { |
128 | /// This header is normally included in the module. |
129 | = 0x0, |
130 | |
131 | /// This header is included but private. |
132 | = 0x1, |
133 | |
134 | /// This header is part of the module (for layering purposes) but |
135 | /// should be textually included. |
136 | = 0x2, |
137 | |
138 | /// This header is explicitly excluded from the module. |
139 | = 0x4, |
140 | |
141 | // Caution: Adding an enumerator needs other changes. |
142 | // Adjust the number of bits for KnownHeader::Storage. |
143 | // Adjust the HeaderFileInfoTrait::ReadData streaming. |
144 | // Adjust the HeaderFileInfoTrait::EmitData streaming. |
145 | // Adjust ModuleMap::addHeader. |
146 | }; |
147 | |
148 | /// Convert a header kind to a role. Requires Kind to not be HK_Excluded. |
149 | static ModuleHeaderRole (Module::HeaderKind Kind); |
150 | |
151 | /// Convert a header role to a kind. |
152 | static Module::HeaderKind (ModuleHeaderRole Role); |
153 | |
154 | /// Check if the header with the given role is a modular one. |
155 | static bool (ModuleHeaderRole Role); |
156 | |
157 | /// A header that is known to reside within a given module, |
158 | /// whether it was included or excluded. |
159 | class { |
160 | llvm::PointerIntPair<Module *, 3, ModuleHeaderRole> ; |
161 | |
162 | public: |
163 | () : Storage(nullptr, NormalHeader) {} |
164 | (Module *M, ModuleHeaderRole Role) : Storage(M, Role) {} |
165 | |
166 | friend bool (const KnownHeader &A, const KnownHeader &B) { |
167 | return A.Storage == B.Storage; |
168 | } |
169 | friend bool (const KnownHeader &A, const KnownHeader &B) { |
170 | return A.Storage != B.Storage; |
171 | } |
172 | |
173 | /// Retrieve the module the header is stored in. |
174 | Module *() const { return Storage.getPointer(); } |
175 | |
176 | /// The role of this header within the module. |
177 | ModuleHeaderRole () const { return Storage.getInt(); } |
178 | |
179 | /// Whether this header is available in the module. |
180 | bool () const { |
181 | return getRole() != ExcludedHeader && getModule()->isAvailable(); |
182 | } |
183 | |
184 | /// Whether this header is accessible from the specified module. |
185 | bool (Module *M) const { |
186 | return !(getRole() & PrivateHeader) || |
187 | (M && M->getTopLevelModule() == getModule()->getTopLevelModule()); |
188 | } |
189 | |
190 | // Whether this known header is valid (i.e., it has an |
191 | // associated module). |
192 | explicit () const { |
193 | return Storage.getPointer() != nullptr; |
194 | } |
195 | }; |
196 | |
197 | using AdditionalModMapsSet = llvm::DenseSet<FileEntryRef>; |
198 | |
199 | private: |
200 | friend class ModuleMapParser; |
201 | |
202 | using = llvm::DenseMap<FileEntryRef, SmallVector<KnownHeader, 1>>; |
203 | |
204 | /// Mapping from each header to the module that owns the contents of |
205 | /// that header. |
206 | HeadersMap ; |
207 | |
208 | /// Map from file sizes to modules with lazy header directives of that size. |
209 | mutable llvm::DenseMap<off_t, llvm::TinyPtrVector<Module*>> ; |
210 | |
211 | /// Map from mtimes to modules with lazy header directives with those mtimes. |
212 | mutable llvm::DenseMap<time_t, llvm::TinyPtrVector<Module*>> |
213 | ; |
214 | |
215 | /// Mapping from directories with umbrella headers to the module |
216 | /// that is generated from the umbrella header. |
217 | /// |
218 | /// This mapping is used to map headers that haven't explicitly been named |
219 | /// in the module map over to the module that includes them via its umbrella |
220 | /// header. |
221 | llvm::DenseMap<const DirectoryEntry *, Module *> UmbrellaDirs; |
222 | |
223 | /// A generation counter that is used to test whether modules of the |
224 | /// same name may shadow or are illegal redefinitions. |
225 | /// |
226 | /// Modules from earlier scopes may shadow modules from later ones. |
227 | /// Modules from the same scope may not have the same name. |
228 | unsigned CurrentModuleScopeID = 0; |
229 | |
230 | llvm::DenseMap<Module *, unsigned> ModuleScopeIDs; |
231 | |
232 | /// The set of attributes that can be attached to a module. |
233 | struct Attributes { |
234 | /// Whether this is a system module. |
235 | LLVM_PREFERRED_TYPE(bool) |
236 | unsigned IsSystem : 1; |
237 | |
238 | /// Whether this is an extern "C" module. |
239 | LLVM_PREFERRED_TYPE(bool) |
240 | unsigned IsExternC : 1; |
241 | |
242 | /// Whether this is an exhaustive set of configuration macros. |
243 | LLVM_PREFERRED_TYPE(bool) |
244 | unsigned IsExhaustive : 1; |
245 | |
246 | /// Whether files in this module can only include non-modular headers |
247 | /// and headers from used modules. |
248 | LLVM_PREFERRED_TYPE(bool) |
249 | unsigned NoUndeclaredIncludes : 1; |
250 | |
251 | Attributes() |
252 | : IsSystem(false), IsExternC(false), IsExhaustive(false), |
253 | NoUndeclaredIncludes(false) {} |
254 | }; |
255 | |
256 | /// A directory for which framework modules can be inferred. |
257 | struct InferredDirectory { |
258 | /// Whether to infer modules from this directory. |
259 | LLVM_PREFERRED_TYPE(bool) |
260 | unsigned InferModules : 1; |
261 | |
262 | /// The attributes to use for inferred modules. |
263 | Attributes Attrs; |
264 | |
265 | /// If \c InferModules is non-zero, the module map file that allowed |
266 | /// inferred modules. Otherwise, invalid. |
267 | FileID ModuleMapFID; |
268 | |
269 | /// The names of modules that cannot be inferred within this |
270 | /// directory. |
271 | SmallVector<std::string, 2> ExcludedModules; |
272 | |
273 | InferredDirectory() : InferModules(false) {} |
274 | }; |
275 | |
276 | /// A mapping from directories to information about inferring |
277 | /// framework modules from within those directories. |
278 | llvm::DenseMap<const DirectoryEntry *, InferredDirectory> InferredDirectories; |
279 | |
280 | /// A mapping from an inferred module to the module map that allowed the |
281 | /// inference. |
282 | llvm::DenseMap<const Module *, FileID> InferredModuleAllowedBy; |
283 | |
284 | llvm::DenseMap<const Module *, AdditionalModMapsSet> AdditionalModMaps; |
285 | |
286 | /// Describes whether we haved parsed a particular file as a module |
287 | /// map. |
288 | llvm::DenseMap<const FileEntry *, bool> ParsedModuleMap; |
289 | |
290 | /// Resolve the given export declaration into an actual export |
291 | /// declaration. |
292 | /// |
293 | /// \param Mod The module in which we're resolving the export declaration. |
294 | /// |
295 | /// \param Unresolved The export declaration to resolve. |
296 | /// |
297 | /// \param Complain Whether this routine should complain about unresolvable |
298 | /// exports. |
299 | /// |
300 | /// \returns The resolved export declaration, which will have a NULL pointer |
301 | /// if the export could not be resolved. |
302 | Module::ExportDecl |
303 | resolveExport(Module *Mod, const Module::UnresolvedExportDecl &Unresolved, |
304 | bool Complain) const; |
305 | |
306 | /// Resolve the given module id to an actual module. |
307 | /// |
308 | /// \param Id The module-id to resolve. |
309 | /// |
310 | /// \param Mod The module in which we're resolving the module-id. |
311 | /// |
312 | /// \param Complain Whether this routine should complain about unresolvable |
313 | /// module-ids. |
314 | /// |
315 | /// \returns The resolved module, or null if the module-id could not be |
316 | /// resolved. |
317 | Module *resolveModuleId(const ModuleId &Id, Module *Mod, bool Complain) const; |
318 | |
319 | /// Add an unresolved header to a module. |
320 | /// |
321 | /// \param Mod The module in which we're adding the unresolved header |
322 | /// directive. |
323 | /// \param Header The unresolved header directive. |
324 | /// \param NeedsFramework If Mod is not a framework but a missing header would |
325 | /// be found in case Mod was, set it to true. False otherwise. |
326 | void (Module *Mod, |
327 | Module::UnresolvedHeaderDirective , |
328 | bool &NeedsFramework); |
329 | |
330 | /// Look up the given header directive to find an actual header file. |
331 | /// |
332 | /// \param M The module in which we're resolving the header directive. |
333 | /// \param Header The header directive to resolve. |
334 | /// \param RelativePathName Filled in with the relative path name from the |
335 | /// module to the resolved header. |
336 | /// \param NeedsFramework If M is not a framework but a missing header would |
337 | /// be found in case M was, set it to true. False otherwise. |
338 | /// \return The resolved file, if any. |
339 | OptionalFileEntryRef |
340 | (Module *M, const Module::UnresolvedHeaderDirective &, |
341 | SmallVectorImpl<char> &RelativePathName, bool &NeedsFramework); |
342 | |
343 | /// Resolve the given header directive. |
344 | /// |
345 | /// \param M The module in which we're resolving the header directive. |
346 | /// \param Header The header directive to resolve. |
347 | /// \param NeedsFramework If M is not a framework but a missing header would |
348 | /// be found in case M was, set it to true. False otherwise. |
349 | void (Module *M, const Module::UnresolvedHeaderDirective &, |
350 | bool &NeedsFramework); |
351 | |
352 | /// Attempt to resolve the specified header directive as naming a builtin |
353 | /// header. |
354 | /// \return \c true if a corresponding builtin header was found. |
355 | bool (Module *M, |
356 | const Module::UnresolvedHeaderDirective &); |
357 | |
358 | /// Looks up the modules that \p File corresponds to. |
359 | /// |
360 | /// If \p File represents a builtin header within Clang's builtin include |
361 | /// directory, this also loads all of the module maps to see if it will get |
362 | /// associated with a specific module (e.g. in /usr/include). |
363 | HeadersMap::iterator (FileEntryRef File); |
364 | |
365 | /// Searches for a module whose umbrella directory contains \p File. |
366 | /// |
367 | /// \param File The header to search for. |
368 | /// |
369 | /// \param IntermediateDirs On success, contains the set of directories |
370 | /// searched before finding \p File. |
371 | KnownHeader ( |
372 | FileEntryRef File, SmallVectorImpl<DirectoryEntryRef> &IntermediateDirs); |
373 | |
374 | /// Given that \p File is not in the Headers map, look it up within |
375 | /// umbrella directories and find or create a module for it. |
376 | KnownHeader (FileEntryRef File); |
377 | |
378 | /// A convenience method to determine if \p File is (possibly nested) |
379 | /// in an umbrella directory. |
380 | bool (FileEntryRef File) { |
381 | SmallVector<DirectoryEntryRef, 2> IntermediateDirs; |
382 | return static_cast<bool>(findHeaderInUmbrellaDirs(File, IntermediateDirs)); |
383 | } |
384 | |
385 | Module *inferFrameworkModule(DirectoryEntryRef FrameworkDir, Attributes Attrs, |
386 | Module *Parent); |
387 | |
388 | public: |
389 | /// Construct a new module map. |
390 | /// |
391 | /// \param SourceMgr The source manager used to find module files and headers. |
392 | /// This source manager should be shared with the header-search mechanism, |
393 | /// since they will refer to the same headers. |
394 | /// |
395 | /// \param Diags A diagnostic engine used for diagnostics. |
396 | /// |
397 | /// \param LangOpts Language options for this translation unit. |
398 | /// |
399 | /// \param Target The target for this translation unit. |
400 | (SourceManager &SourceMgr, DiagnosticsEngine &Diags, |
401 | const LangOptions &LangOpts, const TargetInfo *Target, |
402 | HeaderSearch &); |
403 | |
404 | /// Destroy the module map. |
405 | ~ModuleMap(); |
406 | |
407 | /// Set the target information. |
408 | void setTarget(const TargetInfo &Target); |
409 | |
410 | /// Set the directory that contains Clang-supplied include files, such as our |
411 | /// stdarg.h or tgmath.h. |
412 | void setBuiltinIncludeDir(DirectoryEntryRef Dir) { BuiltinIncludeDir = Dir; } |
413 | |
414 | /// Get the directory that contains Clang-supplied include files. |
415 | OptionalDirectoryEntryRef getBuiltinDir() const { return BuiltinIncludeDir; } |
416 | |
417 | /// Is this a compiler builtin header? |
418 | bool (FileEntryRef File); |
419 | |
420 | bool shouldImportRelativeToBuiltinIncludeDir(StringRef FileName, |
421 | Module *Module) const; |
422 | |
423 | /// Add a module map callback. |
424 | void addModuleMapCallbacks(std::unique_ptr<ModuleMapCallbacks> Callback) { |
425 | Callbacks.push_back(Elt: std::move(Callback)); |
426 | } |
427 | |
428 | /// Retrieve the module that owns the given header file, if any. Note that |
429 | /// this does not implicitly load module maps, except for builtin headers, |
430 | /// and does not consult the external source. (Those checks are the |
431 | /// responsibility of \ref HeaderSearch.) |
432 | /// |
433 | /// \param File The header file that is likely to be included. |
434 | /// |
435 | /// \param AllowTextual If \c true and \p File is a textual header, return |
436 | /// its owning module. Otherwise, no KnownHeader will be returned if the |
437 | /// file is only known as a textual header. |
438 | /// |
439 | /// \returns The module KnownHeader, which provides the module that owns the |
440 | /// given header file. The KnownHeader is default constructed to indicate |
441 | /// that no module owns this header file. |
442 | KnownHeader (FileEntryRef File, bool AllowTextual = false, |
443 | bool AllowExcluded = false); |
444 | |
445 | /// Retrieve all the modules that contain the given header file. Note that |
446 | /// this does not implicitly load module maps, except for builtin headers, |
447 | /// and does not consult the external source. (Those checks are the |
448 | /// responsibility of \ref HeaderSearch.) |
449 | /// |
450 | /// Typically, \ref findModuleForHeader should be used instead, as it picks |
451 | /// the preferred module for the header. |
452 | ArrayRef<KnownHeader> (FileEntryRef File); |
453 | |
454 | /// Like \ref findAllModulesForHeader, but do not attempt to infer module |
455 | /// ownership from umbrella headers if we've not already done so. |
456 | ArrayRef<KnownHeader> (FileEntryRef File) const; |
457 | |
458 | /// Resolve all lazy header directives for the specified file. |
459 | /// |
460 | /// This ensures that the HeaderFileInfo on HeaderSearch is up to date. This |
461 | /// is effectively internal, but is exposed so HeaderSearch can call it. |
462 | void (const FileEntry *File) const; |
463 | |
464 | /// Resolve lazy header directives for the specified module. If File is |
465 | /// provided, only headers with same size and modtime are resolved. If File |
466 | /// is not set, all headers are resolved. |
467 | void (Module *Mod, |
468 | std::optional<const FileEntry *> File) const; |
469 | |
470 | /// Reports errors if a module must not include a specific file. |
471 | /// |
472 | /// \param RequestingModule The module including a file. |
473 | /// |
474 | /// \param RequestingModuleIsModuleInterface \c true if the inclusion is in |
475 | /// the interface of RequestingModule, \c false if it's in the |
476 | /// implementation of RequestingModule. Value is ignored and |
477 | /// meaningless if RequestingModule is nullptr. |
478 | /// |
479 | /// \param FilenameLoc The location of the inclusion's filename. |
480 | /// |
481 | /// \param Filename The included filename as written. |
482 | /// |
483 | /// \param File The included file. |
484 | void (Module *RequestingModule, |
485 | bool RequestingModuleIsModuleInterface, |
486 | SourceLocation FilenameLoc, StringRef Filename, |
487 | FileEntryRef File); |
488 | |
489 | /// Determine whether the given header is part of a module |
490 | /// marked 'unavailable'. |
491 | bool (FileEntryRef ) const; |
492 | |
493 | /// Determine whether the given header is unavailable as part |
494 | /// of the specified module. |
495 | bool (FileEntryRef , |
496 | const Module *RequestingModule) const; |
497 | |
498 | /// Retrieve a module with the given name. |
499 | /// |
500 | /// \param Name The name of the module to look up. |
501 | /// |
502 | /// \returns The named module, if known; otherwise, returns null. |
503 | Module *findModule(StringRef Name) const; |
504 | |
505 | /// Retrieve a module with the given name using lexical name lookup, |
506 | /// starting at the given context. |
507 | /// |
508 | /// \param Name The name of the module to look up. |
509 | /// |
510 | /// \param Context The module context, from which we will perform lexical |
511 | /// name lookup. |
512 | /// |
513 | /// \returns The named module, if known; otherwise, returns null. |
514 | Module *lookupModuleUnqualified(StringRef Name, Module *Context) const; |
515 | |
516 | /// Retrieve a module with the given name within the given context, |
517 | /// using direct (qualified) name lookup. |
518 | /// |
519 | /// \param Name The name of the module to look up. |
520 | /// |
521 | /// \param Context The module for which we will look for a submodule. If |
522 | /// null, we will look for a top-level module. |
523 | /// |
524 | /// \returns The named submodule, if known; otherwose, returns null. |
525 | Module *lookupModuleQualified(StringRef Name, Module *Context) const; |
526 | |
527 | /// Find a new module or submodule, or create it if it does not already |
528 | /// exist. |
529 | /// |
530 | /// \param Name The name of the module to find or create. |
531 | /// |
532 | /// \param Parent The module that will act as the parent of this submodule, |
533 | /// or nullptr to indicate that this is a top-level module. |
534 | /// |
535 | /// \param IsFramework Whether this is a framework module. |
536 | /// |
537 | /// \param IsExplicit Whether this is an explicit submodule. |
538 | /// |
539 | /// \returns The found or newly-created module, along with a boolean value |
540 | /// that will be true if the module is newly-created. |
541 | std::pair<Module *, bool> findOrCreateModule(StringRef Name, Module *Parent, |
542 | bool IsFramework, |
543 | bool IsExplicit); |
544 | |
545 | /// Create a global module fragment for a C++ module unit. |
546 | /// |
547 | /// We model the global module fragment as a submodule of the module |
548 | /// interface unit. Unfortunately, we can't create the module interface |
549 | /// unit's Module until later, because we don't know what it will be called |
550 | /// usually. See C++20 [module.unit]/7.2 for the case we could know its |
551 | /// parent. |
552 | Module *createGlobalModuleFragmentForModuleUnit(SourceLocation Loc, |
553 | Module *Parent = nullptr); |
554 | Module *createImplicitGlobalModuleFragmentForModuleUnit(SourceLocation Loc, |
555 | Module *Parent); |
556 | |
557 | /// Create a global module fragment for a C++ module interface unit. |
558 | Module *createPrivateModuleFragmentForInterfaceUnit(Module *Parent, |
559 | SourceLocation Loc); |
560 | |
561 | /// Create a new C++ module with the specified kind, and reparent any pending |
562 | /// global module fragment(s) to it. |
563 | Module *createModuleUnitWithKind(SourceLocation Loc, StringRef Name, |
564 | Module::ModuleKind Kind); |
565 | |
566 | /// Create a new module for a C++ module interface unit. |
567 | /// The module must not already exist, and will be configured for the current |
568 | /// compilation. |
569 | /// |
570 | /// Note that this also sets the current module to the newly-created module. |
571 | /// |
572 | /// \returns The newly-created module. |
573 | Module *createModuleForInterfaceUnit(SourceLocation Loc, StringRef Name); |
574 | |
575 | /// Create a new module for a C++ module implementation unit. |
576 | /// The interface module for this implementation (implicitly imported) must |
577 | /// exist and be loaded and present in the modules map. |
578 | /// |
579 | /// \returns The newly-created module. |
580 | Module *createModuleForImplementationUnit(SourceLocation Loc, StringRef Name); |
581 | |
582 | /// Create a C++20 header unit. |
583 | Module *(SourceLocation Loc, StringRef Name, |
584 | Module::Header H); |
585 | |
586 | /// Infer the contents of a framework module map from the given |
587 | /// framework directory. |
588 | Module *inferFrameworkModule(DirectoryEntryRef FrameworkDir, bool IsSystem, |
589 | Module *Parent); |
590 | |
591 | /// Create a new top-level module that is shadowed by |
592 | /// \p ShadowingModule. |
593 | Module *createShadowedModule(StringRef Name, bool IsFramework, |
594 | Module *ShadowingModule); |
595 | |
596 | /// Creates a new declaration scope for module names, allowing |
597 | /// previously defined modules to shadow definitions from the new scope. |
598 | /// |
599 | /// \note Module names from earlier scopes will shadow names from the new |
600 | /// scope, which is the opposite of how shadowing works for variables. |
601 | void finishModuleDeclarationScope() { CurrentModuleScopeID += 1; } |
602 | |
603 | bool mayShadowNewModule(Module *ExistingModule) { |
604 | assert(!ExistingModule->Parent && "expected top-level module" ); |
605 | assert(ModuleScopeIDs.count(ExistingModule) && "unknown module" ); |
606 | return ModuleScopeIDs[ExistingModule] < CurrentModuleScopeID; |
607 | } |
608 | |
609 | /// Check whether a framework module can be inferred in the given directory. |
610 | bool canInferFrameworkModule(const DirectoryEntry *Dir) const { |
611 | auto It = InferredDirectories.find(Val: Dir); |
612 | return It != InferredDirectories.end() && It->getSecond().InferModules; |
613 | } |
614 | |
615 | /// Retrieve the module map file containing the definition of the given |
616 | /// module. |
617 | /// |
618 | /// \param Module The module whose module map file will be returned, if known. |
619 | /// |
620 | /// \returns The FileID for the module map file containing the given module, |
621 | /// invalid if the module definition was inferred. |
622 | FileID getContainingModuleMapFileID(const Module *Module) const; |
623 | OptionalFileEntryRef getContainingModuleMapFile(const Module *Module) const; |
624 | |
625 | /// Get the module map file that (along with the module name) uniquely |
626 | /// identifies this module. |
627 | /// |
628 | /// The particular module that \c Name refers to may depend on how the module |
629 | /// was found in header search. However, the combination of \c Name and |
630 | /// this module map will be globally unique for top-level modules. In the case |
631 | /// of inferred modules, returns the module map that allowed the inference |
632 | /// (e.g. contained 'module *'). Otherwise, returns |
633 | /// getContainingModuleMapFile(). |
634 | FileID getModuleMapFileIDForUniquing(const Module *M) const; |
635 | OptionalFileEntryRef getModuleMapFileForUniquing(const Module *M) const; |
636 | |
637 | void setInferredModuleAllowedBy(Module *M, FileID ModMapFID); |
638 | |
639 | /// Canonicalize \p Path in a manner suitable for a module map file. In |
640 | /// particular, this canonicalizes the parent directory separately from the |
641 | /// filename so that it does not affect header resolution relative to the |
642 | /// modulemap. |
643 | /// |
644 | /// \returns an error code if any filesystem operations failed. In this case |
645 | /// \p Path is not modified. |
646 | std::error_code canonicalizeModuleMapPath(SmallVectorImpl<char> &Path); |
647 | |
648 | /// Get any module map files other than getModuleMapFileForUniquing(M) |
649 | /// that define submodules of a top-level module \p M. This is cheaper than |
650 | /// getting the module map file for each submodule individually, since the |
651 | /// expected number of results is very small. |
652 | AdditionalModMapsSet *getAdditionalModuleMapFiles(const Module *M) { |
653 | auto I = AdditionalModMaps.find(Val: M); |
654 | if (I == AdditionalModMaps.end()) |
655 | return nullptr; |
656 | return &I->second; |
657 | } |
658 | |
659 | void addAdditionalModuleMapFile(const Module *M, FileEntryRef ModuleMap); |
660 | |
661 | /// Resolve all of the unresolved exports in the given module. |
662 | /// |
663 | /// \param Mod The module whose exports should be resolved. |
664 | /// |
665 | /// \param Complain Whether to emit diagnostics for failures. |
666 | /// |
667 | /// \returns true if any errors were encountered while resolving exports, |
668 | /// false otherwise. |
669 | bool resolveExports(Module *Mod, bool Complain); |
670 | |
671 | /// Resolve all of the unresolved uses in the given module. |
672 | /// |
673 | /// \param Mod The module whose uses should be resolved. |
674 | /// |
675 | /// \param Complain Whether to emit diagnostics for failures. |
676 | /// |
677 | /// \returns true if any errors were encountered while resolving uses, |
678 | /// false otherwise. |
679 | bool resolveUses(Module *Mod, bool Complain); |
680 | |
681 | /// Resolve all of the unresolved conflicts in the given module. |
682 | /// |
683 | /// \param Mod The module whose conflicts should be resolved. |
684 | /// |
685 | /// \param Complain Whether to emit diagnostics for failures. |
686 | /// |
687 | /// \returns true if any errors were encountered while resolving conflicts, |
688 | /// false otherwise. |
689 | bool resolveConflicts(Module *Mod, bool Complain); |
690 | |
691 | /// Sets the umbrella header of the given module to the given header. |
692 | void |
693 | (Module *Mod, FileEntryRef , |
694 | const Twine &NameAsWritten, |
695 | const Twine &PathRelativeToRootModuleDirectory); |
696 | |
697 | /// Sets the umbrella directory of the given module to the given directory. |
698 | void setUmbrellaDirAsWritten(Module *Mod, DirectoryEntryRef UmbrellaDir, |
699 | const Twine &NameAsWritten, |
700 | const Twine &PathRelativeToRootModuleDirectory); |
701 | |
702 | /// Adds this header to the given module. |
703 | /// \param Role The role of the header wrt the module. |
704 | void (Module *Mod, Module::Header , |
705 | ModuleHeaderRole Role, bool Imported = false); |
706 | |
707 | /// Parse the given module map file, and record any modules we |
708 | /// encounter. |
709 | /// |
710 | /// \param File The file to be parsed. |
711 | /// |
712 | /// \param IsSystem Whether this module map file is in a system header |
713 | /// directory, and therefore should be considered a system module. |
714 | /// |
715 | /// \param HomeDir The directory in which relative paths within this module |
716 | /// map file will be resolved. |
717 | /// |
718 | /// \param ID The FileID of the file to process, if we've already entered it. |
719 | /// |
720 | /// \param Offset [inout] On input the offset at which to start parsing. On |
721 | /// output, the offset at which the module map terminated. |
722 | /// |
723 | /// \param ExternModuleLoc The location of the "extern module" declaration |
724 | /// that caused us to load this module map file, if any. |
725 | /// |
726 | /// \returns true if an error occurred, false otherwise. |
727 | bool parseModuleMapFile(FileEntryRef File, bool IsSystem, |
728 | DirectoryEntryRef HomeDir, FileID ID = FileID(), |
729 | unsigned *Offset = nullptr, |
730 | SourceLocation ExternModuleLoc = SourceLocation()); |
731 | |
732 | /// Dump the contents of the module map, for debugging purposes. |
733 | void dump(); |
734 | |
735 | using module_iterator = llvm::StringMap<Module *>::const_iterator; |
736 | |
737 | module_iterator module_begin() const { return Modules.begin(); } |
738 | module_iterator module_end() const { return Modules.end(); } |
739 | llvm::iterator_range<module_iterator> modules() const { |
740 | return {module_begin(), module_end()}; |
741 | } |
742 | |
743 | /// Cache a module load. M might be nullptr. |
744 | void cacheModuleLoad(const IdentifierInfo &II, Module *M) { |
745 | CachedModuleLoads[&II] = M; |
746 | } |
747 | |
748 | /// Return a cached module load. |
749 | std::optional<Module *> getCachedModuleLoad(const IdentifierInfo &II) { |
750 | auto I = CachedModuleLoads.find(Val: &II); |
751 | if (I == CachedModuleLoads.end()) |
752 | return std::nullopt; |
753 | return I->second; |
754 | } |
755 | }; |
756 | |
757 | } // namespace clang |
758 | |
759 | #endif // LLVM_CLANG_LEX_MODULEMAP_H |
760 | |