[cfe-commits] r145941 - in /cfe/trunk: include/clang/Basic/ lib/Lex/ test/Modules/ test/Modules/Inputs/DependsOnModule.framework/ test/Modules/Inputs/DependsOnModule.framework/Frameworks/ test/Modules/Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/ test/Modules/Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/

Douglas Gregor dgregor at apple.com
Tue Dec 6 09:16:41 PST 2011


Author: dgregor
Date: Tue Dec  6 11:16:41 2011
New Revision: 145941

URL: http://llvm.org/viewvc/llvm-project?rev=145941&view=rev
Log:
Implement modules support for subframeworks (aka embedded
frameworks). A submodule can now be labeled as a "framework", and
header search will look into the appropriate Headers/PrivateHeaders
subdirectories for named headers.


Added:
    cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/Frameworks/
    cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/
    cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/
    cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/Other.h   (with props)
    cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/SubFramework.h   (with props)
    cfe/trunk/test/Modules/subframeworks.m
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
    cfe/trunk/lib/Lex/ModuleMap.cpp
    cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/module.map

Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=145941&r1=145940&r2=145941&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Tue Dec  6 11:16:41 2011
@@ -395,8 +395,6 @@
   "%select{|umbrella }0header '%1' not found">;
 def err_mmap_umbrella_header_conflict : Error<
   "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">;
 def err_mmap_export_module_id : Error<

Modified: cfe/trunk/lib/Lex/ModuleMap.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ModuleMap.cpp?rev=145941&r1=145940&r2=145941&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/ModuleMap.cpp (original)
+++ cfe/trunk/lib/Lex/ModuleMap.cpp Tue Dec  6 11:16:41 2011
@@ -251,6 +251,8 @@
   Result->InferSubmodules = true;
   Result->InferExportWildcard = true;
   
+  // FIXME: Look for subframeworks.
+  
   Modules[ModuleName] = Result;
   return Result;
 }
@@ -559,19 +561,21 @@
   assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
          Tok.is(MMToken::FrameworkKeyword));
 
-  // Parse 'framework' or 'explicit' keyword, if present.
-  bool Framework = false;
+  // Parse 'explicit' or 'framework' keyword, if present.
   bool Explicit = false;
+  bool Framework = false;
 
-  if (Tok.is(MMToken::FrameworkKeyword)) {
-    consumeToken();
-    Framework = true;
-  } 
   // Parse 'explicit' keyword, if present.
-  else if (Tok.is(MMToken::ExplicitKeyword)) {
+  if (Tok.is(MMToken::ExplicitKeyword)) {
     consumeToken();
     Explicit = true;
   }
+
+  // Parse 'framework' keyword, if present.
+  if (Tok.is(MMToken::FrameworkKeyword)) {
+    consumeToken();
+    Framework = true;
+  } 
   
   // Parse 'module' keyword.
   if (!Tok.is(MMToken::ModuleKeyword)) {
@@ -640,6 +644,7 @@
       break;
         
     case MMToken::ExplicitKeyword:
+    case MMToken::FrameworkKeyword:
     case MMToken::ModuleKeyword:
       parseModuleDecl();
       break;
@@ -674,7 +679,27 @@
   // We're done parsing this module. Pop back to our parent scope.
   ActiveModule = ActiveModule->Parent;
 }
- 
+
+/// \brief Append to \p Paths the set of paths needed to get to the 
+/// subframework in which the given module lives.
+void appendSubframeworkPaths(Module *Mod, llvm::SmallVectorImpl<char> &Path) {
+  // Collect the framework names from the given module to the top-level module.
+  llvm::SmallVector<StringRef, 2> Paths;
+  for (; Mod; Mod = Mod->Parent) {
+    if (Mod->IsFramework)
+      Paths.push_back(Mod->Name);
+  }
+  
+  if (Paths.empty())
+    return;
+  
+  // Add Frameworks/Name.framework for each subframework.
+  for (unsigned I = Paths.size() - 1; I != 0; --I) {
+    llvm::sys::path::append(Path, "Frameworks");
+    llvm::sys::path::append(Path, Paths[I-1] + ".framework");
+  }
+}
+
 /// \brief Parse an umbrella header declaration.
 ///
 ///   umbrella-declaration:
@@ -702,14 +727,6 @@
     return;
   }
   
-  // Only top-level modules can have umbrella headers.
-  if (ActiveModule->Parent) {
-    Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_header_submodule)
-      << ActiveModule->getFullModuleName();
-    HadError = true;
-    return;
-  }
-  
   // Look for this file.
   llvm::SmallString<128> PathName;
   const FileEntry *File = 0;
@@ -721,7 +738,10 @@
     // Search for the header file within the search directory.
     PathName += Directory->getName();
     unsigned PathLength = PathName.size();
+    
     if (ActiveModule->isPartOfFramework()) {
+      appendSubframeworkPaths(ActiveModule, PathName);
+      
       // Check whether this file is in the public headers.
       llvm::sys::path::append(PathName, "Headers");
       llvm::sys::path::append(PathName, FileName);
@@ -734,8 +754,6 @@
         llvm::sys::path::append(PathName, FileName);
         File = SourceMgr.getFileManager().getFile(PathName);
       }
-      
-      // FIXME: Deal with subframeworks.
     } else {
       // Lookup for normal headers.
       llvm::sys::path::append(PathName, FileName);
@@ -797,8 +815,10 @@
     // FIXME: Change this search to also look for private headers!
     PathName += Directory->getName();
     
-    if (ActiveModule->isPartOfFramework())
+    if (ActiveModule->isPartOfFramework()) {
+      appendSubframeworkPaths(ActiveModule, PathName);
       llvm::sys::path::append(PathName, "Headers");
+    }
   }
   
   llvm::sys::path::append(PathName, FileName);

Added: cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/Other.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/Other.h?rev=145941&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/Other.h (added)
+++ cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/Other.h Tue Dec  6 11:16:41 2011
@@ -0,0 +1 @@
+double *sub_framework_other;

Propchange: cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/Other.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/Other.h
------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/Other.h
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/SubFramework.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/SubFramework.h?rev=145941&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/SubFramework.h (added)
+++ cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/SubFramework.h Tue Dec  6 11:16:41 2011
@@ -0,0 +1,2 @@
+#include "SubFramework/Other.h"
+float *sub_framework;

Propchange: cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/SubFramework.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/SubFramework.h
------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/SubFramework.h
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/module.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/module.map?rev=145941&r1=145940&r2=145941&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/module.map (original)
+++ cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/module.map Tue Dec  6 11:16:41 2011
@@ -4,4 +4,7 @@
   module * {
     export *
   }
+  explicit framework module SubFramework {
+    umbrella "SubFramework.h"
+  }
 }

Added: cfe/trunk/test/Modules/subframeworks.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/subframeworks.m?rev=145941&view=auto
==============================================================================
--- cfe/trunk/test/Modules/subframeworks.m (added)
+++ cfe/trunk/test/Modules/subframeworks.m Tue Dec  6 11:16:41 2011
@@ -0,0 +1,16 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -Wauto-import -fmodule-cache-path %t -fauto-module-import -F %S/Inputs %s -verify
+
+__import_module__ DependsOnModule;
+
+void testSubFramework() {
+  float *sf1 = sub_framework; // expected-error{{use of undeclared identifier 'sub_framework'}}
+}
+
+__import_module__ DependsOnModule.SubFramework;
+
+void testSubFrameworkAgain() {
+  float *sf2 = sub_framework;
+  double *sfo1 = sub_framework_other;
+}
+





More information about the cfe-commits mailing list