C++ Modules TS: add frontend support for building pcm files from module
interface files. At the moment, all declarations (and no macros) are exported,
and 'export' declarations are not supported yet.
llvm-svn: 279794
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index 3e3215d..50eb6f8 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -558,6 +558,25 @@
return std::make_pair(Result, true);
}
+Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc,
+ StringRef Name) {
+ assert(LangOpts.CurrentModule == Name && "module name mismatch");
+ assert(!Modules[Name] && "redefining existing module");
+
+ auto *Result =
+ new Module(Name, Loc, nullptr, /*IsFramework*/ false,
+ /*IsExplicit*/ false, NumCreatedModules++);
+ Modules[Name] = SourceModule = Result;
+
+ // Mark the main source file as being within the newly-created module so that
+ // declarations and macros are properly visibility-restricted to it.
+ auto *MainFile = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID());
+ assert(MainFile && "no input file for module interface");
+ Headers[MainFile].push_back(KnownHeader(Result, PrivateHeader));
+
+ return Result;
+}
+
/// \brief For a framework module, infer the framework against which we
/// should link.
static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
@@ -805,7 +824,7 @@
Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header));
bool isCompilingModuleHeader =
- LangOpts.CompilingModule && Mod->getTopLevelModule() == SourceModule;
+ LangOpts.isCompilingModule() && Mod->getTopLevelModule() == SourceModule;
if (!Imported || isCompilingModuleHeader) {
// When we import HeaderFileInfo, the external source is expected to
// set the isModuleHeader flag itself.
diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp
index e2eceaf..33d690d 100644
--- a/clang/lib/Lex/PPLexerChange.cpp
+++ b/clang/lib/Lex/PPLexerChange.cpp
@@ -685,7 +685,7 @@
return true;
// Otherwise, we only need module macros if we're actually compiling a module
// interface.
- return getLangOpts().CompilingModule;
+ return getLangOpts().isCompilingModule();
}
void Preprocessor::LeaveSubmodule() {
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index a201838..3566c34 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -1795,7 +1795,7 @@
[this](Token &Tok, bool &HasLexedNextToken) -> int {
IdentifierInfo *II = ExpectFeatureIdentifierInfo(Tok, *this,
diag::err_expected_id_building_module);
- return getLangOpts().CompilingModule && II &&
+ return getLangOpts().isCompilingModule() && II &&
(II->getName() == getLangOpts().CurrentModule);
});
} else if (II == Ident__MODULE__) {
diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp
index 096a610..1f28b3b 100644
--- a/clang/lib/Lex/Preprocessor.cpp
+++ b/clang/lib/Lex/Preprocessor.cpp
@@ -480,7 +480,7 @@
}
Module *Preprocessor::getCurrentModule() {
- if (!getLangOpts().CompilingModule)
+ if (!getLangOpts().isCompilingModule())
return nullptr;
return getHeaderSearchInfo().lookupModule(getLangOpts().CurrentModule);
@@ -795,6 +795,23 @@
// If we have a non-empty module path, load the named module.
if (!ModuleImportPath.empty()) {
+ // Under the Modules TS, the dot is just part of the module name, and not
+ // a real hierarachy separator. Flatten such module names now.
+ //
+ // FIXME: Is this the right level to be performing this transformation?
+ std::string FlatModuleName;
+ if (getLangOpts().ModulesTS) {
+ for (auto &Piece : ModuleImportPath) {
+ if (!FlatModuleName.empty())
+ FlatModuleName += ".";
+ FlatModuleName += Piece.first->getName();
+ }
+ SourceLocation FirstPathLoc = ModuleImportPath[0].second;
+ ModuleImportPath.clear();
+ ModuleImportPath.push_back(
+ std::make_pair(getIdentifierInfo(FlatModuleName), FirstPathLoc));
+ }
+
Module *Imported = nullptr;
if (getLangOpts().Modules) {
Imported = TheModuleLoader.loadModule(ModuleImportLoc,