]> granicus.if.org Git - clang/commitdiff
[Modules] Make header inclusion order from umbrella dirs deterministic
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>
Mon, 12 Dec 2016 22:41:20 +0000 (22:41 +0000)
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>
Mon, 12 Dec 2016 22:41:20 +0000 (22:41 +0000)
Sort the headers by name before adding the includes in
collectModuleHeaderIncludes. This makes the include order for building
umbrellas deterministic across different filesystems and also guarantees
that the ASTWriter always dump top headers in the same order.

There's currently no good way to test for this behavior.

rdar://problem/28116411

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@289478 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Frontend/FrontendActions.cpp

index eb91940cbbfc8078ad05eecf314ec8edbe62a144..ef008d1428f9e510936dc1f467a97da41d5d7874 100644 (file)
@@ -233,6 +233,7 @@ collectModuleHeaderIncludes(const LangOptions &LangOpts, FileManager &FileMgr,
     llvm::sys::path::native(UmbrellaDir.Entry->getName(), DirNative);
 
     vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
+    SmallVector<std::pair<std::string, const FileEntry *>, 8> Headers;
     for (vfs::recursive_directory_iterator Dir(FS, DirNative, EC), End;
          Dir != End && !EC; Dir.increment(EC)) {
       // Check whether this entry has an extension typically associated with 
@@ -263,13 +264,20 @@ collectModuleHeaderIncludes(const LangOptions &LangOpts, FileManager &FileMgr,
            ++It)
         llvm::sys::path::append(RelativeHeader, *It);
 
-      // Include this header as part of the umbrella directory.
-      Module->addTopHeader(Header);
-      addHeaderInclude(RelativeHeader, Includes, LangOpts, Module->IsExternC);
+      Headers.push_back(std::make_pair(RelativeHeader.str(), Header));
     }
 
     if (EC)
       return EC;
+
+    // Sort header paths and make the header inclusion order deterministic
+    // across different OSs and filesystems.
+    llvm::array_pod_sort(Headers.begin(), Headers.end());
+    for (auto &H : Headers) {
+      // Include this header as part of the umbrella directory.
+      Module->addTopHeader(H.second);
+      addHeaderInclude(H.first, Includes, LangOpts, Module->IsExternC);
+    }
   }
 
   // Recurse into submodules.