Update Clang for rebase to r212749.

This also fixes a small issue with arm_neon.h not being generated always.

Includes a cherry-pick of:
r213450 - fixes mac-specific header issue
r213126 - removes a default -Bsymbolic on Android

Change-Id: I2a790a0f5d3b2aab11de596fc3a74e7cbc99081d
diff --git a/lib/Basic/VirtualFileSystem.cpp b/lib/Basic/VirtualFileSystem.cpp
index a469c9a..1f2a856 100644
--- a/lib/Basic/VirtualFileSystem.cpp
+++ b/lib/Basic/VirtualFileSystem.cpp
@@ -14,6 +14,8 @@
 #include "llvm/ADT/iterator_range.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Support/Errc.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/YAMLParser.h"
@@ -65,17 +67,15 @@
 
 FileSystem::~FileSystem() {}
 
-error_code FileSystem::getBufferForFile(const llvm::Twine &Name,
-                                        std::unique_ptr<MemoryBuffer> &Result,
-                                        int64_t FileSize,
-                                        bool RequiresNullTerminator,
-                                        bool IsVolatile) {
+std::error_code FileSystem::getBufferForFile(
+    const llvm::Twine &Name, std::unique_ptr<MemoryBuffer> &Result,
+    int64_t FileSize, bool RequiresNullTerminator, bool IsVolatile) {
   std::unique_ptr<File> F;
-  if (error_code EC = openFileForRead(Name, F))
+  if (std::error_code EC = openFileForRead(Name, F))
     return EC;
 
-  error_code EC = F->getBuffer(Name, Result, FileSize, RequiresNullTerminator,
-                               IsVolatile);
+  std::error_code EC =
+      F->getBuffer(Name, Result, FileSize, RequiresNullTerminator, IsVolatile);
   return EC;
 }
 
@@ -96,11 +96,12 @@
 public:
   ~RealFile();
   ErrorOr<Status> status() override;
-  error_code getBuffer(const Twine &Name, std::unique_ptr<MemoryBuffer> &Result,
-                       int64_t FileSize = -1,
-                       bool RequiresNullTerminator = true,
-                       bool IsVolatile = false) override;
-  error_code close() override;
+  std::error_code getBuffer(const Twine &Name,
+                            std::unique_ptr<MemoryBuffer> &Result,
+                            int64_t FileSize = -1,
+                            bool RequiresNullTerminator = true,
+                            bool IsVolatile = false) override;
+  std::error_code close() override;
   void setName(StringRef Name) override;
 };
 } // end anonymous namespace
@@ -110,7 +111,7 @@
   assert(FD != -1 && "cannot stat closed file");
   if (!S.isStatusKnown()) {
     file_status RealStatus;
-    if (error_code EC = sys::fs::status(FD, RealStatus))
+    if (std::error_code EC = sys::fs::status(FD, RealStatus))
       return EC;
     Status NewS(RealStatus);
     NewS.setName(S.getName());
@@ -119,13 +120,19 @@
   return S;
 }
 
