Back out my heinous hack that tricked the module generation mechanism
into using non-absolute system includes (<foo>)...

... and introduce another hack that is simultaneously more heineous
and more effective. We whitelist Clang-supplied headers that augment
or override system headers (such as float.h, stdarg.h, and
tgmath.h). For these headers, Clang does not provide a module
mapping. Instead, a system-supplied module map can refer to these
headers in a system module, and Clang will look both in its own
include directory and wherever the system-supplied module map
suggests, then adds either or both headers. The end result is that
Clang-supplied headers get merged into the system-supplied module for
the C standard library.

As a drive-by, fix up a few dependencies in the _Builtin_instrinsics
module.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149611 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Basic/Module.cpp b/lib/Basic/Module.cpp
index c5838fb..6348840 100644
--- a/lib/Basic/Module.cpp
+++ b/lib/Basic/Module.cpp
@@ -32,6 +32,8 @@
   if (Parent) {
     if (!Parent->isAvailable())
       IsAvailable = false;
+    if (Parent->IsSystem)
+      IsSystem = true;
     
     Parent->SubModuleIndex[Name] = Parent->SubModules.size();
     Parent->SubModules.push_back(this);
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp
index edadf37..c030232 100644
--- a/lib/Frontend/FrontendActions.cpp
+++ b/lib/Frontend/FrontendActions.cpp
@@ -126,32 +126,6 @@
                           Sysroot, OS);
 }
 
-/// \brief Add an appropriate #include/#import for the given header within
-/// the current module context.
-static void addHeaderInclude(StringRef Header, 
-                             bool IsBuiltinModule,
-                             const LangOptions &LangOpts,
-                             llvm::SmallString<256> &Includes) {
-  if (IsBuiltinModule) {
-    // Our own builtin headers play some evil tricks that depend both on
-    // knowing that our headers will be found first and on include_next. To
-    // Make sure these include_next tricks work, we include with <> and
-    // just the filename itself rather than using an absolutely path.
-    // FIXME: Is there some sensible way to generalize this?
-    Includes += "#include <";
-    Includes += llvm::sys::path::filename(Header);
-    Includes += ">\n";
-    return;
-  }
-  
-  if (LangOpts.ObjC1)
-    Includes += "#import \"";
-  else
-    Includes += "#include \"";  
-  Includes += Header;
-  Includes += "\"\n";
-}
-
 /// \brief Collect the set of header includes needed to construct the given 
 /// module.
 ///
@@ -163,21 +137,31 @@
                                         FileManager &FileMgr,
                                         ModuleMap &ModMap,
                                         clang::Module *Module,
-                                        bool IsBuiltinModule,
                                         llvm::SmallString<256> &Includes) {
   // Don't collect any headers for unavailable modules.
   if (!Module->isAvailable())
     return;
 
   // Add includes for each of these headers.
-  for (unsigned I = 0, N = Module->Headers.size(); I != N; ++I)
-    addHeaderInclude(Module->Headers[I]->getName(), IsBuiltinModule, LangOpts, 
-                     Includes);
+  for (unsigned I = 0, N = Module->Headers.size(); I != N; ++I) {
+    if (LangOpts.ObjC1)
+      Includes += "#import \"";
+    else
+      Includes += "#include \"";
+    Includes += Module->Headers[I]->getName();
+    Includes += "\"\n";
+  }
 
   if (const FileEntry *UmbrellaHeader = Module->getUmbrellaHeader()) {
-    if (Module->Parent)
-      addHeaderInclude(UmbrellaHeader->getName(), IsBuiltinModule, LangOpts, 
-                       Includes);
+    if (Module->Parent) {
+      // Include the umbrella header for submodules.
+      if (LangOpts.ObjC1)
+        Includes += "#import \"";
+      else
+        Includes += "#include \"";
+      Includes += UmbrellaHeader->getName();
+      Includes += "\"\n";
+    }
   } else if (const DirectoryEntry *UmbrellaDir = Module->getUmbrellaDir()) {
     // Add all of the headers we find in this subdirectory.
     llvm::error_code EC;
@@ -199,8 +183,13 @@
         if (ModMap.isHeaderInUnavailableModule(Header))
           continue;
       
-      // Include this header.
-      addHeaderInclude(Dir->path(), IsBuiltinModule, LangOpts, Includes);
+      // Include this header umbrella header for submodules.
+      if (LangOpts.ObjC1)
+        Includes += "#import \"";
+      else
+        Includes += "#include \"";
+      Includes += Dir->path();
+      Includes += "\"\n";
     }
   }
   
