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/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 {