From: Douglas Gregor Date: Wed, 7 Dec 2011 22:05:21 +0000 (+0000) Subject: Implement inference for the "Private" submodule corresponding to X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=23af6d58e392e18ae2946b799264717f480e6596;p=clang Implement inference for the "Private" submodule corresponding to private headers in a framework. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146082 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp index f6df302007..b6ad71a030 100644 --- a/lib/Lex/ModuleMap.cpp +++ b/lib/Lex/ModuleMap.cpp @@ -118,17 +118,28 @@ Module *ModuleMap::findModuleForHeader(const FileEntry *File) { // For a framework module, the umbrella directory is the framework // directory, so strip off the "Headers" or "PrivateHeaders". - // FIXME: Should we tack on an "explicit" for PrivateHeaders? That - // might be what we want, but it feels like a hack. + bool Explicit = UmbrellaModule->InferExplicitSubmodules; unsigned LastSkippedDir = SkippedDirs.size(); - if (LastSkippedDir && UmbrellaModule->IsFramework) + if (LastSkippedDir && UmbrellaModule->IsFramework) { + if (llvm::sys::path::filename(SkippedDirs.back()->getName()) + == "PrivateHeaders") { + // For private headers, add an explicit "Private" module. + // FIXME: This feels somewhat hackish. Do we want to introduce + // some kind of "umbrella directory" here? + Result = findOrCreateModule("Private", Result, + /*IsFramework=*/false, + /*IsExplicit=*/true).first; + Explicit = true; + } + --LastSkippedDir; + } for (unsigned I = LastSkippedDir; I != 0; --I) { // Find or create the module that corresponds to this directory name. StringRef Name = llvm::sys::path::stem(SkippedDirs[I-1]->getName()); Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, - UmbrellaModule->InferExplicitSubmodules).first; + Explicit).first; // Associate the module and the directory. UmbrellaDirs[SkippedDirs[I-1]] = Result; @@ -142,7 +153,7 @@ Module *ModuleMap::findModuleForHeader(const FileEntry *File) { // Infer a submodule with the same name as this header file. StringRef Name = llvm::sys::path::stem(File->getName()); Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, - UmbrellaModule->InferExplicitSubmodules).first; + Explicit).first; // If inferred submodules export everything they import, add a // wildcard to the set of exports. @@ -278,6 +289,41 @@ ModuleMap::inferFrameworkModule(StringRef ModuleName, } } + // Look for private headers. + Module *ModulePrivate = 0; + llvm::SmallString<128> PrivateHeadersDirName(FrameworkDir->getName()); + llvm::sys::path::append(PrivateHeadersDirName, "PrivateHeaders"); + for (llvm::sys::fs::directory_iterator Dir(PrivateHeadersDirName.str(), EC), + DirEnd; + Dir != DirEnd && !EC; Dir.increment(EC)) { + // Check whether this entry has an extension typically associated with + // headers. + if (!llvm::StringSwitch(llvm::sys::path::extension(Dir->path())) + .Cases(".h", ".H", ".hh", ".hpp", true) + .Default(false)) + continue; + + if (const FileEntry *PrivateHeader = FileMgr.getFile(Dir->path())) { + // Create the "private" submodule, if we haven't done so already. + if (!ModulePrivate) { + ModulePrivate = findOrCreateModule("Private", Result, + /*IsFramework=*/false, + /*IsExplicit=*/true).first; + } + + Module *Sub = findOrCreateModule(llvm::sys::path::stem(Dir->path()), + ModulePrivate, /*IsFramework=*/false, + /*IsExplicit=*/true).first; + // header "the private header" + Sub->Headers.push_back(PrivateHeader); + + // export * + Sub->Exports.push_back(Module::ExportDecl(0, true)); + + Headers[PrivateHeader] = Sub; + } + } + return Result; } diff --git a/test/Modules/Inputs/Module.framework/PrivateHeaders/ModulePrivate.h b/test/Modules/Inputs/Module.framework/PrivateHeaders/ModulePrivate.h new file mode 100644 index 0000000000..0782336df9 --- /dev/null +++ b/test/Modules/Inputs/Module.framework/PrivateHeaders/ModulePrivate.h @@ -0,0 +1 @@ +int module_private; diff --git a/test/Modules/auto-module-import.m b/test/Modules/auto-module-import.m index 4ddd0e1025..3703127f34 100644 --- a/test/Modules/auto-module-import.m +++ b/test/Modules/auto-module-import.m @@ -44,3 +44,7 @@ void testModuleSubFrameworkAgain() { #include // expected-warning{{treating #include as an import of module 'DependsOnModule.Private.DependsOnModule'}} int getDependsOnModulePrivate() { return depends_on_module_private; } + +#include // expected-warning{{treating #include as an import of module 'Module.Private.ModulePrivate'}} + +int getModulePrivate() { return module_private; }