@@ -208,8 +197,7 @@
   for (clang::Module::submodule_iterator Sub = Module->submodule_begin(),
                                       SubEnd = Module->submodule_end();
        Sub != SubEnd; ++Sub)
-    collectModuleHeaderIncludes(LangOpts, FileMgr, ModMap, *Sub, 
-                                IsBuiltinModule, Includes);
+    collectModuleHeaderIncludes(LangOpts, FileMgr, ModMap, *Sub, Includes);
 }
 
 bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI, 
@@ -261,11 +249,10 @@
   const FileEntry *UmbrellaHeader = Module->getUmbrellaHeader();
   
   // Collect the set of #includes we need to build the module.
-  bool IsBuiltinModule = StringRef(Module->Name).startswith("_Builtin_");
   llvm::SmallString<256> HeaderContents;
   collectModuleHeaderIncludes(CI.getLangOpts(), CI.getFileManager(),
     CI.getPreprocessor().getHeaderSearchInfo().getModuleMap(),
-    Module, IsBuiltinModule, HeaderContents);
+    Module, HeaderContents);
   if (UmbrellaHeader && HeaderContents.empty()) {
     // Simple case: we have an umbrella header and there are no additional
     // includes, we can just parse the umbrella header directly.
diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp
index ee75e69..9faa126 100644
--- a/lib/Frontend/InitHeaderSearch.cpp
+++ b/lib/Frontend/InitHeaderSearch.cpp
@@ -666,5 +666,13 @@
 
   Init.AddDefaultIncludePaths(Lang, Triple, HSOpts);
 
+  if (HSOpts.UseBuiltinIncludes) {
+    // Set up the builtin include directory in the module map.
+    llvm::sys::Path P(HSOpts.ResourceDir);
+    P.appendComponent("include");
+    if (const DirectoryEntry *Dir = HS.getFileMgr().getDirectory(P.str()))
+      HS.getModuleMap().setBuiltinIncludeDir(Dir);
+  }
+
   Init.Realize(Lang);
 }
diff --git a/lib/Headers/module.map b/lib/Headers/module.map
index e321ca3..418ba50 100644
--- a/lib/Headers/module.map
+++ b/lib/Headers/module.map
@@ -1,42 +1,3 @@
-module _Builtin_stdlib [system] {
-  explicit module float_constants {
-    header "float.h"
-  }
-
-  explicit module iso646 {
-    header "iso646.h"
-  }
-
-  explicit module limits {
-    header "limits.h"
-  }
-
-  explicit module stdalign {
-    header "stdalign.h"
-  }
-
-  explicit module stdarg {
-    header "stdarg.h"
-  }
-
-  explicit module stdbool {
-    header "stdbool.h"
-  }
-
-  explicit module stddef {
-    header "stddef.h"
-  }
-
-  explicit module stdint {
-    header "stdint.h"
-  }
-
-  explicit module varargs {
-    requires unavailable
-    header "varargs.h"
-  }
-}
-
 module _Builtin_intrinsics [system] {
   explicit module altivec {
     requires altivec
@@ -45,10 +6,16 @@
 
   explicit module intel {
     requires x86
+    export *
 
     header "immintrin.h"
     header "x86intrin.h"
 
+    explicit module mm_malloc {
+      header "mm_malloc.h"
+      export * // note: for <stdlib.h> dependency
+    }
+
     explicit module cpuid {
       header "cpuid.h"
     }
@@ -61,6 +28,7 @@
     explicit module sse {
       requires sse
       export mmx
+      export * // note: for hackish <emmintrin.h> dependency
       header "xmmintrin.h"
     }
 
@@ -136,12 +104,5 @@
       requires mm3dnow
       header "mm3dnow.h"
     }
-
-    explicit module mm_malloc {
-      header "mm_malloc.h"
-    }
   }
-
-  // FIXME: tgmath.h
-  // FIXME: unwind.h
 }
diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp
index 3583b03..c1c5066 100644
--- a/lib/Lex/ModuleMap.cpp
+++ b/lib/Lex/ModuleMap.cpp
@@ -71,7 +71,7 @@
 
 ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
                      const LangOptions &LangOpts, const TargetInfo *Target)
-  : LangOpts(LangOpts), Target(Target)
+  : LangOpts(LangOpts), Target(Target), BuiltinIncludeDir(0)
 {
   llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
   Diags = llvm::IntrusiveRefCntPtr<DiagnosticsEngine>(
@@ -499,7 +499,10 @@
     
     /// \brief The directory that this module map resides in.
     const DirectoryEntry *Directory;
-    
+
+    /// \brief The directory containing Clang-supplied headers.
+    const DirectoryEntry *BuiltinIncludeDir;
+
     /// \brief Whether an error occurred.
     bool HadError;
     
@@ -540,9 +543,11 @@
     explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 
                              DiagnosticsEngine &Diags,
                              ModuleMap &Map,
-                             const DirectoryEntry *Directory)
+                             const DirectoryEntry *Directory,
+                             const DirectoryEntry *BuiltinIncludeDir)
       : L(L), SourceMgr(SourceMgr), Diags(Diags), Map(Map), 
-        Directory(Directory), HadError(false), ActiveModule(0)
+        Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir), 
+        HadError(false), ActiveModule(0)
     {
       TargetOptions TargetOpts;
       TargetOpts.Triple = llvm::sys::getDefaultTargetTriple();
@@ -1028,6 +1033,24 @@
   }
 }
 
+/// \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:
@@ -1058,6 +1081,7 @@
 
   // Look for this file.
   const FileEntry *File = 0;
+  const FileEntry *BuiltinFile = 0;
   llvm::SmallString<128> PathName;
   if (llvm::sys::path::is_absolute(FileName)) {
     PathName = FileName;
@@ -1090,6 +1114,24 @@
       // Lookup for normal headers.
       llvm::sys::path::append(PathName, FileName);
       File = SourceMgr.getFileManager().getFile(PathName);
+      
+      // If this is a system module with a top-level header, this header
+      // may have a counterpart (or replacement) in the set of headers
+      // supplied by Clang. Find that builtin header.
+      if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir &&
+          BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) {
+        llvm::SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
+        llvm::sys::path::append(BuiltinPathName, FileName);
+        BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
+        
+        // If Clang supplies this header but the underlying system does not,
+        // just silently swap in our builtin version. Otherwise, we'll end
+        // up adding both (later).
+        if (!File && BuiltinFile) {
+          File = BuiltinFile;
+          BuiltinFile = 0;
+        }
+      }
     }
   }
   
@@ -1113,6 +1155,10 @@
     } else {
       // Record this header.
       Map.addHeader(ActiveModule, File);
+      
+      // If there is a builtin counterpart to this file, add it now.
+      if (BuiltinFile)
+        Map.addHeader(ActiveModule, BuiltinFile);
     }
   } else {
     Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
@@ -1375,7 +1421,8 @@
   // Parse this module map file.
   Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
   Diags->getClient()->BeginSourceFile(MMapLangOpts);
-  ModuleMapParser Parser(L, *SourceMgr, *Diags, *this, File->getDir());
+  ModuleMapParser Parser(L, *SourceMgr, *Diags, *this, File->getDir(),
+                         BuiltinIncludeDir);
   bool Result = Parser.parseModuleMapFile();
   Diags->getClient()->EndSourceFile();