"module '%0' already has an umbrella header ('%1')">;
def err_mmap_umbrella_header_submodule : Error<
"submodule '%0' can not have an umbrella header">;
-
+def err_mmap_umbrella_clash : Error<
+ "umbrella header for module '%0' already covers this directory">;
+
}
namespace clang {
+class DirectoryEntry;
class FileEntry;
class FileManager;
class DiagnosticConsumer;
/// that header.
llvm::DenseMap<const FileEntry *, Module *> Headers;
+ /// \brief Mapping from directories with umbrella headers to the module
+ /// that is generated from the umbrella header.
+ ///
+ /// This mapping is used to map headers that haven't explicitly been named
+ /// in the module map over to the module that includes them via its umbrella
+ /// header.
+ llvm::DenseMap<const DirectoryEntry *, Module *> UmbrellaDirs;
+
friend class ModuleMapParser;
public:
if (Known != Headers.end())
return Known->second;
+ const DirectoryEntry *Dir = File->getDir();
+ llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
+ = UmbrellaDirs.find(Dir);
+ if (KnownDir != UmbrellaDirs.end())
+ return KnownDir->second;
+
+ // Walk up the directory hierarchy looking for umbrella headers.
+ llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs;
+ StringRef DirName = Dir->getName();
+ do {
+ // Retrieve our parent path.
+ DirName = llvm::sys::path::parent_path(DirName);
+ if (DirName.empty())
+ break;
+
+ // Resolve the parent path to a directory entry.
+ Dir = SourceMgr->getFileManager().getDirectory(DirName);
+ if (!Dir)
+ break;
+
+ KnownDir = UmbrellaDirs.find(Dir);
+ if (KnownDir != UmbrellaDirs.end()) {
+ Module *Result = KnownDir->second;
+
+ // Record each of the directories we stepped through as being part of
+ // the module we found, since the umbrella header covers them all.
+ for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
+ UmbrellaDirs[SkippedDirs[I]] = Result;
+
+ return Result;
+ }
+
+ SkippedDirs.push_back(Dir);
+ } while (true);
+
return 0;
}
Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
<< FileName << OwningModule->getFullModuleName();
HadError = true;
+ } else if ((OwningModule = Map.UmbrellaDirs[Directory])) {
+ Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
+ << OwningModule->getFullModuleName();
+ HadError = true;
} else {
// Record this umbrella header.
ActiveModule->UmbrellaHeader = File;
Map.Headers[File] = ActiveModule;
+ Map.UmbrellaDirs[Directory] = ActiveModule;
}
} else {
Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
-module diamond_top { umbrella "diamond_top.h" }
-module diamond_left { umbrella "diamond_left.h" }
-module diamond_right { umbrella "diamond_right.h" }
-module diamond_bottom { umbrella "diamond_bottom.h" }
-module irgen { umbrella "irgen.h" }
-module lookup_left_objc { umbrella "lookup_left.h" }
-module lookup_right_objc { umbrella "lookup_right.h" }
-module lookup_left_cxx { umbrella "lookup_left.hpp" }
-module lookup_right_cxx { umbrella "lookup_right.hpp" }
-module module_private_left { umbrella "module_private_left.h" }
-module module_private_right { umbrella "module_private_right.h" }
-module macros { umbrella "macros.h" }
-module category_top { umbrella "category_top.h" }
-module category_left { umbrella "category_left.h" }
-module category_right { umbrella "category_right.h" }
-module category_bottom { umbrella "category_bottom.h" }
-module redeclarations_left { umbrella "redeclarations_left.h" }
-module redeclarations_right { umbrella "redeclarations_right.h" }
-module load_failure { umbrella "load_failure.h" }
+module diamond_top { header "diamond_top.h" }
+module diamond_left { header "diamond_left.h" }
+module diamond_right { header "diamond_right.h" }
+module diamond_bottom { header "diamond_bottom.h" }
+module irgen { header "irgen.h" }
+module lookup_left_objc { header "lookup_left.h" }
+module lookup_right_objc { header "lookup_right.h" }
+module lookup_left_cxx { header "lookup_left.hpp" }
+module lookup_right_cxx { header "lookup_right.hpp" }
+module module_private_left { header "module_private_left.h" }
+module module_private_right { header "module_private_right.h" }
+module macros { header "macros.h" }
+module category_top { header "category_top.h" }
+module category_left { header "category_left.h" }
+module category_right { header "category_right.h" }
+module category_bottom { header "category_bottom.h" }
+module redeclarations_left { header "redeclarations_left.h" }
+module redeclarations_right { header "redeclarations_right.h" }
+module load_failure { header "load_failure.h" }
int umbrella;
+
+#include "umbrella_sub.h"
+
// RUN: %clang_cc1 -x objective-c -fmodule-cache-path %t -fmodule-name=libB -emit-module-from-map %S/Inputs/normal-module-map/module.map
// RUN: %clang_cc1 -x objective-c -fmodule-cache-path %t -fmodule-name=libNested -emit-module-from-map %S/Inputs/normal-module-map/nested/module.map
// RUN: %clang_cc1 -x objective-c -fmodule-cache-path %t -fauto-module-import -I %S/Inputs/normal-module-map %s -verify
-#include "Umbrella/Umbrella.h"
+#include "Umbrella/umbrella_sub.h"
int getUmbrella() {
- return umbrella;
+ return umbrella + umbrella_sub;
}
__import_module__ Umbrella2;