summaryrefslogtreecommitdiffstats
path: root/include/clang/Lex/ModuleMap.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Lex/ModuleMap.h')
-rw-r--r--include/clang/Lex/ModuleMap.h116
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();
OpenPOWER on IntegriCloud