-error_code RealFile::getBuffer(const Twine &Name,
-                               std::unique_ptr<MemoryBuffer> &Result,
-                               int64_t FileSize, bool RequiresNullTerminator,
-                               bool IsVolatile) {
+std::error_code RealFile::getBuffer(const Twine &Name,
+                                    std::unique_ptr<MemoryBuffer> &Result,
+                                    int64_t FileSize,
+                                    bool RequiresNullTerminator,
+                                    bool IsVolatile) {
   assert(FD != -1 && "cannot get buffer for closed file");
-  return MemoryBuffer::getOpenFile(FD, Name.str().c_str(), Result, FileSize,
-                                   RequiresNullTerminator, IsVolatile);
+  ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
+      MemoryBuffer::getOpenFile(FD, Name.str().c_str(), FileSize,
+                                RequiresNullTerminator, IsVolatile);
+  if (std::error_code EC = BufferOrErr.getError())
+    return EC;
+  Result = std::move(BufferOrErr.get());
+  return std::error_code();
 }
 
 // FIXME: This is terrible, we need this for ::close.
@@ -138,11 +145,11 @@
 #define S_ISFIFO(x) (0)
 #endif
 #endif
-error_code RealFile::close() {
+std::error_code RealFile::close() {
   if (::close(FD))
-    return error_code(errno, system_category());
+    return std::error_code(errno, std::generic_category());
   FD = -1;
-  return error_code::success();
+  return std::error_code();
 }
 
 void RealFile::setName(StringRef Name) {
@@ -154,28 +161,29 @@
 class RealFileSystem : public FileSystem {
 public:
   ErrorOr<Status> status(const Twine &Path) override;
-  error_code openFileForRead(const Twine &Path,
-                             std::unique_ptr<File> &Result) override;
+  std::error_code openFileForRead(const Twine &Path,
+                                  std::unique_ptr<File> &Result) override;
+  directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override;
 };
 } // end anonymous namespace
 
 ErrorOr<Status> RealFileSystem::status(const Twine &Path) {
   sys::fs::file_status RealStatus;
-  if (error_code EC = sys::fs::status(Path, RealStatus))
+  if (std::error_code EC = sys::fs::status(Path, RealStatus))
     return EC;
   Status Result(RealStatus);
   Result.setName(Path.str());
   return Result;
 }
 
-error_code RealFileSystem::openFileForRead(const Twine &Name,
-                                           std::unique_ptr<File> &Result) {
+std::error_code RealFileSystem::openFileForRead(const Twine &Name,
+                                                std::unique_ptr<File> &Result) {
   int FD;
-  if (error_code EC = sys::fs::openFileForRead(Name, FD))
+  if (std::error_code EC = sys::fs::openFileForRead(Name, FD))
     return EC;
   Result.reset(new RealFile(FD));
   Result->setName(Name.str());
-  return error_code::success();
+  return std::error_code();
 }
 
 IntrusiveRefCntPtr<FileSystem> vfs::getRealFileSystem() {
@@ -183,6 +191,46 @@
   return FS;
 }
 
+namespace {
+class RealFSDirIter : public clang::vfs::detail::DirIterImpl {
+  std::string Path;
+  llvm::sys::fs::directory_iterator Iter;
+public:
+  RealFSDirIter(const Twine &_Path, std::error_code &EC)
+      : Path(_Path.str()), Iter(Path, EC) {
+    if (!EC && Iter != llvm::sys::fs::directory_iterator()) {
+      llvm::sys::fs::file_status S;
+      EC = Iter->status(S);
+      if (!EC) {
+        CurrentEntry = Status(S);
+        CurrentEntry.setName(Iter->path());
+      }
+    }
+  }
+
+  std::error_code increment() override {
+    std::error_code EC;
+    Iter.increment(EC);
+    if (EC) {
+      return EC;
+    } else if (Iter == llvm::sys::fs::directory_iterator()) {
+      CurrentEntry = Status();
+    } else {
+      llvm::sys::fs::file_status S;
+      EC = Iter->status(S);
+      CurrentEntry = Status(S);
+      CurrentEntry.setName(Iter->path());
+    }
+    return EC;
+  }
+};
+}
+
+directory_iterator RealFileSystem::dir_begin(const Twine &Dir,
+                                             std::error_code &EC) {
+  return directory_iterator(std::make_shared<RealFSDirIter>(Dir, EC));
+}
+
 //===-----------------------------------------------------------------------===/
 // OverlayFileSystem implementation
 //===-----------------------------------------------------------------------===/
@@ -198,21 +246,90 @@
   // FIXME: handle symlinks that cross file systems
   for (iterator I = overlays_begin(), E = overlays_end(); I != E; ++I) {
     ErrorOr<Status> Status = (*I)->status(Path);
-    if (Status || Status.getError() != errc::no_such_file_or_directory)
+    if (Status || Status.getError() != llvm::errc::no_such_file_or_directory)
       return Status;
   }
-  return error_code(errc::no_such_file_or_directory, system_category());
+  return make_error_code(llvm::errc::no_such_file_or_directory);
 }
 
-error_code OverlayFileSystem::openFileForRead(const llvm::Twine &Path,
-                                              std::unique_ptr<File> &Result) {
+std::error_code
+OverlayFileSystem::openFileForRead(const llvm::Twine &Path,
+                                   std::unique_ptr<File> &Result) {
   // FIXME: handle symlinks that cross file systems
   for (iterator I = overlays_begin(), E = overlays_end(); I != E; ++I) {
-    error_code EC = (*I)->openFileForRead(Path, Result);
-    if (!EC || EC != errc::no_such_file_or_directory)
+    std::error_code EC = (*I)->openFileForRead(Path, Result);
+    if (!EC || EC != llvm::errc::no_such_file_or_directory)
       return EC;
   }
-  return error_code(errc::no_such_file_or_directory, system_category());
+  return make_error_code(llvm::errc::no_such_file_or_directory);
+}
+
+clang::vfs::detail::DirIterImpl::~DirIterImpl() { }
+
+namespace {
+class OverlayFSDirIterImpl : public clang::vfs::detail::DirIterImpl {
+  OverlayFileSystem &Overlays;
+  std::string Path;
+  OverlayFileSystem::iterator CurrentFS;
+  directory_iterator CurrentDirIter;
+  llvm::StringSet<> SeenNames;
+
+  std::error_code incrementFS() {
+    assert(CurrentFS != Overlays.overlays_end() && "incrementing past end");
+    ++CurrentFS;
+    for (auto E = Overlays.overlays_end(); CurrentFS != E; ++CurrentFS) {
+      std::error_code EC;
+      CurrentDirIter = (*CurrentFS)->dir_begin(Path, EC);
+      if (EC && EC != errc::no_such_file_or_directory)
+        return EC;
+      if (CurrentDirIter != directory_iterator())
+        break; // found
+    }
+    return std::error_code();
+  }
+
+  std::error_code incrementDirIter(bool IsFirstTime) {
+    assert((IsFirstTime || CurrentDirIter != directory_iterator()) &&
+           "incrementing past end");
+    std::error_code EC;
+    if (!IsFirstTime)
+      CurrentDirIter.increment(EC);
+    if (!EC && CurrentDirIter == directory_iterator())
+      EC = incrementFS();
+    return EC;
+  }
+
+  std::error_code incrementImpl(bool IsFirstTime) {
+    while (true) {
+      std::error_code EC = incrementDirIter(IsFirstTime);
+      if (EC || CurrentDirIter == directory_iterator()) {
+        CurrentEntry = Status();
+        return EC;
+      }
+      CurrentEntry = *CurrentDirIter;
+      StringRef Name = llvm::sys::path::filename(CurrentEntry.getName());
+      if (SeenNames.insert(Name))
+        return EC; // name not seen before
+    }
+    llvm_unreachable("returned above");
+  }
+
+public:
+  OverlayFSDirIterImpl(const Twine &Path, OverlayFileSystem &FS,
+                       std::error_code &EC)
+      : Overlays(FS), Path(Path.str()), CurrentFS(Overlays.overlays_begin()) {
+    CurrentDirIter = (*CurrentFS)->dir_begin(Path, EC);
+    EC = incrementImpl(true);
+  }
+
+  std::error_code increment() override { return incrementImpl(false); }
+};
+} // end anonymous namespace
+
+directory_iterator OverlayFileSystem::dir_begin(const Twine &Dir,
+                                                std::error_code &EC) {
+  return directory_iterator(
+      std::make_shared<OverlayFSDirIterImpl>(Dir, *this, EC));
 }
 
 //===-----------------------------------------------------------------------===/
@@ -291,6 +408,19 @@
   static bool classof(const Entry *E) { return E->getKind() == EK_File; }
 };
 
+class VFSFromYAML;
+
+class VFSFromYamlDirIterImpl : public clang::vfs::detail::DirIterImpl {
+  std::string Dir;
+  VFSFromYAML &FS;
+  DirectoryEntry::iterator Current, End;
+public:
+  VFSFromYamlDirIterImpl(const Twine &Path, VFSFromYAML &FS,
+                         DirectoryEntry::iterator Begin,
+                         DirectoryEntry::iterator End, std::error_code &EC);
+  std::error_code increment() override;
+};
+
 /// \brief A virtual file system parsed from a YAML file.
 ///
 /// Currently, this class allows creating virtual directories and mapping
@@ -376,6 +506,9 @@
   ErrorOr<Entry *> lookupPath(sys::path::const_iterator Start,
                               sys::path::const_iterator End, Entry *From);
 
+  /// \brief Get the status of a given an \c Entry.
+  ErrorOr<Status> status(const Twine &Path, Entry *E);
+
 public:
   ~VFSFromYAML();
 
@@ -389,8 +522,30 @@
                              IntrusiveRefCntPtr<FileSystem> ExternalFS);
 
   ErrorOr<Status> status(const Twine &Path) override;
-  error_code openFileForRead(const Twine &Path,
-                             std::unique_ptr<File> &Result) override;
+  std::error_code openFileForRead(const Twine &Path,
+                                  std::unique_ptr<File> &Result) override;
+
+  directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override{
+    ErrorOr<Entry *> E = lookupPath(Dir);
+    if (!E) {
+      EC = E.getError();
+      return directory_iterator();
+    }
+    ErrorOr<Status> S = status(Dir, *E);
+    if (!S) {
+      EC = S.getError();
+      return directory_iterator();
+    }
+    if (!S->isDirectory()) {
+      EC = std::error_code(static_cast<int>(errc::not_a_directory),
+                           std::system_category());
+      return directory_iterator();
+    }
+
+    DirectoryEntry *D = cast<DirectoryEntry>(*E);
+    return directory_iterator(std::make_shared<VFSFromYamlDirIterImpl>(Dir,
+        *this, D->contents_begin(), D->contents_end(), EC));
+  }
 };
 
 /// \brief A helper class to hold the common YAML parsing state.
