[cfe-commits] r144921 - in /cfe/trunk: include/clang/Basic/DiagnosticLexKinds.td include/clang/Lex/ModuleMap.h lib/Lex/ModuleMap.cpp test/Modules/Inputs/DependsOnModule.framework/Headers/other.h test/Modules/Inputs/DependsOnModule.framework/module.map

Douglas Gregor dgregor at apple.com
Thu Nov 17 14:09:43 PST 2011


Author: dgregor
Date: Thu Nov 17 16:09:43 2011
New Revision: 144921

URL: http://llvm.org/viewvc/llvm-project?rev=144921&view=rev
Log:
Add the notion of "framework" modules to module maps. Framework
modules (obviously) describe frameworks, and understand the header
layout of frameworks.

Added:
    cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/Headers/other.h
    cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/module.map
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
    cfe/trunk/include/clang/Lex/ModuleMap.h
    cfe/trunk/lib/Lex/ModuleMap.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=144921&r1=144920&r2=144921&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Thu Nov 17 16:09:43 2011
@@ -392,7 +392,7 @@
 def err_mmap_header_conflict : Error<
   "header '%0' is already part of module '%1'">;
 def err_mmap_header_not_found : Error<
-  "%select{|umbrella }0 header '%1' not found">;
+  "%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<

Modified: cfe/trunk/include/clang/Lex/ModuleMap.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/ModuleMap.h?rev=144921&r1=144920&r2=144921&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/ModuleMap.h (original)
+++ cfe/trunk/include/clang/Lex/ModuleMap.h Thu Nov 17 16:09:43 2011
@@ -59,19 +59,23 @@
     /// \brief The headers that are part of this module.
     llvm::SmallVector<const FileEntry *, 2> Headers;
     
+    /// \brief Whether this is a framework module.
+    bool IsFramework;
+    
     /// \brief Whether this is an explicit submodule.
     bool IsExplicit;
     
     /// \brief Construct a top-level module.
-    explicit Module(StringRef Name, SourceLocation DefinitionLoc)
+    explicit Module(StringRef Name, SourceLocation DefinitionLoc,
+                    bool IsFramework)
       : Name(Name), DefinitionLoc(DefinitionLoc), Parent(0), UmbrellaHeader(0),
-        IsExplicit(false) { }
+        IsFramework(IsFramework), IsExplicit(false) { }
     
     /// \brief Construct  a new module or submodule.
     Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, 
-           bool IsExplicit)
+           bool IsFramework, bool IsExplicit)
       : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), 
-        UmbrellaHeader(0), IsExplicit(IsExplicit) {
+        UmbrellaHeader(0), IsFramework(IsFramework), IsExplicit(IsExplicit) {
     }
      
     ~Module();
@@ -79,6 +83,18 @@
     /// \brief Determine whether this module is a submodule.
     bool isSubModule() const { return Parent != 0; }
     
+    /// \brief Determine whether this module is a part of a framework,
+    /// either because it is a framework module or because it is a submodule
+    /// of a framework module.
+    bool isPartOfFramework() const {
+      for (const Module *Mod = this; Mod; Mod = Mod->Parent) 
+        if (Mod->IsFramework)
+          return true;
+      
+      return false;
+    }
+    
+    
     /// \brief Retrieve the full name of this module, including the path from
     /// its top-level module.
     std::string getFullModuleName() const;

Modified: cfe/trunk/lib/Lex/ModuleMap.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ModuleMap.cpp?rev=144921&r1=144920&r2=144921&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/ModuleMap.cpp (original)
+++ cfe/trunk/lib/Lex/ModuleMap.cpp Thu Nov 17 16:09:43 2011
@@ -162,7 +162,8 @@
   if (!UmbrellaHeader)
     return 0;
   
-  Module *Result = new Module(ModuleName, SourceLocation());
+  Module *Result = new Module(ModuleName, SourceLocation(), 
+                              /*IsFramework=*/true);
   Result->UmbrellaHeader = UmbrellaHeader;
   Headers[UmbrellaHeader] = Result;
   UmbrellaDirs[FrameworkDir] = Result;
@@ -177,6 +178,8 @@
 static void dumpModule(llvm::raw_ostream &OS, ModuleMap::Module *M, 
                        unsigned Indent) {
   indent(OS, Indent);
+  if (M->IsFramework)
+    OS << "framework ";
   if (M->IsExplicit)
     OS << "explicit ";
   OS << M->Name << " {\n";
@@ -230,6 +233,7 @@
       HeaderKeyword,
       Identifier,
       ExplicitKeyword,
+      FrameworkKeyword,
       ModuleKeyword,
       UmbrellaKeyword,
       StringLiteral,
@@ -333,6 +337,7 @@
     Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
                  .Case("header", MMToken::HeaderKeyword)
                  .Case("explicit", MMToken::ExplicitKeyword)
+                 .Case("framework", MMToken::FrameworkKeyword)
                  .Case("module", MMToken::ModuleKeyword)
                  .Case("umbrella", MMToken::UmbrellaKeyword)
                  .Default(MMToken::Identifier);
@@ -416,18 +421,26 @@
 /// \brief Parse a module declaration.
 ///
 ///   module-declaration:
-///     'module' identifier { module-member* }
+///     'framework'[opt] 'module' identifier { module-member* }
 ///
 ///   module-member:
 ///     umbrella-declaration
 ///     header-declaration
 ///     'explicit'[opt] module-declaration
 void ModuleMapParser::parseModuleDecl() {
-  assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword));
-  
-  // Parse 'explicit' keyword, if present.
+  assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
+         Tok.is(MMToken::FrameworkKeyword));
+
+  // Parse 'framework' or 'explicit' keyword, if present.
+  bool Framework = false;
   bool Explicit = false;
