summaryrefslogtreecommitdiffstats
path: root/clang/lib/Lex/ModuleMap.cpp
diff options
context:
space:
mode:
authorDaniel Jasper <djasper@google.com>2013-09-24 09:14:14 +0000
committerDaniel Jasper <djasper@google.com>2013-09-24 09:14:14 +0000
commitba7f2f7110c201e3564e89bd306e058aa9c6b881 (patch)
tree8f90b26f22d7dccaa4a21ed9d63f101ea2f090dc /clang/lib/Lex/ModuleMap.cpp
parent22127cee34f0d2cf816fed14875e8e1ac12eee3c (diff)
downloadbcm5719-llvm-ba7f2f7110c201e3564e89bd306e058aa9c6b881.tar.gz
bcm5719-llvm-ba7f2f7110c201e3564e89bd306e058aa9c6b881.zip
Module use declarations (II)
Review: http://llvm-reviews.chandlerc.com/D1546. I have picked up this patch form Lawrence (http://llvm-reviews.chandlerc.com/D1063) and did a few changes. From the original change description (updated as appropriate): This patch adds a check that ensures that modules only use modules they have so declared. To this end, it adds a statement on intended module use to the module.map grammar: use module-id A module can then only use headers from other modules if it 'uses' them. This enforcement is off by default, but may be turned on with the new option -fmodules-decluse. When enforcing the module semantics, we also need to consider a source file part of a module. This is achieved with a compiler option -fmodule-name=<module-id>. The compiler at present only applies restrictions to the module directly being built. llvm-svn: 191283
Diffstat (limited to 'clang/lib/Lex/ModuleMap.cpp')
-rw-r--r--clang/lib/Lex/ModuleMap.cpp64
1 files changed, 63 insertions, 1 deletions
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index df80a93e4db..0f12af361a4 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -387,6 +387,10 @@ ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
// Create a new module with this name.
Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
IsExplicit);
+ if (LangOpts.CurrentModule == Name) {
+ SourceModule = Result;
+ SourceModuleName = Name;
+ }
if (!Parent) {
Modules[Name] = Result;
if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
@@ -518,6 +522,10 @@ ModuleMap::inferFrameworkModule(StringRef ModuleName,
Module *Result = new Module(ModuleName, SourceLocation(), Parent,
/*IsFramework=*/true, /*IsExplicit=*/false);
+ if (LangOpts.CurrentModule == ModuleName) {
+ SourceModule = Result;
+ SourceModuleName = ModuleName;
+ }
if (IsSystem)
Result->IsSystem = IsSystem;
@@ -653,6 +661,20 @@ bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
return HadError;
}
+bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
+ bool HadError = false;
+ for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) {
+ Module *DirectUse =
+ resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain);
+ if (DirectUse)
+ Mod->DirectUses.push_back(DirectUse);
+ else
+ HadError = true;
+ }
+ Mod->UnresolvedDirectUses.clear();
+ return HadError;
+}
+
bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
bool HadError = false;
for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
@@ -727,6 +749,7 @@ namespace clang {
Period,
PrivateKeyword,
UmbrellaKeyword,
+ UseKeyword,
RequiresKeyword,
Star,
StringLiteral,
@@ -819,6 +842,7 @@ namespace clang {
SourceLocation LeadingLoc);
void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
void parseExportDecl();
+ void parseUseDecl();
void parseLinkDecl();
void parseConfigMacros();
void parseConflict();
@@ -873,6 +897,7 @@ retry:
.Case("private", MMToken::PrivateKeyword)
.Case("requires", MMToken::RequiresKeyword)
.Case("umbrella", MMToken::UmbrellaKeyword)
+ .Case("use", MMToken::UseKeyword)
.Default(MMToken::Identifier);
break;
@@ -1209,6 +1234,10 @@ void ModuleMapParser::parseModuleDecl() {
case MMToken::ExportKeyword:
parseExportDecl();
break;
+
+ case MMToken::UseKeyword:
+ parseUseDecl();
+ break;
case MMToken::RequiresKeyword:
parseRequiresDecl();
@@ -1593,7 +1622,7 @@ void ModuleMapParser::parseExportDecl() {
break;
}
- Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
+ Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
HadError = true;
return;
} while (true);
@@ -1604,6 +1633,38 @@ void ModuleMapParser::parseExportDecl() {
ActiveModule->UnresolvedExports.push_back(Unresolved);
}
+/// \brief Parse a module uses declaration.
+///
+/// uses-declaration:
+/// 'uses' wildcard-module-id
+void ModuleMapParser::parseUseDecl() {
+ assert(Tok.is(MMToken::UseKeyword));
+ consumeToken();
+ // Parse the module-id.
+ ModuleId ParsedModuleId;
+
+ do {
+ if (Tok.is(MMToken::Identifier)) {
+ ParsedModuleId.push_back(
+ std::make_pair(Tok.getString(), Tok.getLocation()));
+ consumeToken();
+
+ if (Tok.is(MMToken::Period)) {
+ consumeToken();
+ continue;
+ }
+
+ break;
+ }
+
+ Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
+ HadError = true;
+ return;
+ } while (true);
+
+ ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
+}
+
/// \brief Parse a link declaration.
///
/// module-declaration:
@@ -2001,6 +2062,7 @@ bool ModuleMapParser::parseModuleMapFile() {
case MMToken::Star:
case MMToken::StringLiteral:
case MMToken::UmbrellaKeyword:
+ case MMToken::UseKeyword:
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
HadError = true;
consumeToken();
OpenPOWER on IntegriCloud