summaryrefslogtreecommitdiffstats
path: root/include/clang/Basic/Module.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Basic/Module.h')
-rw-r--r--include/clang/Basic/Module.h102
1 files changed, 91 insertions, 11 deletions
diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h
index e3953a4..7470610 100644
--- a/include/clang/Basic/Module.h
+++ b/include/clang/Basic/Module.h
@@ -16,11 +16,13 @@
#define LLVM_CLANG_BASIC_MODULE_H
#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include <string>
@@ -63,6 +65,9 @@ public:
/// \brief The umbrella header or directory.
llvm::PointerUnion<const DirectoryEntry *, const FileEntry *> Umbrella;
+
+ /// \brief The name of the umbrella entry, as written in the module map.
+ std::string UmbrellaAsWritten;
private:
/// \brief The submodules of this module, indexed by name.
@@ -85,6 +90,9 @@ private:
/// \brief Cache of modules visible to lookup in this module.
mutable llvm::DenseSet<const Module*> VisibleModulesCache;
+ /// The ID used when referencing this module within a VisibleModuleSet.
+ unsigned VisibilityID;
+
public:
enum HeaderKind {
HK_Normal,
@@ -100,6 +108,17 @@ public:
struct Header {
std::string NameAsWritten;
const FileEntry *Entry;
+
+ explicit operator bool() { return Entry; }
+ };
+
+ /// \brief Information about a directory name as found in the module map
+ /// file.
+ struct DirectoryName {
+ std::string NameAsWritten;
+ const DirectoryEntry *Entry;
+
+ explicit operator bool() { return Entry; }
};
/// \brief The headers that are part of this module.
@@ -182,10 +201,7 @@ public:
/// particular module.
enum NameVisibilityKind {
/// \brief All of the names in this module are hidden.
- ///
Hidden,
- /// \brief Only the macro names in this module are visible.
- MacrosVisible,
/// \brief All of the names in this module are visible.
AllVisible
};
@@ -193,15 +209,12 @@ public:
/// \brief The visibility of names within this particular module.
NameVisibilityKind NameVisibility;
- /// \brief The location at which macros within this module became visible.
- SourceLocation MacroVisibilityLoc;
-
/// \brief The location of the inferred submodule.
SourceLocation InferredSubmoduleLoc;
/// \brief The set of modules imported by this module, and on which this
/// module depends.
- SmallVector<Module *, 2> Imports;
+ llvm::SmallSetVector<Module *, 2> Imports;
/// \brief Describes an exported module.
///
@@ -288,7 +301,7 @@ public:
/// \brief Construct a new module or submodule.
Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
- bool IsFramework, bool IsExplicit);
+ bool IsFramework, bool IsExplicit, unsigned VisibilityID);
~Module();
@@ -371,12 +384,14 @@ public:
/// \brief Retrieve the directory for which this module serves as the
/// umbrella.
- const DirectoryEntry *getUmbrellaDir() const;
+ DirectoryName getUmbrellaDir() const;
/// \brief Retrieve the header that serves as the umbrella header for this
/// module.
- const FileEntry *getUmbrellaHeader() const {
- return Umbrella.dyn_cast<const FileEntry *>();
+ Header getUmbrellaHeader() const {
+ if (auto *E = Umbrella.dyn_cast<const FileEntry *>())
+ return Header{UmbrellaAsWritten, E};
+ return Header{};
}
/// \brief Determine whether this module has an umbrella directory that is
@@ -399,6 +414,10 @@ public:
/// \brief The top-level headers associated with this module.
ArrayRef<const FileEntry *> getTopHeaders(FileManager &FileMgr);
+ /// \brief Determine whether this module has declared its intention to
+ /// directly use another module.
+ bool directlyUses(const Module *Requested) const;
+
/// \brief Add the given feature requirement to the list of features
/// required by this module.
///
@@ -437,6 +456,8 @@ public:
return VisibleModulesCache.count(M);
}
+ unsigned getVisibilityID() const { return VisibilityID; }
+
typedef std::vector<Module *>::iterator submodule_iterator;
typedef std::vector<Module *>::const_iterator submodule_const_iterator;
@@ -466,6 +487,65 @@ private:
void buildVisibleModulesCache() const;
};
+/// \brief A set of visible modules.
+class VisibleModuleSet {
+public:
+ VisibleModuleSet() : Generation(0) {}
+ VisibleModuleSet(VisibleModuleSet &&O)
+ : ImportLocs(std::move(O.ImportLocs)), Generation(O.Generation ? 1 : 0) {
+ O.ImportLocs.clear();
+ ++O.Generation;
+ }
+
+ /// Move from another visible modules set. Guaranteed to leave the source
+ /// empty and bump the generation on both.
+ VisibleModuleSet &operator=(VisibleModuleSet &&O) {
+ ImportLocs = std::move(O.ImportLocs);
+ O.ImportLocs.clear();
+ ++O.Generation;
+ ++Generation;
+ return *this;
+ }
+
+ /// \brief Get the current visibility generation. Incremented each time the
+ /// set of visible modules changes in any way.
+ unsigned getGeneration() const { return Generation; }
+
+ /// \brief Determine whether a module is visible.
+ bool isVisible(const Module *M) const {
+ return getImportLoc(M).isValid();
+ }
+
+ /// \brief Get the location at which the import of a module was triggered.
+ SourceLocation getImportLoc(const Module *M) const {
+ return M->getVisibilityID() < ImportLocs.size()
+ ? ImportLocs[M->getVisibilityID()]
+ : SourceLocation();
+ }
+
+ /// \brief A callback to call when a module is made visible (directly or
+ /// indirectly) by a call to \ref setVisible.
+ typedef llvm::function_ref<void(Module *M)> VisibleCallback;
+ /// \brief A callback to call when a module conflict is found. \p Path
+ /// consists of a sequence of modules from the conflicting module to the one
+ /// made visible, where each was exported by the next.
+ typedef llvm::function_ref<void(ArrayRef<Module *> Path,
+ Module *Conflict, StringRef Message)>
+ ConflictCallback;
+ /// \brief Make a specific module visible.
+ void setVisible(Module *M, SourceLocation Loc,
+ VisibleCallback Vis = [](Module *) {},
+ ConflictCallback Cb = [](ArrayRef<Module *>, Module *,
+ StringRef) {});
+
+private:
+ /// Import locations for each visible module. Indexed by the module's
+ /// VisibilityID.
+ std::vector<SourceLocation> ImportLocs;
+ /// Visibility generation, bumped every time the visibility state changes.
+ unsigned Generation;
+};
+
} // end namespace clang
OpenPOWER on IntegriCloud