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, nullopt. |
267 | OptionalFileEntryRef ModuleMapFile; |
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 | // FIXME: Consider making the values non-optional. |
283 | llvm::DenseMap<const Module *, OptionalFileEntryRef> InferredModuleAllowedBy; |
284 | |
285 | llvm::DenseMap<const Module *, AdditionalModMapsSet> AdditionalModMaps; |
286 | |
287 | /// Describes whether we haved parsed a particular file as a module |
288 | /// map. |
289 | llvm::DenseMap<const FileEntry *, bool> ParsedModuleMap; |
290 | |
291 | /// Resolve the given export declaration into an actual export |
292 | /// declaration. |
293 | /// |
294 | /// \param Mod The module in which we're resolving the export declaration. |
295 | /// |
296 | /// \param Unresolved The export declaration to resolve. |
297 | /// |
298 | /// \param Complain Whether this routine should complain about unresolvable |
299 | /// exports. |
300 | /// |
301 | /// \returns The resolved export declaration, which will have a NULL pointer |
302 | /// if the export could not be resolved. |
303 | Module::ExportDecl |
304 | resolveExport(Module *Mod, const Module::UnresolvedExportDecl &Unresolved, |
305 | bool Complain) const; |
306 | |
307 | /// Resolve the given module id to an actual module. |
308 | /// |
309 | /// \param Id The module-id to resolve. |
310 | /// |
311 | /// \param Mod The module in which we're resolving the module-id. |
312 | /// |
313 | /// \param Complain Whether this routine should complain about unresolvable |
314 | /// module-ids. |
315 | /// |
316 | /// \returns The resolved module, or null if the module-id could not be |
317 | /// resolved. |
318 | Module *resolveModuleId(const ModuleId &Id, Module *Mod, bool Complain) const; |
319 | |
320 | /// Add an unresolved header to a module. |
321 | /// |
322 | /// \param Mod The module in which we're adding the unresolved header |
323 | /// directive. |
324 | /// \param Header The unresolved header directive. |
325 | /// \param NeedsFramework If Mod is not a framework but a missing header would |
326 | /// be found in case Mod was, set it to true. False otherwise. |
327 | void (Module *Mod, |
328 | Module::UnresolvedHeaderDirective , |
329 | bool &NeedsFramework); |
330 | |
331 | /// Look up the given header directive to find an actual header file. |
332 | /// |
333 | /// \param M The module in which we're resolving the header directive. |
334 | /// \param Header The header directive to resolve. |
335 | /// \param RelativePathName Filled in with the relative path name from the |
336 | /// module to the resolved header. |
337 | /// \param NeedsFramework If M is not a framework but a missing header would |
338 | /// be found in case M was, set it to true. False otherwise. |
339 | /// \return The resolved file, if any. |
340 | OptionalFileEntryRef |
341 | (Module *M, const Module::UnresolvedHeaderDirective &, |
342 | SmallVectorImpl<char> &RelativePathName, bool &NeedsFramework); |
343 | |
344 | /// Resolve the given header directive. |
345 | /// |
346 | /// \param M The module in which we're resolving the header directive. |
347 | /// \param Header The header directive to resolve. |
348 | /// \param NeedsFramework If M is not a framework but a missing header would |
349 | /// be found in case M was, set it to true. False otherwise. |
350 | void (Module *M, const Module::UnresolvedHeaderDirective &, |
351 | bool &NeedsFramework); |
352 | |
353 | /// Attempt to resolve the specified header directive as naming a builtin |
354 | /// header. |
355 | /// \return \c true if a corresponding builtin header was found. |
356 | bool (Module *M, |
357 | const Module::UnresolvedHeaderDirective &); |
358 | |
359 | /// Looks up the modules that \p File corresponds to. |
360 | /// |
361 | /// If \p File represents a builtin header within Clang's builtin include |
362 | /// directory, this also loads all of the module maps to see if it will get |
363 | /// associated with a specific module (e.g. in /usr/include). |
364 | HeadersMap::iterator (FileEntryRef File); |
365 | |
366 | /// Searches for a module whose umbrella directory contains \p File. |
367 | /// |
368 | /// \param File The header to search for. |
369 | /// |
370 | /// \param IntermediateDirs On success, contains the set of directories |
371 | /// searched before finding \p File. |
372 | KnownHeader ( |
373 | FileEntryRef File, SmallVectorImpl<DirectoryEntryRef> &IntermediateDirs); |
374 | |
375 | /// Given that \p File is not in the Headers map, look it up within |
376 | /// umbrella directories and find or create a module for it. |
377 | KnownHeader (FileEntryRef File); |
378 | |
379 | /// A convenience method to determine if \p File is (possibly nested) |
380 | /// in an umbrella directory. |
381 | bool (FileEntryRef File) { |
382 | SmallVector<DirectoryEntryRef, 2> IntermediateDirs; |
383 | return static_cast<bool>(findHeaderInUmbrellaDirs(File, IntermediateDirs)); |
384 | } |
385 | |
386 | Module *inferFrameworkModule(DirectoryEntryRef FrameworkDir, Attributes Attrs, |
387 | Module *Parent); |
388 | |
389 | public: |
390 | /// Construct a new module map. |
391 | /// |
392 | /// \param SourceMgr The source manager used to find module files and headers. |
393 | /// This source manager should be shared with the header-search mechanism, |
394 | /// since they will refer to the same headers. |
395 | /// |
396 | /// \param Diags A diagnostic engine used for diagnostics. |
397 | /// |
398 | /// \param LangOpts Language options for this translation unit. |
399 | /// |
400 | /// \param Target The target for this translation unit. |
401 | (SourceManager &SourceMgr, DiagnosticsEngine &Diags, |
402 | const LangOptions &LangOpts, const TargetInfo *Target, |
403 | HeaderSearch &); |
404 | |
405 | /// Destroy the module map. |
406 | ~ModuleMap(); |
407 | |
408 | /// Set the target information. |
409 | void setTarget(const TargetInfo &Target); |
410 | |
411 | /// Set the directory that contains Clang-supplied include files, such as our |
412 | /// stdarg.h or tgmath.h. |
413 | void setBuiltinIncludeDir(DirectoryEntryRef Dir) { BuiltinIncludeDir = Dir; } |
414 | |
415 | /// Get the directory that contains Clang-supplied include files. |
416 | OptionalDirectoryEntryRef getBuiltinDir() const { return BuiltinIncludeDir; } |
417 | |
418 | /// Is this a compiler builtin header? |
419 | bool (FileEntryRef File); |
420 | |
421 | bool shouldImportRelativeToBuiltinIncludeDir(StringRef FileName, |
422 | Module *Module) const; |
423 | |
424 | /// Add a module map callback. |
425 | void addModuleMapCallbacks(std::unique_ptr<ModuleMapCallbacks> Callback) { |
426 | Callbacks.push_back(Elt: std::move(Callback)); |
427 | } |
428 | |
429 | /// Retrieve the module that owns the given header file, if any. Note that |
430 | /// this does not implicitly load module maps, except for builtin headers, |
431 | /// and does not consult the external source. (Those checks are the |
432 | /// responsibility of \ref HeaderSearch.) |
433 | /// |
434 | /// \param File The header file that is likely to be included. |
435 | /// |
436 | /// \param AllowTextual If \c true and \p File is a textual header, return |
437 | /// its owning module. Otherwise, no KnownHeader will be returned if the |
438 | /// file is only known as a textual header. |
439 | /// |
440 | /// \returns The module KnownHeader, which provides the module that owns the |
441 | /// given header file. The KnownHeader is default constructed to indicate |
442 | /// that no module owns this header file. |
443 | KnownHeader (FileEntryRef File, bool AllowTextual = false, |
444 | bool AllowExcluded = false); |
445 | |
446 | /// Retrieve all the modules that contain the given header file. Note that |
447 | /// this does not implicitly load module maps, except for builtin headers, |
448 | /// and does not consult the external source. (Those checks are the |
449 | /// responsibility of \ref HeaderSearch.) |
450 | /// |
451 | /// Typically, \ref findModuleForHeader should be used instead, as it picks |
452 | /// the preferred module for the header. |
453 | ArrayRef<KnownHeader> (FileEntryRef File); |
454 | |
455 | /// Like \ref findAllModulesForHeader, but do not attempt to infer module |
456 | /// ownership from umbrella headers if we've not already done so. |
457 | ArrayRef<KnownHeader> (FileEntryRef File) const; |
458 | |
459 | /// Resolve all lazy header directives for the specified file. |
460 | /// |
461 | /// This ensures that the HeaderFileInfo on HeaderSearch is up to date. This |
462 | /// is effectively internal, but is exposed so HeaderSearch can call it. |
463 | void (const FileEntry *File) const; |
464 | |
465 | /// Resolve lazy header directives for the specified module. If File is |
466 | /// provided, only headers with same size and modtime are resolved. If File |
467 | /// is not set, all headers are resolved. |
468 | void (Module *Mod, |
469 | std::optional<const FileEntry *> File) const; |
470 | |
471 | /// Reports errors if a module must not include a specific file. |
472 | /// |
473 | /// \param RequestingModule The module including a file. |
474 | /// |
475 | /// \param RequestingModuleIsModuleInterface \c true if the inclusion is in |
476 | /// the interface of RequestingModule, \c false if it's in the |
477 | /// implementation of RequestingModule. Value is ignored and |
478 | /// meaningless if RequestingModule is nullptr. |
479 | /// |
480 | /// \param FilenameLoc The location of the inclusion's filename. |
481 | /// |
482 | /// \param Filename The included filename as written. |
483 | /// |
484 | /// \param File The included file. |
485 | void (Module *RequestingModule, |
486 | bool RequestingModuleIsModuleInterface, |
487 | SourceLocation FilenameLoc, StringRef Filename, |
488 | FileEntryRef File); |
489 | |
490 | /// Determine whether the given header is part of a module |
491 | /// marked 'unavailable'. |
492 | bool (FileEntryRef ) const; |
493 | |
494 | /// Determine whether the given header is unavailable as part |
495 | /// of the specified module. |
496 | bool (FileEntryRef , |
497 | const Module *RequestingModule) const; |
498 | |
499 | /// Retrieve a module with the given name. |
500 | /// |
501 | /// \param Name The name of the module to look up. |
502 | /// |
503 | /// \returns The named module, if known; otherwise, returns null. |
504 | Module *findModule(StringRef Name) const; |
505 | |
506 | /// Retrieve a module with the given name using lexical name lookup, |
507 | /// starting at the given context. |
508 | /// |
509 | /// \param Name The name of the module to look up. |
510 | /// |
511 | /// \param Context The module context, from which we will perform lexical |
512 | /// name lookup. |
513 | /// |
514 | /// \returns The named module, if known; otherwise, returns null. |
515 | Module *lookupModuleUnqualified(StringRef Name, Module *Context) const; |
516 | |
517 | /// Retrieve a module with the given name within the given context, |
518 | /// using direct (qualified) name lookup. |
519 | /// |
520 | /// \param Name The name of the module to look up. |
521 | /// |
522 | /// \param Context The module for which we will look for a submodule. If |
523 | /// null, we will look for a top-level module. |
524 | /// |
525 | /// \returns The named submodule, if known; otherwose, returns null. |
526 | Module *lookupModuleQualified(StringRef Name, Module *Context) const; |
527 | |
528 | /// Find a new module or submodule, or create it if it does not already |
529 | /// exist. |
530 | /// |
531 | /// \param Name The name of the module to find or create. |
532 | /// |
533 | /// \param Parent The module that will act as the parent of this submodule, |
534 | /// or nullptr to indicate that this is a top-level module. |
535 | /// |
536 | /// \param IsFramework Whether this is a framework module. |
537 | /// |
538 | /// \param IsExplicit Whether this is an explicit submodule. |
539 | /// |
540 | /// \returns The found or newly-created module, along with a boolean value |
541 | /// that will be true if the module is newly-created. |
542 | std::pair<Module *, bool> findOrCreateModule(StringRef Name, Module *Parent, |
543 | bool IsFramework, |
544 | bool IsExplicit); |
545 | |
546 | /// Create a global module fragment for a C++ module unit. |
547 | /// |
548 | /// We model the global module fragment as a submodule of the module |
549 | /// interface unit. Unfortunately, we can't create the module interface |
550 | /// unit's Module until later, because we don't know what it will be called |
551 | /// usually. See C++20 [module.unit]/7.2 for the case we could know its |
552 | /// parent. |
553 | Module *createGlobalModuleFragmentForModuleUnit(SourceLocation Loc, |
554 | Module *Parent = nullptr); |
555 | Module *createImplicitGlobalModuleFragmentForModuleUnit(SourceLocation Loc, |
556 | Module *Parent); |
557 | |
558 | /// Create a global module fragment for a C++ module interface unit. |
559 | Module *createPrivateModuleFragmentForInterfaceUnit(Module *Parent, |
560 | SourceLocation Loc); |
561 | |
562 | /// Create a new C++ module with the specified kind, and reparent any pending |
563 | /// global module fragment(s) to it. |
564 | Module *createModuleUnitWithKind(SourceLocation Loc, StringRef Name, |
565 | Module::ModuleKind Kind); |
566 | |
567 | /// Create a new module for a C++ module interface unit. |
568 | /// The module must not already exist, and will be configured for the current |
569 | /// compilation. |
570 | /// |
571 | /// Note that this also sets the current module to the newly-created module. |
572 | /// |
573 | /// \returns The newly-created module. |
574 | Module *createModuleForInterfaceUnit(SourceLocation Loc, StringRef Name); |
575 | |
576 | /// Create a new module for a C++ module implementation unit. |
577 | /// The interface module for this implementation (implicitly imported) must |
578 | /// exist and be loaded and present in the modules map. |
579 | /// |
580 | /// \returns The newly-created module. |
581 | Module *createModuleForImplementationUnit(SourceLocation Loc, StringRef Name); |
582 | |
583 | /// Create a C++20 header unit. |
584 | Module *(SourceLocation Loc, StringRef Name, |
585 | Module::Header H); |
586 | |
587 | /// Infer the contents of a framework module map from the given |
588 | /// framework directory. |
589 | Module *inferFrameworkModule(DirectoryEntryRef FrameworkDir, bool IsSystem, |
590 | Module *Parent); |
591 | |
592 | /// Create a new top-level module that is shadowed by |
593 | /// \p ShadowingModule. |
594 | Module *createShadowedModule(StringRef Name, bool IsFramework, |
595 | Module *ShadowingModule); |
596 | |
597 | /// Creates a new declaration scope for module names, allowing |
598 | /// previously defined modules to shadow definitions from the new scope. |
599 | /// |
600 | /// \note Module names from earlier scopes will shadow names from the new |
601 | /// scope, which is the opposite of how shadowing works for variables. |
602 | void finishModuleDeclarationScope() { CurrentModuleScopeID += 1; } |
603 | |
604 | bool mayShadowNewModule(Module *ExistingModule) { |
605 | assert(!ExistingModule->Parent && "expected top-level module" ); |
606 | assert(ModuleScopeIDs.count(ExistingModule) && "unknown module" ); |
607 | return ModuleScopeIDs[ExistingModule] < CurrentModuleScopeID; |
608 | } |
609 | |
610 | /// Check whether a framework module can be inferred in the given directory. |
611 | bool canInferFrameworkModule(const DirectoryEntry *Dir) const { |
612 | auto It = InferredDirectories.find(Val: Dir); |
613 | return It != InferredDirectories.end() && It->getSecond().InferModules; |
614 | } |
615 | |
616 | /// Retrieve the module map file containing the definition of the given |
617 | /// module. |
618 | /// |
619 | /// \param Module The module whose module map file will be returned, if known. |
620 | /// |
621 | /// \returns The file entry for the module map file containing the given |
622 | /// module, or nullptr if the module definition was inferred. |
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 | OptionalFileEntryRef getModuleMapFileForUniquing(const Module *M) const; |
635 | |
636 | void setInferredModuleAllowedBy(Module *M, OptionalFileEntryRef ModMap); |
637 | |
638 | /// Canonicalize \p Path in a manner suitable for a module map file. In |
639 | /// particular, this canonicalizes the parent directory separately from the |
640 | /// filename so that it does not affect header resolution relative to the |
641 | /// modulemap. |
642 | /// |
643 | /// \returns an error code if any filesystem operations failed. In this case |
644 | /// \p Path is not modified. |
645 | std::error_code canonicalizeModuleMapPath(SmallVectorImpl<char> &Path); |
646 | |
647 | /// Get any module map files other than getModuleMapFileForUniquing(M) |
648 | /// that define submodules of a top-level module \p M. This is cheaper than |
649 | /// getting the module map file for each submodule individually, since the |
650 | /// expected number of results is very small. |
651 | AdditionalModMapsSet *getAdditionalModuleMapFiles(const Module *M) { |
652 | auto I = AdditionalModMaps.find(Val: M); |
653 | if (I == AdditionalModMaps.end()) |
654 | return nullptr; |
655 | return &I->second; |
656 | } |
657 | |
658 | void addAdditionalModuleMapFile(const Module *M, FileEntryRef ModuleMap); |
659 | |
660 | /// Resolve all of the unresolved exports in the given module. |
661 | /// |
662 | /// \param Mod The module whose exports should be resolved. |
663 | /// |
664 | /// \param Complain Whether to emit diagnostics for failures. |
665 | /// |
666 | /// \returns true if any errors were encountered while resolving exports, |
667 | /// false otherwise. |
668 | bool resolveExports(Module *Mod, bool Complain); |
669 | |
670 | /// Resolve all of the unresolved uses in the given module. |
671 | /// |
672 | /// \param Mod The module whose uses should be resolved. |
673 | /// |
674 | /// \param Complain Whether to emit diagnostics for failures. |
675 | /// |
676 | /// \returns true if any errors were encountered while resolving uses, |
677 | /// false otherwise. |
678 | bool resolveUses(Module *Mod, bool Complain); |
679 | |
680 | /// Resolve all of the unresolved conflicts in the given module. |
681 | /// |
682 | /// \param Mod The module whose conflicts should be resolved. |
683 | /// |
684 | /// \param Complain Whether to emit diagnostics for failures. |
685 | /// |
686 | /// \returns true if any errors were encountered while resolving conflicts, |
687 | /// false otherwise. |
688 | bool resolveConflicts(Module *Mod, bool Complain); |
689 | |
690 | /// Sets the umbrella header of the given module to the given header. |
691 | void |
692 | (Module *Mod, FileEntryRef , |
693 | const Twine &NameAsWritten, |
694 | const Twine &PathRelativeToRootModuleDirectory); |
695 | |
696 | /// Sets the umbrella directory of the given module to the given directory. |
697 | void setUmbrellaDirAsWritten(Module *Mod, DirectoryEntryRef UmbrellaDir, |
698 | const Twine &NameAsWritten, |
699 | const Twine &PathRelativeToRootModuleDirectory); |
700 | |
701 | /// Adds this header to the given module. |
702 | /// \param Role The role of the header wrt the module. |
703 | void (Module *Mod, Module::Header , |
704 | ModuleHeaderRole Role, bool Imported = false); |
705 | |
706 | /// Parse the given module map file, and record any modules we |
707 | /// encounter. |
708 | /// |
709 | /// \param File The file to be parsed. |
710 | /// |
711 | /// \param IsSystem Whether this module map file is in a system header |
712 | /// directory, and therefore should be considered a system module. |
713 | /// |
714 | /// \param HomeDir The directory in which relative paths within this module |
715 | /// map file will be resolved. |
716 | /// |
717 | /// \param ID The FileID of the file to process, if we've already entered it. |
718 | /// |
719 | /// \param Offset [inout] On input the offset at which to start parsing. On |
720 | /// output, the offset at which the module map terminated. |
721 | /// |
722 | /// \param ExternModuleLoc The location of the "extern module" declaration |
723 | /// that caused us to load this module map file, if any. |
724 | /// |
725 | /// \returns true if an error occurred, false otherwise. |
726 | bool parseModuleMapFile(FileEntryRef File, bool IsSystem, |
727 | DirectoryEntryRef HomeDir, FileID ID = FileID(), |
728 | unsigned *Offset = nullptr, |
729 | SourceLocation ExternModuleLoc = SourceLocation()); |
730 | |
731 | /// Dump the contents of the module map, for debugging purposes. |
732 | void dump(); |
733 | |
734 | using module_iterator = llvm::StringMap<Module *>::const_iterator; |
735 | |
736 | module_iterator module_begin() const { return Modules.begin(); } |
737 | module_iterator module_end() const { return Modules.end(); } |
738 | llvm::iterator_range<module_iterator> modules() const { |
739 | return {module_begin(), module_end()}; |
740 | } |
741 | |
742 | /// Cache a module load. M might be nullptr. |
743 | void cacheModuleLoad(const IdentifierInfo &II, Module *M) { |
744 | CachedModuleLoads[&II] = M; |
745 | } |
746 | |
747 | /// Return a cached module load. |
748 | std::optional<Module *> getCachedModuleLoad(const IdentifierInfo &II) { |
749 | auto I = CachedModuleLoads.find(Val: &II); |
750 | if (I == CachedModuleLoads.end()) |
751 | return std::nullopt; |
752 | return I->second; |
753 | } |
754 | }; |
755 | |
756 | } // namespace clang |
757 | |
758 | #endif // LLVM_CLANG_LEX_MODULEMAP_H |
759 | |