aboutsummaryrefslogtreecommitdiff
path: root/include/clang
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang')
-rw-r--r--include/clang/Basic/DiagnosticFrontendKinds.td2
-rw-r--r--include/clang/Basic/DiagnosticLexKinds.td3
-rw-r--r--include/clang/Basic/Module.h57
-rw-r--r--include/clang/Lex/HeaderSearch.h5
-rw-r--r--include/clang/Lex/ModuleMap.h20
-rw-r--r--include/clang/Serialization/ASTBitCodes.h4
6 files changed, 76 insertions, 15 deletions
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index 5efba22529..82a570472c 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -143,4 +143,6 @@ def warn_missing_submodule : Warning<"missing submodule '%0'">,
InGroup<IncompleteUmbrella>;
def err_module_map_temp_file : Error<
"unable to write temporary module map file '%0'">, DefaultFatal;
+def err_module_unavailable : Error<"module '%0' requires feature '%1'">;
+
}
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index 62bd315842..41c67fb1f2 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -421,7 +421,8 @@ def err_mmap_explicit_top_level : Error<
"'explicit' is not permitted on top-level modules">;
def err_mmap_nested_submodule_id : Error<
"qualified module name can only be used to define modules at the top level">;
-
+def err_mmap_expected_feature : Error<"expected a feature name">;
+
def warn_auto_module_import : Warning<
"treating #%select{include|import|include_next|__include_macros}0 as an "
"import of module '%1'">, InGroup<AutoImport>, DefaultIgnore;
diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h
index 96b716e0ce..4e6bba2ed3 100644
--- a/include/clang/Basic/Module.h
+++ b/include/clang/Basic/Module.h
@@ -29,8 +29,9 @@ namespace llvm {
namespace clang {
-class FileEntry;
class DirectoryEntry;
+class FileEntry;
+class LangOptions;
/// \brief Describes the name of a module.
typedef llvm::SmallVector<std::pair<std::string, SourceLocation>, 2>
@@ -57,7 +58,18 @@ public:
/// \brief The headers that are part of this module.
llvm::SmallVector<const FileEntry *, 2> Headers;
-
+
+ /// \brief The set of language features required to use this module.
+ ///
+ /// If any of these features is not present, the \c IsAvailable bit
+ /// will be false to indicate that this (sub)module is not
+ /// available.
+ llvm::SmallVector<std::string, 2> Requires;
+
+ /// \brief Whether this module is available in the current
+ /// translation unit.
+ unsigned IsAvailable : 1;
+
/// \brief Whether this module was loaded from a module file.
unsigned IsFromModuleFile : 1;
@@ -134,21 +146,40 @@ public:
explicit Module(StringRef Name, SourceLocation DefinitionLoc,
bool IsFramework)
: Name(Name), DefinitionLoc(DefinitionLoc), Parent(0), Umbrella(),
- IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(false),
- InferSubmodules(false), InferExplicitSubmodules(false),
+ IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework),
+ IsExplicit(false), InferSubmodules(false), InferExplicitSubmodules(false),
InferExportWildcard(false), NameVisibility(Hidden) { }
/// \brief Construct a new module or submodule.
Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
bool IsFramework, bool IsExplicit)
: Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent),
- Umbrella(), IsFromModuleFile(false), IsFramework(IsFramework),
- IsExplicit(IsExplicit), InferSubmodules(false),
+ Umbrella(), IsAvailable(true), IsFromModuleFile(false),
+ IsFramework(IsFramework), IsExplicit(IsExplicit), InferSubmodules(false),
InferExplicitSubmodules(false), InferExportWildcard(false),
- NameVisibility(Hidden) { }
+ NameVisibility(Hidden)
+ {
+ if (Parent && !Parent->isAvailable())
+ IsAvailable = false;
+ }
~Module();
+ /// \brief Determine whether this module is available for use within the
+ /// current translation unit.
+ bool isAvailable() const { return IsAvailable; }
+
+ /// \brief Determine whether this module is available for use within the
+ /// current translation unit.
+ ///
+ /// \param LangOpts The language options used for the current
+ /// translation unit.
+ ///
+ /// \param Feature If this module is unavailable, this parameter
+ /// will be set to one of the features that is required for use of
+ /// this module (but is not available).
+ bool isAvailable(const LangOptions &LangOpts, StringRef &Feature) const;
+
/// \brief Determine whether this module is a submodule.
bool isSubModule() const { return Parent != 0; }
@@ -203,7 +234,17 @@ public:
bool hasUmbrellaDir() const {
return Umbrella && Umbrella.is<const DirectoryEntry *>();
}
-
+
+ /// \briaf Add the given feature requirement to the list of features
+ /// required by this module.
+ ///
+ /// \param Feature The feature that is required by this module (and
+ /// its submodules).
+ ///
+ /// \param LangOpts The set of language options that will be used to
+ /// evaluate the availability of this feature.
+ void addRequirement(StringRef Feature, const LangOptions &LangOpts);
+
/// \brief Print the module map for this module to the given stream.
///
void print(llvm::raw_ostream &OS, unsigned Indent = 0) const;
diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h
index ade5d2a6f1..10242fa264 100644
--- a/include/clang/Lex/HeaderSearch.h
+++ b/include/clang/Lex/HeaderSearch.h
@@ -185,7 +185,8 @@ class HeaderSearch {
explicit HeaderSearch(const HeaderSearch&);
void operator=(const HeaderSearch&);
public:
- HeaderSearch(FileManager &FM, DiagnosticsEngine &Diags);
+ HeaderSearch(FileManager &FM, DiagnosticsEngine &Diags,
+ const LangOptions &LangOpts);
~HeaderSearch();
FileManager &getFileMgr() const { return FileMgr; }
@@ -369,6 +370,8 @@ public:
bool hasModuleMap(StringRef Filename, const DirectoryEntry *Root);
/// \brief Retrieve the module that corresponds to the given file, if any.
+ ///
+ /// \param File The header that we wish to map to a module.
Module *findModuleForHeader(const FileEntry *File);
diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h
index 2d95255290..b017a05e97 100644
--- a/include/clang/Lex/ModuleMap.h
+++ b/include/clang/Lex/ModuleMap.h
@@ -38,8 +38,13 @@ class ModuleMapParser;
class ModuleMap {
SourceManager *SourceMgr;
llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
- LangOptions LangOpts;
-
+ const LangOptions &LangOpts;
+
+ /// \brief Language options used to parse the module map itself.
+ ///
+ /// These are always simple C language options.
+ LangOptions MMapLangOpts;
+
/// \brief The top-level modules that are known.
llvm::StringMap<Module *> Modules;
@@ -82,7 +87,10 @@ public:
///
/// \param DC A diagnostic consumer that will be cloned for use in generating
/// diagnostics.
- ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC);
+ ///
+ /// \param LangOpts Language options for this translation unit.
+ ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
+ const LangOptions &LangOpts);
/// \brief Destroy the module map.
///
@@ -96,6 +104,10 @@ public:
/// that no module owns this header file.
Module *findModuleForHeader(const FileEntry *File);
+ /// \brief Determine whether the given header is part of a module
+ /// marked 'unavailable'.
+ bool isHeaderInUnavailableModule(const FileEntry *Header);
+
/// \brief Retrieve a module with the given name.
///
/// \param The name of the module to look up.
@@ -188,7 +200,7 @@ public:
/// \brief Adds this header to the given module.
void addHeader(Module *Mod, const FileEntry *Header);
-
+
/// \brief Parse the given module map file, and record any modules we
/// encounter.
///
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index 7fd550f992..bd6e3a2b40 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -527,7 +527,9 @@ namespace clang {
SUBMODULE_IMPORTS = 5,
/// \brief Specifies the submodules that are re-exported from this
/// submodule.
- SUBMODULE_EXPORTS = 6
+ SUBMODULE_EXPORTS = 6,
+ /// \brief Specifies a required feature.
+ SUBMODULE_REQUIRES = 7
};
/// \defgroup ASTAST AST file AST constants