-  if (Tok.is(MMToken::ExplicitKeyword)) {
+
+  if (Tok.is(MMToken::FrameworkKeyword)) {
+    consumeToken();
+    Framework = true;
+  } 
+  // Parse 'explicit' keyword, if present.
+  else if (Tok.is(MMToken::ExplicitKeyword)) {
     consumeToken();
     Explicit = true;
   }
@@ -481,7 +494,8 @@
   }
 
   // Start defining this module.
-  ActiveModule = new Module(ModuleName, ModuleNameLoc, ActiveModule, Explicit);
+  ActiveModule = new Module(ModuleName, ModuleNameLoc, ActiveModule, Framework,
+                            Explicit);
   ModuleSpace[ModuleName] = ActiveModule;
   
   bool Done = false;
@@ -562,11 +576,32 @@
   // Look for this file.
   llvm::SmallString<128> PathName;
   PathName += Directory->getName();
-  llvm::sys::path::append(PathName, FileName);
+  unsigned PathLength = PathName.size();
+  const FileEntry *File = 0;
+  if (ActiveModule->isPartOfFramework()) {
+    // Check whether this file is in the public headers.
+    llvm::sys::path::append(PathName, "Headers");
+    llvm::sys::path::append(PathName, FileName);
+    File = SourceMgr.getFileManager().getFile(PathName);
+
+    if (!File) {
+      // Check whether this file is in the private headers.
+      PathName.resize(PathLength);
+      llvm::sys::path::append(PathName, "PrivateHeaders");
+      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);
+    File = SourceMgr.getFileManager().getFile(PathName);
+  }
   
   // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
   // Come up with a lazy way to do this.
-  if (const FileEntry *File = SourceMgr.getFileManager().getFile(PathName)) {
+  if (File) {
     if (const Module *OwningModule = Map.Headers[File]) {
       Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
         << FileName << OwningModule->getFullModuleName();
@@ -609,6 +644,10 @@
   // Look for this file.
   llvm::SmallString<128> PathName;
   PathName += Directory->getName();
+  
+  if (ActiveModule->isPartOfFramework())
+    llvm::sys::path::append(PathName, "Headers");
+
   llvm::sys::path::append(PathName, FileName);
   
   // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
@@ -641,6 +680,7 @@
       return HadError;
       
     case MMToken::ModuleKeyword:
+    case MMToken::FrameworkKeyword:
       parseModuleDecl();
       break;
       

Added: cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/Headers/other.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/Headers/other.h?rev=144921&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/Headers/other.h (added)
+++ cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/Headers/other.h Thu Nov 17 16:09:43 2011
@@ -0,0 +1 @@
+int depends_on_module_other;

Added: 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=144921&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/module.map (added)
+++ cfe/trunk/test/Modules/Inputs/DependsOnModule.framework/module.map Thu Nov 17 16:09:43 2011
@@ -0,0 +1,4 @@
+framework module DependsOnModule {
+  umbrella "DependsOnModule.h"
+  header "other.h"
+}





More information about the cfe-commits mailing list