aboutsummaryrefslogtreecommitdiff
path: root/lib/Lex/ModuleMap.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-12-07 22:05:21 +0000
committerDouglas Gregor <dgregor@apple.com>2011-12-07 22:05:21 +0000
commit23af6d58e392e18ae2946b799264717f480e6596 (patch)
treef91fee0a77b9dd9f0364b3ab2507edd90ace2537 /lib/Lex/ModuleMap.cpp
parent4813442c124d13a5c9cbf71beb7762275e45aacd (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.cpp56
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;
}