@@ -740,21 +895,21 @@
   Path_.toVector(Path);
 
   // Handle relative paths
-  if (error_code EC = sys::fs::make_absolute(Path))
+  if (std::error_code EC = sys::fs::make_absolute(Path))
     return EC;
 
   if (Path.empty())
-    return error_code(errc::invalid_argument, system_category());
+    return make_error_code(llvm::errc::invalid_argument);
 
   sys::path::const_iterator Start = sys::path::begin(Path);
   sys::path::const_iterator End = sys::path::end(Path);
   for (std::vector<Entry *>::iterator I = Roots.begin(), E = Roots.end();
        I != E; ++I) {
     ErrorOr<Entry *> Result = lookupPath(Start, End, *I);
-    if (Result || Result.getError() != errc::no_such_file_or_directory)
+    if (Result || Result.getError() != llvm::errc::no_such_file_or_directory)
       return Result;
   }
-  return error_code(errc::no_such_file_or_directory, system_category());
+  return make_error_code(llvm::errc::no_such_file_or_directory);
 }
 
 ErrorOr<Entry *> VFSFromYAML::lookupPath(sys::path::const_iterator Start,
@@ -767,7 +922,7 @@
   if (CaseSensitive ? !Start->equals(From->getName())
                     : !Start->equals_lower(From->getName()))
     // failure to match
-    return error_code(errc::no_such_file_or_directory, system_category());
+    return make_error_code(llvm::errc::no_such_file_or_directory);
 
   ++Start;
 
@@ -778,25 +933,22 @@
 
   DirectoryEntry *DE = dyn_cast<DirectoryEntry>(From);
   if (!DE)
-    return error_code(errc::not_a_directory, system_category());
+    return make_error_code(llvm::errc::not_a_directory);
 
   for (DirectoryEntry::iterator I = DE->contents_begin(),
                                 E = DE->contents_end();
        I != E; ++I) {
     ErrorOr<Entry *> Result = lookupPath(Start, End, *I);
-    if (Result || Result.getError() != errc::no_such_file_or_directory)
+    if (Result || Result.getError() != llvm::errc::no_such_file_or_directory)
       return Result;
   }
-  return error_code(errc::no_such_file_or_directory, system_category());
+  return make_error_code(llvm::errc::no_such_file_or_directory);
 }
 
