[cfe-commits] r144859 - in /cfe/trunk: include/clang/Basic/DiagnosticLexKinds.td include/clang/Lex/ModuleMap.h lib/Lex/ModuleMap.cpp test/Modules/Inputs/module.map test/Modules/Inputs/normal-module-map/Umbrella/Umbrella.h test/Modules/normal-module-map.cpp

Douglas Gregor dgregor at apple.com
Wed Nov 16 15:02:25 PST 2011


Author: dgregor
Date: Wed Nov 16 17:02:25 2011
New Revision: 144859

URL: http://llvm.org/viewvc/llvm-project?rev=144859&view=rev
Log:
A module with an umbrella header assumes that all of the headers in
the umbrella header's directory and its subdirectories are part of the
module (that's why it's an umbrella). Make sure that these headers are
considered to be part of the module for lookup purposes.


Modified:
    cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
    cfe/trunk/include/clang/Lex/ModuleMap.h
    cfe/trunk/lib/Lex/ModuleMap.cpp
    cfe/trunk/test/Modules/Inputs/module.map
    cfe/trunk/test/Modules/Inputs/normal-module-map/Umbrella/Umbrella.h
    cfe/trunk/test/Modules/normal-module-map.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=144859&r1=144858&r2=144859&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Wed Nov 16 17:02:25 2011
@@ -397,5 +397,7 @@
   "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">;
+
 }

Modified: cfe/trunk/include/clang/Lex/ModuleMap.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/ModuleMap.h?rev=144859&r1=144858&r2=144859&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/ModuleMap.h (original)
+++ cfe/trunk/include/clang/Lex/ModuleMap.h Wed Nov 16 17:02:25 2011
@@ -27,6 +27,7 @@
 
 namespace clang {
   
+class DirectoryEntry;
 class FileEntry;
 class FileManager;
 class DiagnosticConsumer;
@@ -96,6 +97,14 @@
   /// that header.
   llvm::DenseMap<const FileEntry *, Module *> Headers;
   
+  /// \brief Mapping from directories with umbrella headers to the module
+  /// that is generated from the umbrella header.
+  ///
+  /// This mapping is used to map headers that haven't explicitly been named
+  /// in the module map over to the module that includes them via its umbrella
+  /// header.
+  llvm::DenseMap<const DirectoryEntry *, Module *> UmbrellaDirs;
+  
   friend class ModuleMapParser;
   
 public:

Modified: cfe/trunk/lib/Lex/ModuleMap.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ModuleMap.cpp?rev=144859&r1=144858&r2=144859&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/ModuleMap.cpp (original)
+++ cfe/trunk/lib/Lex/ModuleMap.cpp Wed Nov 16 17:02:25 2011
@@ -81,6 +81,41 @@
   if (Known != Headers.end())
     return Known->second;
   
+  const DirectoryEntry *Dir = File->getDir();
+  llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
+    = UmbrellaDirs.find(Dir);
+  if (KnownDir != UmbrellaDirs.end())
+    return KnownDir->second;
+
+  // Walk up the directory hierarchy looking for umbrella headers.
+  llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs;
+  StringRef DirName = Dir->getName();
+  do {
+    // Retrieve our parent path.
+    DirName = llvm::sys::path::parent_path(DirName);
+    if (DirName.empty())
+      break;
+    
+    // Resolve the parent path to a directory entry.
+    Dir = SourceMgr->getFileManager().getDirectory(DirName);
+    if (!Dir)
+      break;
+    
+    KnownDir = UmbrellaDirs.find(Dir);
+    if (KnownDir != UmbrellaDirs.end()) {
+      Module *Result = KnownDir->second;
+      
+      // Record each of the directories we stepped through as being part of
+      // the module we found, since the umbrella header covers them all.
+      for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
+        UmbrellaDirs[SkippedDirs[I]] = Result;
+      
+      return Result;
+    }
+    
+    SkippedDirs.push_back(Dir);
+  } while (true);
+  
   return 0;
 }
 
@@ -493,10 +528,15 @@
       Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
         << FileName << OwningModule->getFullModuleName();
       HadError = true;
+    } else if ((OwningModule = Map.UmbrellaDirs[Directory])) {
+      Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
+        << OwningModule->getFullModuleName();
+      HadError = true;
     } else {
       // Record this umbrella header.
       ActiveModule->UmbrellaHeader = File;
       Map.Headers[File] = ActiveModule;
+      Map.UmbrellaDirs[Directory] = ActiveModule;
     }
   } else {
     Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)

