]> granicus.if.org Git - clang/commitdiff
Implement inference for the "Private" submodule corresponding to
authorDouglas Gregor <dgregor@apple.com>
Wed, 7 Dec 2011 22:05:21 +0000 (22:05 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 7 Dec 2011 22:05:21 +0000 (22:05 +0000)
private headers in a framework.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146082 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Lex/ModuleMap.cpp
test/Modules/Inputs/Module.framework/PrivateHeaders/ModulePrivate.h [new file with mode: 0644]
test/Modules/auto-module-import.m

index f6df30200733e341af6a843a2199809685441bd2..b6ad71a030bd4c9731870558a25aeafd1d32910b 100644 (file)
@@ -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;
 }
 
diff --git a/test/Modules/Inputs/Module.framework/PrivateHeaders/ModulePrivate.h b/test/Modules/Inputs/Module.framework/PrivateHeaders/ModulePrivate.h
new file mode 100644 (file)
index 0000000..0782336
--- /dev/null
@@ -0,0 +1 @@
+int module_private;
index 4ddd0e10259f81648d10af33052cc04c8fe92271..3703127f34acc7ebb9dbc9c8c547b21c1f3af03c 100644 (file)
@@ -44,3 +44,7 @@ void testModuleSubFrameworkAgain() {
 #include <DependsOnModule/DependsOnModulePrivate.h> // expected-warning{{treating #include as an import of module 'DependsOnModule.Private.DependsOnModule'}}
 
 int getDependsOnModulePrivate() { return depends_on_module_private; }
+
+#include <Module/ModulePrivate.h> // expected-warning{{treating #include as an import of module 'Module.Private.ModulePrivate'}}
+
+int getModulePrivate() { return module_private; }