aboutsummaryrefslogtreecommitdiff
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.h88
1 files changed, 64 insertions, 24 deletions
diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h
index e8d774e1eb54..9b66840ba412 100644
--- a/include/clang/Basic/Module.h
+++ b/include/clang/Basic/Module.h
@@ -51,10 +51,21 @@ public:
/// \brief The location of the module definition.
SourceLocation DefinitionLoc;
-
+
/// \brief The parent of this module. This will be NULL for the top-level
/// module.
Module *Parent;
+
+ /// \brief 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
+ /// \c ModuleMap will be globally unique for top-level modules. In the case of
+ /// inferred modules, \c ModuleMap will contain the module map that allowed
+ /// the inference (e.g. contained 'Module *') rather than the virtual
+ /// inferred module map file.
+ const FileEntry *ModuleMap;
/// \brief The umbrella header or directory.
llvm::PointerUnion<const DirectoryEntry *, const FileEntry *> Umbrella;
@@ -88,7 +99,19 @@ public:
SmallVector<const FileEntry *, 2> ExcludedHeaders;
/// \brief The headers that are private to this module.
- llvm::SmallVector<const FileEntry *, 2> PrivateHeaders;
+ SmallVector<const FileEntry *, 2> PrivateHeaders;
+
+ /// \brief Information about a header directive as found in the module map
+ /// file.
+ struct HeaderDirective {
+ SourceLocation FileNameLoc;
+ std::string FileName;
+ bool IsUmbrella;
+ };
+
+ /// \brief Headers that are mentioned in the module map file but could not be
+ /// found on the file system.
+ SmallVector<HeaderDirective, 1> MissingHeaders;
/// \brief An individual requirement: a feature name and a flag indicating
/// the required state of that feature.
@@ -100,8 +123,13 @@ public:
/// will be false to indicate that this (sub)module is not available.
SmallVector<Requirement, 2> Requirements;
- /// \brief Whether this module is available in the current
- /// translation unit.
+ /// \brief Whether this module is missing a feature from \c Requirements.
+ unsigned IsMissingRequirement : 1;
+
+ /// \brief Whether this module is available in the current translation unit.
+ ///
+ /// If the module is missing headers or does not meet all requirements then
+ /// this bit will be 0.
unsigned IsAvailable : 1;
/// \brief Whether this module was loaded from a module file.
@@ -116,7 +144,15 @@ public:
/// \brief Whether this is a "system" module (which assumes that all
/// headers in it are system headers).
unsigned IsSystem : 1;
-
+
+ /// \brief Whether this is an 'extern "C"' module (which implicitly puts all
+ /// headers in it within an 'extern "C"' block, and allows the module to be
+ /// imported within such a block).
+ unsigned IsExternC : 1;
+
+ /// \brief Whether this is an inferred submodule (module * { ... }).
+ unsigned IsInferred : 1;
+
/// \brief Whether we should infer submodules for this module based on
/// the headers.
///
@@ -148,11 +184,14 @@ public:
MacrosVisible,
/// \brief All of the names in this module are visible.
AllVisible
- };
-
- ///\ brief The visibility of names within this particular module.
+ };
+
+ /// \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;
@@ -243,19 +282,11 @@ public:
/// \brief The list of conflicts.
std::vector<Conflict> Conflicts;
- /// \brief Construct a top-level module.
- explicit Module(StringRef Name, SourceLocation DefinitionLoc,
- bool IsFramework)
- : Name(Name), DefinitionLoc(DefinitionLoc), Parent(0),Umbrella(),ASTFile(0),
- IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework),
- IsExplicit(false), IsSystem(false),
- InferSubmodules(false), InferExplicitSubmodules(false),
- InferExportWildcard(false), ConfigMacrosExhaustive(false),
- NameVisibility(Hidden) { }
-
/// \brief Construct a new module or submodule.
- Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
- bool IsFramework, bool IsExplicit);
+ ///
+ /// For an explanation of \p ModuleMap, see Module::ModuleMap.
+ Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
+ const FileEntry *ModuleMap, bool IsFramework, bool IsExplicit);
~Module();
@@ -276,14 +307,15 @@ public:
/// this module.
bool isAvailable(const LangOptions &LangOpts,
const TargetInfo &Target,
- Requirement &Req) const;
+ Requirement &Req,
+ HeaderDirective &MissingHeader) const;
/// \brief Determine whether this module is a submodule.
- bool isSubModule() const { return Parent != 0; }
+ bool isSubModule() const { return Parent != nullptr; }
/// \brief Determine whether this module is a submodule of the given other
/// module.
- bool isSubModuleOf(Module *Other) const;
+ bool isSubModuleOf(const Module *Other) const;
/// \brief Determine whether this module is a part of a framework,
/// either because it is a framework module or because it is a submodule
@@ -330,7 +362,8 @@ public:
/// \brief Set the serialized AST file for the top-level module of this module.
void setASTFile(const FileEntry *File) {
- assert((getASTFile() == 0 || getASTFile() == File) && "file path changed");
+ assert((File == nullptr || getASTFile() == nullptr ||
+ getASTFile() == File) && "file path changed");
getTopLevelModule()->ASTFile = File;
}
@@ -382,6 +415,9 @@ public:
const LangOptions &LangOpts,
const TargetInfo &Target);
+ /// \brief Mark this module and all of its submodules as unavailable.
+ void markUnavailable(bool MissingRequirement = false);
+
/// \brief Find the submodule with the given name.
///
/// \returns The submodule if found, or NULL otherwise.
@@ -389,6 +425,10 @@ public:
/// \brief Determine whether the specified module would be visible to
/// a lookup at the end of this module.
+ ///
+ /// FIXME: This may return incorrect results for (submodules of) the
+ /// module currently being built, if it's queried before we see all
+ /// of its imports.
bool isModuleVisible(const Module *M) const {
if (VisibleModulesCache.empty())
buildVisibleModulesCache();