Modified: cfe/trunk/test/Modules/Inputs/module.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/module.map?rev=144859&r1=144858&r2=144859&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/module.map (original)
+++ cfe/trunk/test/Modules/Inputs/module.map Wed Nov 16 17:02:25 2011
@@ -1,19 +1,19 @@
-module diamond_top { umbrella "diamond_top.h" }
-module diamond_left { umbrella "diamond_left.h" }
-module diamond_right { umbrella "diamond_right.h" }
-module diamond_bottom { umbrella "diamond_bottom.h" }
-module irgen { umbrella "irgen.h" }
-module lookup_left_objc { umbrella "lookup_left.h" }
-module lookup_right_objc { umbrella "lookup_right.h" }
-module lookup_left_cxx { umbrella "lookup_left.hpp" }
-module lookup_right_cxx { umbrella "lookup_right.hpp" }
-module module_private_left { umbrella "module_private_left.h" }
-module module_private_right { umbrella "module_private_right.h" }
-module macros { umbrella "macros.h" }
-module category_top { umbrella "category_top.h" }
-module category_left { umbrella "category_left.h" }
-module category_right { umbrella "category_right.h" }
-module category_bottom { umbrella "category_bottom.h" }
-module redeclarations_left { umbrella "redeclarations_left.h" }
-module redeclarations_right { umbrella "redeclarations_right.h" }
-module load_failure { umbrella "load_failure.h" }
+module diamond_top { header "diamond_top.h" }
+module diamond_left { header "diamond_left.h" }
+module diamond_right { header "diamond_right.h" }
+module diamond_bottom { header "diamond_bottom.h" }
+module irgen { header "irgen.h" }
+module lookup_left_objc { header "lookup_left.h" }
+module lookup_right_objc { header "lookup_right.h" }
+module lookup_left_cxx { header "lookup_left.hpp" }
+module lookup_right_cxx { header "lookup_right.hpp" }
+module module_private_left { header "module_private_left.h" }
+module module_private_right { header "module_private_right.h" }
+module macros { header "macros.h" }
+module category_top { header "category_top.h" }
+module category_left { header "category_left.h" }
+module category_right { header "category_right.h" }
+module category_bottom { header "category_bottom.h" }
+module redeclarations_left { header "redeclarations_left.h" }
+module redeclarations_right { header "redeclarations_right.h" }
+module load_failure { header "load_failure.h" }

Modified: cfe/trunk/test/Modules/Inputs/normal-module-map/Umbrella/Umbrella.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/normal-module-map/Umbrella/Umbrella.h?rev=144859&r1=144858&r2=144859&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/normal-module-map/Umbrella/Umbrella.h (original)
+++ cfe/trunk/test/Modules/Inputs/normal-module-map/Umbrella/Umbrella.h Wed Nov 16 17:02:25 2011
@@ -1 +1,4 @@
 int umbrella;
+
+#include "umbrella_sub.h"
+

Modified: cfe/trunk/test/Modules/normal-module-map.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/normal-module-map.cpp?rev=144859&r1=144858&r2=144859&view=diff
==============================================================================
--- cfe/trunk/test/Modules/normal-module-map.cpp (original)
+++ cfe/trunk/test/Modules/normal-module-map.cpp Wed Nov 16 17:02:25 2011
@@ -4,10 +4,10 @@
 // RUN: %clang_cc1 -x objective-c -fmodule-cache-path %t -fmodule-name=libB -emit-module-from-map %S/Inputs/normal-module-map/module.map
 // RUN: %clang_cc1 -x objective-c -fmodule-cache-path %t -fmodule-name=libNested -emit-module-from-map %S/Inputs/normal-module-map/nested/module.map
 // RUN: %clang_cc1 -x objective-c -fmodule-cache-path %t -fauto-module-import -I %S/Inputs/normal-module-map %s -verify
-#include "Umbrella/Umbrella.h"
+#include "Umbrella/umbrella_sub.h"
 
 int getUmbrella() { 
-  return umbrella; 
+  return umbrella + umbrella_sub; 
 }
 
 __import_module__ Umbrella2;





More information about the cfe-commits mailing list