r180934 - When looking for the module associated with one of our magical builtin headers, speculatively load module maps.

Douglas Gregor dgregor at apple.com
Thu May 2 10:58:30 PDT 2013


Author: dgregor
Date: Thu May  2 12:58:30 2013
New Revision: 180934

URL: http://llvm.org/viewvc/llvm-project?rev=180934&view=rev
Log:
When looking for the module associated with one of our magical builtin headers, speculatively load module maps.

The "magical" builtin headers are the headers we provide as part of
the C standard library, which typically comes from /usr/include. We
essentially merge our headers into that location (due to cyclic
dependencies). This change makes sure that, when header search finds
one of our builtin headers, we figure out which module it actually
lives in. This case is fairly rare; one ends up having to include one
of the few built-in C headers we provide before including anything
from /usr/include to trigger it. Fixes <rdar://problem/13787184>.

Added:
    cfe/trunk/test/Modules/Inputs/System/usr/include/dbl_max.h
    cfe/trunk/test/Modules/Inputs/System/usr/include/uses_other_constants.h
Modified:
    cfe/trunk/lib/Lex/ModuleMap.cpp
    cfe/trunk/test/Modules/Inputs/System/usr/include/module.map
    cfe/trunk/test/Modules/cstd.m

Modified: cfe/trunk/lib/Lex/ModuleMap.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ModuleMap.cpp?rev=180934&r1=180933&r2=180934&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/ModuleMap.cpp (original)
+++ cfe/trunk/lib/Lex/ModuleMap.cpp Thu May  2 12:58:30 2013
@@ -149,6 +149,24 @@ static StringRef sanitizeFilenameAsIdent
   return Name;
 }
 
+/// \brief Determine whether the given file name is the name of a builtin
+/// header, supplied by Clang to replace, override, or augment existing system
+/// headers.
+static bool isBuiltinHeader(StringRef FileName) {
+  return llvm::StringSwitch<bool>(FileName)
+           .Case("float.h", true)
+           .Case("iso646.h", true)
+           .Case("limits.h", true)
+           .Case("stdalign.h", true)
+           .Case("stdarg.h", true)
+           .Case("stdbool.h", true)
+           .Case("stddef.h", true)
+           .Case("stdint.h", true)
+           .Case("tgmath.h", true)
+           .Case("unwind.h", true)
+           .Default(false);
+}
+
 Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
   HeadersMap::iterator Known = Headers.find(File);
   if (Known != Headers.end()) {
@@ -158,6 +176,25 @@ Module *ModuleMap::findModuleForHeader(c
 
     return Known->second.getModule();
   }
+
+  // If we've found a builtin header within Clang's builtin include directory,
+  // load all of the module maps to see if it will get associated with a
+  // specific module (e.g., in /usr/include).
+  if (File->getDir() == BuiltinIncludeDir &&
+      isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
+    SmallVector<Module *, 4> AllModules;
+    HeaderInfo.collectAllModules(AllModules);
+
+    // Check again.
+    Known = Headers.find(File);
+    if (Known != Headers.end()) {
+      // If a header is not available, don't report that it maps to anything.
+      if (!Known->second.isAvailable())
+        return 0;
+
+      return Known->second.getModule();
+    }
+  }
   
   const DirectoryEntry *Dir = File->getDir();
   SmallVector<const DirectoryEntry *, 2> SkippedDirs;
@@ -1266,24 +1303,6 @@ static void appendSubframeworkPaths(Modu
   }
 }
 
-/// \brief Determine whether the given file name is the name of a builtin
-/// header, supplied by Clang to replace, override, or augment existing system
-/// headers.
-static bool isBuiltinHeader(StringRef FileName) {
-  return llvm::StringSwitch<bool>(FileName)
-      .Case("float.h", true)
-      .Case("iso646.h", true)
-      .Case("limits.h", true)
-      .Case("stdalign.h", true)
-      .Case("stdarg.h", true)
-      .Case("stdbool.h", true)
-      .Case("stddef.h", true)
-      .Case("stdint.h", true)
-      .Case("tgmath.h", true)
-      .Case("unwind.h", true)
-      .Default(false);
-}
-
 /// \brief Parse a header declaration.
 ///
 ///   header-declaration:

Added: cfe/trunk/test/Modules/Inputs/System/usr/include/dbl_max.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/System/usr/include/dbl_max.h?rev=180934&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/System/usr/include/dbl_max.h (added)
+++ cfe/trunk/test/Modules/Inputs/System/usr/include/dbl_max.h Thu May  2 12:58:30 2013
@@ -0,0 +1 @@
+#define DBL_MAX __DBL_MAX__

Modified: cfe/trunk/test/Modules/Inputs/System/usr/include/module.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/System/usr/include/module.map?rev=180934&r1=180933&r2=180934&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/System/usr/include/module.map (original)
+++ cfe/trunk/test/Modules/Inputs/System/usr/include/module.map Thu May  2 12:58:30 2013
@@ -19,3 +19,14 @@ module cstd [system] {
     header "stdint.h"
   }
 }
+
+module other_constants {
+  explicit module dbl_max {
+    header "dbl_max.h"
+  }
+}
+
+module uses_other_constants {
+  header "uses_other_constants.h"
+  export *
+}

Added: cfe/trunk/test/Modules/Inputs/System/usr/include/uses_other_constants.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/System/usr/include/uses_other_constants.h?rev=180934&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/System/usr/include/uses_other_constants.h (added)
+++ cfe/trunk/test/Modules/Inputs/System/usr/include/uses_other_constants.h Thu May  2 12:58:30 2013
@@ -0,0 +1,3 @@
+ at import other_constants;
+#include <float.h>
+

Modified: cfe/trunk/test/Modules/cstd.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/cstd.m?rev=180934&r1=180933&r2=180934&view=diff
==============================================================================
--- cfe/trunk/test/Modules/cstd.m (original)
+++ cfe/trunk/test/Modules/cstd.m Thu May  2 12:58:30 2013
@@ -1,6 +1,9 @@
 // RUN: rm -rf %t
 // RUN: %clang -fsyntax-only -isystem %S/Inputs/System/usr/include -fmodules -fmodules-cache-path=%t -D__need_wint_t -Werror=implicit-function-declaration %s
 
+ at import uses_other_constants;
+const double other_value = DBL_MAX;
+
 // Supplied by compiler, but referenced from the "/usr/include" module map.
 @import cstd.float_constants;
 
@@ -16,7 +19,7 @@ void test_fprintf(FILE *file) {
 // Supplied by compiler, which forwards to the "/usr/include" version.
 @import cstd.stdint;
 
-my_awesome_nonstandard_integer_type value;
+my_awesome_nonstandard_integer_type value2;
 
 // Supplied by the compiler; that version wins.
 @import cstd.stdbool;
@@ -25,5 +28,3 @@ my_awesome_nonstandard_integer_type valu
 #  error "bool was not defined!"
 #endif
 
-
-





More information about the cfe-commits mailing list