Tweak the syntax of umbrella headers, so that "umbrella" is treated as
a modifier for a header declarartion, e.g.,
umbrella header "headername"
Collapse the umbrella-handling code in the parser into the
header-handling code, so we don't duplicate the header-search logic.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146159 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Basic/Module.cpp b/lib/Basic/Module.cpp
index 1697157..69a62d3 100644
--- a/lib/Basic/Module.cpp
+++ b/lib/Basic/Module.cpp
@@ -90,9 +90,14 @@
if (const FileEntry *UmbrellaHeader = getUmbrellaHeader()) {
OS.indent(Indent + 2);
- OS << "umbrella \"";
+ OS << "umbrella header \"";
OS.write_escaped(UmbrellaHeader->getName());
OS << "\"\n";
+ } else if (const DirectoryEntry *UmbrellaDir = getUmbrellaDir()) {
+ OS.indent(Indent + 2);
+ OS << "umbrella \"";
+ OS.write_escaped(UmbrellaDir->getName());
+ OS << "\"\n";
}
for (unsigned I = 0, N = Headers.size(); I != N; ++I) {
diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp
index 8457b1c..e4c9d77 100644
--- a/lib/Lex/ModuleMap.cpp
+++ b/lib/Lex/ModuleMap.cpp
@@ -259,7 +259,7 @@
else
Modules[ModuleName] = Result;
- // umbrella "umbrella-header-name"
+ // umbrella header "umbrella-header-name"
Result->Umbrella = UmbrellaHeader;
Headers[UmbrellaHeader] = Result;
UmbrellaDirs[FrameworkDir] = Result;
@@ -493,8 +493,7 @@
ModuleId;
bool parseModuleId(ModuleId &Id);
void parseModuleDecl();
- void parseUmbrellaDecl();
- void parseHeaderDecl();
+ void parseHeaderDecl(SourceLocation UmbrellaLoc);
void parseExportDecl();
void parseInferredSubmoduleDecl(bool Explicit);
@@ -656,7 +655,6 @@
/// 'explicit'[opt] 'framework'[opt] 'module' module-id { module-member* }
///
/// module-member:
-/// umbrella-declaration
/// header-declaration
/// submodule-declaration
/// export-declaration
@@ -798,14 +796,14 @@
parseExportDecl();
break;
- case MMToken::HeaderKeyword:
- parseHeaderDecl();
+ case MMToken::UmbrellaKeyword:
+ parseHeaderDecl(consumeToken());
break;
- case MMToken::UmbrellaKeyword:
- parseUmbrellaDecl();
+ case MMToken::HeaderKeyword:
+ parseHeaderDecl(SourceLocation());
break;
-
+
default:
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
consumeToken();
@@ -845,105 +843,16 @@
}
}
-/// \brief Parse an umbrella header declaration.
-///
-/// umbrella-declaration:
-/// 'umbrella' string-literal
-void ModuleMapParser::parseUmbrellaDecl() {
- assert(Tok.is(MMToken::UmbrellaKeyword));
- SourceLocation UmbrellaLoc = consumeToken();
-
- // Parse the header name.
- if (!Tok.is(MMToken::StringLiteral)) {
- Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
- << "umbrella";
- HadError = true;
- return;
- }
- std::string FileName = Tok.getString();
- SourceLocation FileNameLoc = consumeToken();
-
- // Check whether we already have an umbrella header.
- if (ActiveModule->getUmbrellaHeader()) {
- Diags.Report(FileNameLoc, diag::err_mmap_umbrella_header_conflict)
- << ActiveModule->getFullModuleName()
- << ActiveModule->getUmbrellaHeader()->getName();
- HadError = true;
- return;
- }
-
- // Look for this file.
- llvm::SmallString<128> PathName;
- const FileEntry *File = 0;
-
- if (llvm::sys::path::is_absolute(FileName)) {
- PathName = FileName;
- File = SourceMgr.getFileManager().getFile(PathName);
- } else {
- // Search for the header file within the search directory.
- PathName += Directory->getName();
- unsigned PathLength = PathName.size();
-
- if (ActiveModule->isPartOfFramework()) {
- appendSubframeworkPaths(ActiveModule, PathName);
-
- // Check whether this file is in the public headers.
- llvm::sys::path::append(PathName, "Headers");
- llvm::sys::path::append(PathName, FileName);
- File = SourceMgr.getFileManager().getFile(PathName);
-
- if (!File) {
- // Check whether this file is in the private headers.
- PathName.resize(PathLength);
- llvm::sys::path::append(PathName, "PrivateHeaders");
- llvm::sys::path::append(PathName, FileName);
- File = SourceMgr.getFileManager().getFile(PathName);
- }
- } else {
- // Lookup for normal headers.
- llvm::sys::path::append(PathName, FileName);
- File = SourceMgr.getFileManager().getFile(PathName);
- }
- }
-
- // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
- // Come up with a lazy way to do this.
- if (File) {
- const DirectoryEntry *UmbrellaDir = File->getDir();
- if (ActiveModule->IsFramework) {
- // For framework modules, use the framework directory as the umbrella
- // directory.
- UmbrellaDir = SourceMgr.getFileManager().getDirectory(
- llvm::sys::path::parent_path(UmbrellaDir->getName()));
- }
-
- if (const Module *OwningModule = Map.Headers[File]) {
- Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
- << FileName << OwningModule->getFullModuleName();
- HadError = true;
- } else if ((OwningModule = Map.UmbrellaDirs[UmbrellaDir])) {
- Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
- << OwningModule->getFullModuleName();
- HadError = true;
- } else {
- // Record this umbrella header.
- Map.setUmbrellaHeader(ActiveModule, File);
- }
- } else {
- Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
- << true << FileName;
- HadError = true;
- }
-}
-
/// \brief Parse a header declaration.
///
/// header-declaration:
-/// 'header' string-literal
-void ModuleMapParser::parseHeaderDecl() {
+/// 'umbrella'[opt] 'header' string-literal
+void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc) {
assert(Tok.is(MMToken::HeaderKeyword));
consumeToken();
+ bool Umbrella = UmbrellaLoc.isValid();
+
// Parse the header name.
if (!Tok.is(MMToken::StringLiteral)) {
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
@@ -954,6 +863,15 @@
std::string FileName = Tok.getString();
SourceLocation FileNameLoc = consumeToken();
+ // Check whether we already have an umbrella header.
+ if (Umbrella && ActiveModule->getUmbrellaHeader()) {
+ Diags.Report(FileNameLoc, diag::err_mmap_umbrella_header_conflict)
+ << ActiveModule->getFullModuleName()
+ << ActiveModule->getUmbrellaHeader()->getName();
+ HadError = true;
+ return;
+ }
+
// Look for this file.
const FileEntry *File = 0;
llvm::SmallString<128> PathName;
@@ -994,8 +912,25 @@
Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
<< FileName << OwningModule->getFullModuleName();
HadError = true;
+ } else if (Umbrella) {
+ const DirectoryEntry *UmbrellaDir = File->getDir();
+ if (ActiveModule->IsFramework) {
+ // For framework modules, use the framework directory as the umbrella
+ // directory.
+ UmbrellaDir = SourceMgr.getFileManager().getDirectory(
+ llvm::sys::path::parent_path(UmbrellaDir->getName()));
+ }
+
+ if ((OwningModule = Map.UmbrellaDirs[UmbrellaDir])) {
+ Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
+ << OwningModule->getFullModuleName();
+ HadError = true;
+ } else {
+ // Record this umbrella header.
+ Map.setUmbrellaHeader(ActiveModule, File);
+ }
} else {
- // Record this file.
+ // Record this header.
Map.addHeader(ActiveModule, File);
}
} else {
diff --git a/test/Modules/Inputs/DependsOnModule.framework/module.map b/test/Modules/Inputs/DependsOnModule.framework/module.map
index 6bf82b4..d8fe2fc 100644
--- a/test/Modules/Inputs/DependsOnModule.framework/module.map
+++ b/test/Modules/Inputs/DependsOnModule.framework/module.map
@@ -1,11 +1,11 @@
framework module DependsOnModule {
- umbrella "DependsOnModule.h"
+ umbrella header "DependsOnModule.h"
header "other.h"
module * {
export *
}
explicit framework module SubFramework {
- umbrella "SubFramework.h"
+ umbrella header "SubFramework.h"
module * {
export *
diff --git a/test/Modules/Inputs/normal-module-map/Umbrella/module.map b/test/Modules/Inputs/normal-module-map/Umbrella/module.map
index dd2e434..611cf9f 100644
--- a/test/Modules/Inputs/normal-module-map/Umbrella/module.map
+++ b/test/Modules/Inputs/normal-module-map/Umbrella/module.map
@@ -1,3 +1,3 @@
module Umbrella {
- umbrella "Umbrella.h"
+ umbrella header "Umbrella.h"
}
\ No newline at end of file
diff --git a/test/Modules/Inputs/normal-module-map/Umbrella2/module.map b/test/Modules/Inputs/normal-module-map/Umbrella2/module.map
index 7c6c3f4..1e57704 100644
--- a/test/Modules/Inputs/normal-module-map/Umbrella2/module.map
+++ b/test/Modules/Inputs/normal-module-map/Umbrella2/module.map
@@ -1,3 +1,3 @@
module Umbrella2 {
- umbrella "Umbrella2.h"
-}
\ No newline at end of file
+ umbrella header "Umbrella2.h"
+}