diff options
Diffstat (limited to 'include/clang/Lex/ModuleMap.h')
-rw-r--r-- | include/clang/Lex/ModuleMap.h | 116 |
1 files changed, 82 insertions, 34 deletions
diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h index a86a927..ed885a7 100644 --- a/include/clang/Lex/ModuleMap.h +++ b/include/clang/Lex/ModuleMap.h @@ -65,19 +65,21 @@ private: llvm::StringMap<Module *> Modules; public: - /// \brief Describes the role of a module header. + /// \brief Flags describing the role of a module header. enum ModuleHeaderRole { /// \brief This header is normally included in the module. - NormalHeader, + NormalHeader = 0x0, /// \brief This header is included but private. - PrivateHeader, - /// \brief This header is explicitly excluded from the module. - ExcludedHeader + PrivateHeader = 0x1, + /// \brief This header is part of the module (for layering purposes) but + /// should be textually included. + TextualHeader = 0x2, // Caution: Adding an enumerator needs other changes. // Adjust the number of bits for KnownHeader::Storage. // Adjust the bitfield HeaderFileInfo::HeaderRole size. // Adjust the HeaderFileInfoTrait::ReadData streaming. // Adjust the HeaderFileInfoTrait::EmitData streaming. + // Adjust ModuleMap::addHeader. }; /// \brief A header that is known to reside within a given module, @@ -96,8 +98,8 @@ public: ModuleHeaderRole getRole() const { return Storage.getInt(); } /// \brief Whether this header is available in the module. - bool isAvailable() const { - return getRole() != ExcludedHeader && getModule()->isAvailable(); + bool isAvailable() const { + return getModule()->isAvailable(); } // \brief Whether this known header is valid (i.e., it has an @@ -107,6 +109,8 @@ public: } }; + typedef llvm::SmallPtrSet<const FileEntry *, 1> AdditionalModMapsSet; + private: typedef llvm::DenseMap<const FileEntry *, SmallVector<KnownHeader, 1> > HeadersMap; @@ -123,15 +127,29 @@ private: /// header. llvm::DenseMap<const DirectoryEntry *, Module *> UmbrellaDirs; + /// \brief The set of attributes that can be attached to a module. + struct Attributes { + Attributes() : IsSystem(), IsExternC(), IsExhaustive() {} + + /// \brief Whether this is a system module. + unsigned IsSystem : 1; + + /// \brief Whether this is an extern "C" module. + unsigned IsExternC : 1; + + /// \brief Whether this is an exhaustive set of configuration macros. + unsigned IsExhaustive : 1; + }; + /// \brief A directory for which framework modules can be inferred. struct InferredDirectory { - InferredDirectory() : InferModules(), InferSystemModules() { } + InferredDirectory() : InferModules() {} /// \brief Whether to infer modules from this directory. unsigned InferModules : 1; - /// \brief Whether the modules we infer are [system] modules. - unsigned InferSystemModules : 1; + /// \brief The attributes to use for inferred modules. + Attributes Attrs; /// \brief If \c InferModules is non-zero, the module map file that allowed /// inferred modules. Otherwise, nullptr. @@ -146,6 +164,12 @@ private: /// framework modules from within those directories. llvm::DenseMap<const DirectoryEntry *, InferredDirectory> InferredDirectories; + /// A mapping from an inferred module to the module map that allowed the + /// inference. + llvm::DenseMap<const Module *, const FileEntry *> InferredModuleAllowedBy; + + llvm::DenseMap<const Module *, AdditionalModMapsSet> AdditionalModMaps; + /// \brief Describes whether we haved parsed a particular file as a module /// map. llvm::DenseMap<const FileEntry *, bool> ParsedModuleMap; @@ -204,6 +228,10 @@ private: return static_cast<bool>(findHeaderInUmbrellaDirs(File, IntermediateDirs)); } + Module *inferFrameworkModule(StringRef ModuleName, + const DirectoryEntry *FrameworkDir, + Attributes Attrs, Module *Parent); + public: /// \brief Construct a new module map. /// @@ -241,11 +269,16 @@ public: /// used from. Used to disambiguate if a header is present in multiple /// modules. /// + /// \param IncludeTextualHeaders If \c true, also find textual headers. By + /// default, these are treated like excluded headers and result in no known + /// header being found. + /// /// \returns The module KnownHeader, which provides the module that owns the /// given header file. The KnownHeader is default constructed to indicate /// that no module owns this header file. KnownHeader findModuleForHeader(const FileEntry *File, - Module *RequestingModule = nullptr); + Module *RequestingModule = nullptr, + bool IncludeTextualHeaders = false); /// \brief Reports errors if a module must not include a specific file. /// @@ -306,9 +339,6 @@ public: /// \param Parent The module that will act as the parent of this submodule, /// or NULL to indicate that this is a top-level module. /// - /// \param ModuleMap The module map that defines or allows the inference of - /// this module. - /// /// \param IsFramework Whether this is a framework module. /// /// \param IsExplicit Whether this is an explicit submodule. @@ -316,26 +346,9 @@ public: /// \returns The found or newly-created module, along with a boolean value /// that will be true if the module is newly-created. std::pair<Module *, bool> findOrCreateModule(StringRef Name, Module *Parent, - const FileEntry *ModuleMap, bool IsFramework, bool IsExplicit); - /// \brief Determine whether we can infer a framework module a framework - /// with the given name in the given - /// - /// \param ParentDir The directory that is the parent of the framework - /// directory. - /// - /// \param Name The name of the module. - /// - /// \param IsSystem Will be set to 'true' if the inferred module must be a - /// system module. - /// - /// \returns true if we are allowed to infer a framework module, and false - /// otherwise. - bool canInferFrameworkModule(const DirectoryEntry *ParentDir, - StringRef Name, bool &IsSystem) const; - /// \brief Infer the contents of a framework module map from the given /// framework directory. Module *inferFrameworkModule(StringRef ModuleName, @@ -349,7 +362,35 @@ public: /// /// \returns The file entry for the module map file containing the given /// module, or NULL if the module definition was inferred. - const FileEntry *getContainingModuleMapFile(Module *Module) const; + const FileEntry *getContainingModuleMapFile(const Module *Module) const; + + /// \brief Get the module map file that (along with the module name) uniquely + /// identifies this module. + /// + /// The particular module that \c Name refers to may depend on how the module + /// was found in header search. However, the combination of \c Name and + /// this module map will be globally unique for top-level modules. In the case + /// of inferred modules, returns the module map that allowed the inference + /// (e.g. contained 'module *'). Otherwise, returns + /// getContainingModuleMapFile(). + const FileEntry *getModuleMapFileForUniquing(const Module *M) const; + + void setInferredModuleAllowedBy(Module *M, const FileEntry *ModuleMap); + + /// \brief Get any module map files other than getModuleMapFileForUniquing(M) + /// that define submodules of a top-level module \p M. This is cheaper than + /// getting the module map file for each submodule individually, since the + /// expected number of results is very small. + AdditionalModMapsSet *getAdditionalModuleMapFiles(const Module *M) { + auto I = AdditionalModMaps.find(M); + if (I == AdditionalModMaps.end()) + return nullptr; + return &I->second; + } + + void addAdditionalModuleMapFile(const Module *M, const FileEntry *ModuleMap) { + AdditionalModMaps[M].insert(ModuleMap); + } /// \brief Resolve all of the unresolved exports in the given module. /// @@ -401,9 +442,12 @@ public: /// \brief Adds this header to the given module. /// \param Role The role of the header wrt the module. - void addHeader(Module *Mod, const FileEntry *Header, + void addHeader(Module *Mod, Module::Header Header, ModuleHeaderRole Role); + /// \brief Marks this header as being excluded from the given module. + void excludeHeader(Module *Mod, Module::Header Header); + /// \brief Parse the given module map file, and record any modules we /// encounter. /// @@ -412,8 +456,12 @@ public: /// \param IsSystem Whether this module map file is in a system header /// directory, and therefore should be considered a system module. /// + /// \param HomeDir The directory in which relative paths within this module + /// map file will be resolved. + /// /// \returns true if an error occurred, false otherwise. - bool parseModuleMapFile(const FileEntry *File, bool IsSystem); + bool parseModuleMapFile(const FileEntry *File, bool IsSystem, + const DirectoryEntry *HomeDir); /// \brief Dump the contents of the module map, for debugging purposes. void dump(); |