diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-12-07 22:05:21 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-12-07 22:05:21 +0000 |
commit | 23af6d58e392e18ae2946b799264717f480e6596 (patch) | |
tree | f91fee0a77b9dd9f0364b3ab2507edd90ace2537 /lib/Lex/ModuleMap.cpp | |
parent | 4813442c124d13a5c9cbf71beb7762275e45aacd (diff) |
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
Diffstat (limited to 'lib/Lex/ModuleMap.cpp')
-rw-r--r-- | lib/Lex/ModuleMap.cpp | 56 |
1 files changed, 51 insertions, 5 deletions
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<bool>(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; } |