-ErrorOr<Status> VFSFromYAML::status(const Twine &Path) {
-  ErrorOr<Entry *> Result = lookupPath(Path);
-  if (!Result)
-    return Result.getError();
-
+ErrorOr<Status> VFSFromYAML::status(const Twine &Path, Entry *E) {
+  assert(E != nullptr);
   std::string PathStr(Path.str());
-  if (FileEntry *F = dyn_cast<FileEntry>(*Result)) {
+  if (FileEntry *F = dyn_cast<FileEntry>(E)) {
     ErrorOr<Status> S = ExternalFS->status(F->getExternalContentsPath());
     assert(!S || S->getName() == F->getExternalContentsPath());
     if (S && !F->useExternalName(UseExternalNames))
@@ -805,31 +957,39 @@
       S->IsVFSMapped = true;
     return S;
   } else { // directory
-    DirectoryEntry *DE = cast<DirectoryEntry>(*Result);
+    DirectoryEntry *DE = cast<DirectoryEntry>(E);
     Status S = DE->getStatus();
     S.setName(PathStr);
     return S;
   }
 }
 
-error_code VFSFromYAML::openFileForRead(const Twine &Path,
-                                        std::unique_ptr<vfs::File> &Result) {
+ErrorOr<Status> VFSFromYAML::status(const Twine &Path) {
+  ErrorOr<Entry *> Result = lookupPath(Path);
+  if (!Result)
+    return Result.getError();
+  return status(Path, *Result);
+}
+
+std::error_code
+VFSFromYAML::openFileForRead(const Twine &Path,
+                             std::unique_ptr<vfs::File> &Result) {
   ErrorOr<Entry *> E = lookupPath(Path);
   if (!E)
     return E.getError();
 
   FileEntry *F = dyn_cast<FileEntry>(*E);
   if (!F) // FIXME: errc::not_a_file?
-    return error_code(errc::invalid_argument, system_category());
+    return make_error_code(llvm::errc::invalid_argument);
 
-  if (error_code EC = ExternalFS->openFileForRead(F->getExternalContentsPath(),
-                                                  Result))
+  if (std::error_code EC =
+          ExternalFS->openFileForRead(F->getExternalContentsPath(), Result))
     return EC;
 
   if (!F->useExternalName(UseExternalNames))
     Result->setName(Path.str());
 
-  return error_code::success();
+  return std::error_code();
 }
 
 IntrusiveRefCntPtr<FileSystem>
@@ -981,3 +1141,70 @@
 
   JSONWriter(OS).write(Mappings, IsCaseSensitive);
 }
+
+VFSFromYamlDirIterImpl::VFSFromYamlDirIterImpl(const Twine &_Path,
+                                               VFSFromYAML &FS,
+                                               DirectoryEntry::iterator Begin,
+                                               DirectoryEntry::iterator End,
+                                               std::error_code &EC)
+    : Dir(_Path.str()), FS(FS), Current(Begin), End(End) {
+  if (Current != End) {
+    SmallString<128> PathStr(Dir);
+    llvm::sys::path::append(PathStr, (*Current)->getName());
+    llvm::ErrorOr<vfs::Status> S = FS.status(PathStr.str());
+    if (S)
+      CurrentEntry = *S;
+    else
+      EC = S.getError();
+  }
+}
+
+std::error_code VFSFromYamlDirIterImpl::increment() {
+  assert(Current != End && "cannot iterate past end");
+  if (++Current != End) {
+    SmallString<128> PathStr(Dir);
+    llvm::sys::path::append(PathStr, (*Current)->getName());
+    llvm::ErrorOr<vfs::Status> S = FS.status(PathStr.str());
+    if (!S)
+      return S.getError();
+    CurrentEntry = *S;
+  } else {
+    CurrentEntry = Status();
+  }
+  return std::error_code();
+}
+
+vfs::recursive_directory_iterator::recursive_directory_iterator(FileSystem &FS_,
+                                                           const Twine &Path,
+                                                           std::error_code &EC)
+    : FS(&FS_) {
+  directory_iterator I = FS->dir_begin(Path, EC);
+  if (!EC && I != directory_iterator()) {
+    State = std::make_shared<IterState>();
+    State->push(I);
+  }
+}
+
+vfs::recursive_directory_iterator &
+recursive_directory_iterator::increment(std::error_code &EC) {
+  assert(FS && State && !State->empty() && "incrementing past end");
+  assert(State->top()->isStatusKnown() && "non-canonical end iterator");
+  vfs::directory_iterator End;
+  if (State->top()->isDirectory()) {
+    vfs::directory_iterator I = FS->dir_begin(State->top()->getName(), EC);
+    if (EC)
+      return *this;
+    if (I != End) {
+      State->push(I);
+      return *this;
+    }
+  }
+
+  while (!State->empty() && State->top().increment(EC) == End)
+    State->pop();
+
+  if (State->empty())
+    State.reset(); // end iterator
+
+  return *this;
+}