<div dir="ltr">We test it in clangd (<a href="https://reviews.llvm.org/D33416">https://reviews.llvm.org/D33416</a>).<div>Logically, it's  a single change, split into two part: for cfe and clang-tools-extra.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, May 24, 2017 at 1:48 AM, Bruno Cardoso Lopes <span dir="ltr"><<a href="mailto:bruno.cardoso@gmail.com" target="_blank">bruno.cardoso@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Any specific reason why this doesn't contain a testcase?<br>
<div class="HOEnZb"><div class="h5"><br>
On Tue, May 23, 2017 at 4:37 AM, Ilya Biryukov via cfe-commits<br>
<<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br>
> Author: ibiryukov<br>
> Date: Tue May 23 06:37:52 2017<br>
> New Revision: 303630<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=303630&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=303630&view=rev</a><br>
> Log:<br>
> Allow to use vfs::FileSystem for file accesses inside ASTUnit.<br>
><br>
> Reviewers: bkramer, krasimir, arphaman, akyrtzi<br>
><br>
> Reviewed By: bkramer<br>
><br>
> Subscribers: klimek, cfe-commits<br>
><br>
> Differential Revision: <a href="https://reviews.llvm.org/D33397" rel="noreferrer" target="_blank">https://reviews.llvm.org/<wbr>D33397</a><br>
><br>
> Modified:<br>
>     cfe/trunk/include/clang/<wbr>Frontend/ASTUnit.h<br>
>     cfe/trunk/include/clang/<wbr>Frontend/CompilerInvocation.h<br>
>     cfe/trunk/lib/Frontend/<wbr>ASTUnit.cpp<br>
>     cfe/trunk/lib/Frontend/<wbr>CompilerInvocation.cpp<br>
><br>
> Modified: cfe/trunk/include/clang/<wbr>Frontend/ASTUnit.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/ASTUnit.h?rev=303630&r1=303629&r2=303630&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Frontend/ASTUnit.h?rev=<wbr>303630&r1=303629&r2=303630&<wbr>view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/include/clang/<wbr>Frontend/ASTUnit.h (original)<br>
> +++ cfe/trunk/include/clang/<wbr>Frontend/ASTUnit.h Tue May 23 06:37:52 2017<br>
> @@ -59,6 +59,10 @@ class TargetInfo;<br>
>  class FrontendAction;<br>
>  class ASTDeserializationListener;<br>
><br>
> +namespace vfs {<br>
> +class FileSystem;<br>
> +}<br>
> +<br>
>  /// \brief Utility class for loading a ASTContext from an AST file.<br>
>  ///<br>
>  class ASTUnit : public ModuleLoader {<br>
> @@ -420,7 +424,8 @@ private:<br>
>    explicit ASTUnit(bool MainFileIsAST);<br>
><br>
>    bool Parse(std::shared_ptr<<wbr>PCHContainerOperations> PCHContainerOps,<br>
> -             std::unique_ptr<llvm::<wbr>MemoryBuffer> OverrideMainBuffer);<br>
> +             std::unique_ptr<llvm::<wbr>MemoryBuffer> OverrideMainBuffer,<br>
> +             IntrusiveRefCntPtr<vfs::<wbr>FileSystem> VFS);<br>
><br>
>    struct ComputedPreamble {<br>
>      llvm::MemoryBuffer *Buffer;<br>
> @@ -434,11 +439,13 @@ private:<br>
>            PreambleEndsAtStartOfLine(<wbr>PreambleEndsAtStartOfLine) {}<br>
>    };<br>
>    ComputedPreamble ComputePreamble(<wbr>CompilerInvocation &Invocation,<br>
> -                                   unsigned MaxLines);<br>
> +                                   unsigned MaxLines,<br>
> +                                   IntrusiveRefCntPtr<vfs::<wbr>FileSystem> VFS);<br>
><br>
>    std::unique_ptr<llvm::<wbr>MemoryBuffer> getMainBufferWithPrecompiledPr<wbr>eamble(<br>
>        std::shared_ptr<<wbr>PCHContainerOperations> PCHContainerOps,<br>
> -      const CompilerInvocation &PreambleInvocationIn, bool AllowRebuild = true,<br>
> +      const CompilerInvocation &PreambleInvocationIn,<br>
> +      IntrusiveRefCntPtr<vfs::<wbr>FileSystem> VFS, bool AllowRebuild = true,<br>
>        unsigned MaxLines = 0);<br>
>    void RealizeTopLevelDeclsFromPreamb<wbr>le();<br>
><br>
> @@ -731,11 +738,17 @@ private:<br>
>    /// of this translation unit should be precompiled, to improve the performance<br>
>    /// of reparsing. Set to zero to disable preambles.<br>
>    ///<br>
> +  /// \param VFS - A vfs::FileSystem to be used for all file accesses. Note that<br>
> +  /// preamble is saved to a temporary directory on a RealFileSystem, so in order<br>
> +  /// for it to be loaded correctly, VFS should have access to it(i.e., be an<br>
> +  /// overlay over RealFileSystem).<br>
> +  ///<br>
>    /// \returns \c true if a catastrophic failure occurred (which means that the<br>
>    /// \c ASTUnit itself is invalid), or \c false otherwise.<br>
>    bool LoadFromCompilerInvocation(<br>
>        std::shared_ptr<<wbr>PCHContainerOperations> PCHContainerOps,<br>
> -      unsigned PrecompilePreambleAfterNParses<wbr>);<br>
> +      unsigned PrecompilePreambleAfterNParses<wbr>,<br>
> +      IntrusiveRefCntPtr<vfs::<wbr>FileSystem> VFS);<br>
><br>
>  public:<br>
><br>
> @@ -826,6 +839,11 @@ public:<br>
>    /// (e.g. because the PCH could not be loaded), this accepts the ASTUnit<br>
>    /// mainly to allow the caller to see the diagnostics.<br>
>    ///<br>
> +  /// \param VFS - A vfs::FileSystem to be used for all file accesses. Note that<br>
> +  /// preamble is saved to a temporary directory on a RealFileSystem, so in order<br>
> +  /// for it to be loaded correctly, VFS should have access to it(i.e., be an<br>
> +  /// overlay over RealFileSystem). RealFileSystem will be used if \p VFS is nullptr.<br>
> +  ///<br>
>    // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we<br>
>    // shouldn't need to specify them at construction time.<br>
>    static ASTUnit *LoadFromCommandLine(<br>
> @@ -842,15 +860,23 @@ public:<br>
>        bool AllowPCHWithCompilerErrors = false, bool SkipFunctionBodies = false,<br>
>        bool UserFilesAreVolatile = false, bool ForSerialization = false,<br>
>        llvm::Optional<StringRef> ModuleFormat = llvm::None,<br>
> -      std::unique_ptr<ASTUnit> *ErrAST = nullptr);<br>
> +      std::unique_ptr<ASTUnit> *ErrAST = nullptr,<br>
> +      IntrusiveRefCntPtr<vfs::<wbr>FileSystem> VFS = nullptr);<br>
><br>
>    /// \brief Reparse the source files using the same command-line options that<br>
>    /// were originally used to produce this translation unit.<br>
>    ///<br>
> +  /// \param VFS - A vfs::FileSystem to be used for all file accesses. Note that<br>
> +  /// preamble is saved to a temporary directory on a RealFileSystem, so in order<br>
> +  /// for it to be loaded correctly, VFS should give an access to this(i.e. be an<br>
> +  /// overlay over RealFileSystem). FileMgr->getVirtualFileSystem(<wbr>) will be used if<br>
> +  /// \p VFS is nullptr.<br>
> +  ///<br>
>    /// \returns True if a failure occurred that causes the ASTUnit not to<br>
>    /// contain any translation-unit information, false otherwise.<br>
>    bool Reparse(std::shared_ptr<<wbr>PCHContainerOperations> PCHContainerOps,<br>
> -               ArrayRef<RemappedFile> RemappedFiles = None);<br>
> +               ArrayRef<RemappedFile> RemappedFiles = None,<br>
> +               IntrusiveRefCntPtr<vfs::<wbr>FileSystem> VFS = nullptr);<br>
><br>
>    /// \brief Perform code completion at the given file, line, and<br>
>    /// column within this translation unit.<br>
><br>
> Modified: cfe/trunk/include/clang/<wbr>Frontend/CompilerInvocation.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CompilerInvocation.h?rev=303630&r1=303629&r2=303630&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Frontend/<wbr>CompilerInvocation.h?rev=<wbr>303630&r1=303629&r2=303630&<wbr>view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/include/clang/<wbr>Frontend/CompilerInvocation.h (original)<br>
> +++ cfe/trunk/include/clang/<wbr>Frontend/CompilerInvocation.h Tue May 23 06:37:52 2017<br>
> @@ -225,6 +225,11 @@ IntrusiveRefCntPtr<vfs::<wbr>FileSystem><br>
>  createVFSFromCompilerInvocatio<wbr>n(const CompilerInvocation &CI,<br>
>                                  DiagnosticsEngine &Diags);<br>
><br>
> +IntrusiveRefCntPtr<vfs::<wbr>FileSystem><br>
> +<wbr>createVFSFromCompilerInvocatio<wbr>n(const CompilerInvocation &CI,<br>
> +                                DiagnosticsEngine &Diags,<br>
> +                                IntrusiveRefCntPtr<vfs::<wbr>FileSystem> BaseFS);<br>
> +<br>
>  } // end namespace clang<br>
><br>
>  #endif<br>
><br>
> Modified: cfe/trunk/lib/Frontend/<wbr>ASTUnit.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=303630&r1=303629&r2=303630&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/<wbr>Frontend/ASTUnit.cpp?rev=<wbr>303630&r1=303629&r2=303630&<wbr>view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/lib/Frontend/<wbr>ASTUnit.cpp (original)<br>
> +++ cfe/trunk/lib/Frontend/<wbr>ASTUnit.cpp Tue May 23 06:37:52 2017<br>
> @@ -90,6 +90,21 @@ namespace {<br>
>      /// \brief Erase temporary files and the preamble file.<br>
>      void Cleanup();<br>
>    };<br>
> +<br>
> +  template <class T><br>
> +  std::unique_ptr<T> valueOrNull(llvm::ErrorOr<std:<wbr>:unique_ptr<T>> Val) {<br>
> +    if (!Val)<br>
> +      return nullptr;<br>
> +    return std::move(*Val);<br>
> +  }<br>
> +<br>
> +  template <class T><br>
> +  bool moveOnNoError(llvm::ErrorOr<T> Val, T &Output) {<br>
> +    if (!Val)<br>
> +      return false;<br>
> +    Output = std::move(*Val);<br>
> +    return true;<br>
> +  }<br>
>  }<br>
><br>
>  static llvm::sys::SmartMutex<false> &getOnDiskMutex() {<br>
> @@ -1019,7 +1034,8 @@ static void checkAndSanitizeDiags(SmallV<br>
>  /// \returns True if a failure occurred that causes the ASTUnit not to<br>
>  /// contain any translation-unit information, false otherwise.<br>
>  bool ASTUnit::Parse(std::shared_<wbr>ptr<PCHContainerOperations> PCHContainerOps,<br>
> -                    std::unique_ptr<llvm::<wbr>MemoryBuffer> OverrideMainBuffer) {<br>
> +                    std::unique_ptr<llvm::<wbr>MemoryBuffer> OverrideMainBuffer,<br>
> +                    IntrusiveRefCntPtr<vfs::<wbr>FileSystem> VFS) {<br>
>    SavedMainFileBuffer.reset();<br>
><br>
>    if (!Invocation)<br>
> @@ -1028,6 +1044,12 @@ bool ASTUnit::Parse(std::shared_<wbr>ptr<PCHC<br>
>    // Create the compiler instance to use for building the AST.<br>
>    std::unique_ptr<<wbr>CompilerInstance> Clang(<br>
>        new CompilerInstance(std::move(<wbr>PCHContainerOps)));<br>
> +  if (FileMgr && VFS) {<br>
> +    assert(VFS == FileMgr->getVirtualFileSystem(<wbr>) &&<br>
> +           "VFS passed to Parse and VFS in FileMgr are different");<br>
> +  } else if (VFS) {<br>
> +    Clang->setVirtualFileSystem(<wbr>VFS);<br>
> +  }<br>
><br>
>    // Recover resources if we crash before exiting this method.<br>
>    llvm::<wbr>CrashRecoveryContextCleanupReg<wbr>istrar<CompilerInstance><br>
> @@ -1170,7 +1192,8 @@ static std::string GetPreamblePCHPath()<br>
>  /// that corresponds to the main file along with a pair (bytes, start-of-line)<br>
>  /// that describes the preamble.<br>
>  ASTUnit::ComputedPreamble<br>
> -ASTUnit::ComputePreamble(<wbr>CompilerInvocation &Invocation, unsigned MaxLines) {<br>
> +ASTUnit::ComputePreamble(<wbr>CompilerInvocation &Invocation, unsigned MaxLines,<br>
> +                         IntrusiveRefCntPtr<vfs::<wbr>FileSystem> VFS) {<br>
>    FrontendOptions &FrontendOpts = Invocation.getFrontendOpts();<br>
>    PreprocessorOptions &PreprocessorOpts = Invocation.<wbr>getPreprocessorOpts();<br>
><br>
> @@ -1180,28 +1203,32 @@ ASTUnit::ComputePreamble(<wbr>CompilerInvocat<br>
>    llvm::MemoryBuffer *Buffer = nullptr;<br>
>    std::unique_ptr<llvm::<wbr>MemoryBuffer> BufferOwner;<br>
>    std::string MainFilePath(FrontendOpts.<wbr>Inputs[0].getFile());<br>
> -  llvm::sys::fs::UniqueID MainFileID;<br>
> -  if (!llvm::sys::fs::getUniqueID(<wbr>MainFilePath, MainFileID)) {<br>
> +  auto MainFileStatus = VFS->status(MainFilePath);<br>
> +  if (MainFileStatus) {<br>
> +    llvm::sys::fs::UniqueID MainFileID = MainFileStatus->getUniqueID();<br>
> +<br>
>      // Check whether there is a file-file remapping of the main file<br>
>      for (const auto &RF : PreprocessorOpts.<wbr>RemappedFiles) {<br>
>        std::string MPath(RF.first);<br>
> -      llvm::sys::fs::UniqueID MID;<br>
> -      if (!llvm::sys::fs::getUniqueID(<wbr>MPath, MID)) {<br>
> +      auto MPathStatus = VFS->status(MPath);<br>
> +      if (MPathStatus) {<br>
> +        llvm::sys::fs::UniqueID MID = MPathStatus->getUniqueID();<br>
>          if (MainFileID == MID) {<br>
>            // We found a remapping. Try to load the resulting, remapped source.<br>
> -          BufferOwner = getBufferForFile(RF.second);<br>
> +          BufferOwner = valueOrNull(VFS-><wbr>getBufferForFile(RF.second));<br>
>            if (!BufferOwner)<br>
>              return ComputedPreamble(nullptr, nullptr, 0, true);<br>
>          }<br>
>        }<br>
>      }<br>
> -<br>
> +<br>
>      // Check whether there is a file-buffer remapping. It supercedes the<br>
>      // file-file remapping.<br>
>      for (const auto &RB : PreprocessorOpts.<wbr>RemappedFileBuffers) {<br>
>        std::string MPath(RB.first);<br>
> -      llvm::sys::fs::UniqueID MID;<br>
> -      if (!llvm::sys::fs::getUniqueID(<wbr>MPath, MID)) {<br>
> +      auto MPathStatus = VFS->status(MPath);<br>
> +      if (MPathStatus) {<br>
> +        llvm::sys::fs::UniqueID MID = MPathStatus->getUniqueID();<br>
>          if (MainFileID == MID) {<br>
>            // We found a remapping.<br>
>            BufferOwner.reset();<br>
> @@ -1213,7 +1240,7 @@ ASTUnit::ComputePreamble(<wbr>CompilerInvocat<br>
><br>
>    // If the main source file was not remapped, load it now.<br>
>    if (!Buffer && !BufferOwner) {<br>
> -    BufferOwner = getBufferForFile(FrontendOpts.<wbr>Inputs[0].getFile());<br>
> +    BufferOwner = valueOrNull(VFS-><wbr>getBufferForFile(FrontendOpts.<wbr>Inputs[0].getFile()));<br>
>      if (!BufferOwner)<br>
>        return ComputedPreamble(nullptr, nullptr, 0, true);<br>
>    }<br>
> @@ -1324,8 +1351,10 @@ makeStandaloneDiagnostic(const LangOptio<br>
>  std::unique_ptr<llvm::<wbr>MemoryBuffer><br>
>  ASTUnit::<wbr>getMainBufferWithPrecompiledPr<wbr>eamble(<br>
>      std::shared_ptr<<wbr>PCHContainerOperations> PCHContainerOps,<br>
> -    const CompilerInvocation &PreambleInvocationIn, bool AllowRebuild,<br>
> +    const CompilerInvocation &PreambleInvocationIn,<br>
> +    IntrusiveRefCntPtr<vfs::<wbr>FileSystem> VFS, bool AllowRebuild,<br>
>      unsigned MaxLines) {<br>
> +  assert(VFS && "VFS is null");<br>
><br>
>    auto PreambleInvocation =<br>
>        std::make_shared<<wbr>CompilerInvocation>(<wbr>PreambleInvocationIn);<br>
> @@ -1333,7 +1362,8 @@ ASTUnit::<wbr>getMainBufferWithPrecompiledPr<wbr>e<br>
>    PreprocessorOptions &PreprocessorOpts<br>
>      = PreambleInvocation-><wbr>getPreprocessorOpts();<br>
><br>
> -  ComputedPreamble NewPreamble = ComputePreamble(*<wbr>PreambleInvocation, MaxLines);<br>
> +  ComputedPreamble NewPreamble =<br>
> +      ComputePreamble(*<wbr>PreambleInvocation, MaxLines, VFS);<br>
><br>
>    if (!NewPreamble.Size) {<br>
>      // We couldn't find a preamble in the main source. Clear out the current<br>
> @@ -1369,7 +1399,7 @@ ASTUnit::<wbr>getMainBufferWithPrecompiledPr<wbr>e<br>
>            break;<br>
><br>
>          vfs::Status Status;<br>
> -        if (FileMgr-><wbr>getNoncachedStatValue(R.<wbr>second, Status)) {<br>
> +        if (!moveOnNoError(VFS->status(R.<wbr>second), Status)) {<br>
>            // If we can't stat the file we're remapping to, assume that something<br>
>            // horrible happened.<br>
>            AnyFileChanged = true;<br>
> @@ -1386,7 +1416,7 @@ ASTUnit::<wbr>getMainBufferWithPrecompiledPr<wbr>e<br>
>            break;<br>
><br>
>          vfs::Status Status;<br>
> -        if (FileMgr-><wbr>getNoncachedStatValue(RB.<wbr>first, Status)) {<br>
> +        if (!moveOnNoError(VFS->status(<wbr>RB.first), Status)) {<br>
>            AnyFileChanged = true;<br>
>            break;<br>
>          }<br>
> @@ -1401,7 +1431,7 @@ ASTUnit::<wbr>getMainBufferWithPrecompiledPr<wbr>e<br>
>             !AnyFileChanged && F != FEnd;<br>
>             ++F) {<br>
>          vfs::Status Status;<br>
> -        if (FileMgr-><wbr>getNoncachedStatValue(F-><wbr>first(), Status)) {<br>
> +        if (!moveOnNoError(VFS->status(F-<wbr>>first()), Status)) {<br>
>            // If we can't stat the file, assume that something horrible happened.<br>
>            AnyFileChanged = true;<br>
>            break;<br>
> @@ -1546,14 +1576,14 @@ ASTUnit::<wbr>getMainBufferWithPrecompiledPr<wbr>e<br>
>    TopLevelDeclsInPreamble.clear(<wbr>);<br>
>    PreambleDiagnostics.clear();<br>
><br>
> -  IntrusiveRefCntPtr<vfs::<wbr>FileSystem> VFS =<br>
> -      createVFSFromCompilerInvocatio<wbr>n(Clang->getInvocation(), getDiagnostics());<br>
> +  VFS = createVFSFromCompilerInvocatio<wbr>n(Clang->getInvocation(),<br>
> +                                        getDiagnostics(), VFS);<br>
>    if (!VFS)<br>
>      return nullptr;<br>
><br>
>    // Create a file manager object to provide access to and cache the filesystem.<br>
>    Clang->setFileManager(new FileManager(Clang-><wbr>getFileSystemOpts(), VFS));<br>
> -<br>
> +<br>
>    // Create the source manager.<br>
>    Clang->setSourceManager(new SourceManager(getDiagnostics()<wbr>,<br>
>                                              Clang->getFileManager()));<br>
> @@ -1863,10 +1893,13 @@ ASTUnit *ASTUnit::<wbr>LoadFromCompilerInvoca<br>
><br>
>  bool ASTUnit::<wbr>LoadFromCompilerInvocation(<br>
>      std::shared_ptr<<wbr>PCHContainerOperations> PCHContainerOps,<br>
> -    unsigned PrecompilePreambleAfterNParses<wbr>) {<br>
> +    unsigned PrecompilePreambleAfterNParses<wbr>,<br>
> +    IntrusiveRefCntPtr<vfs::<wbr>FileSystem> VFS) {<br>
>    if (!Invocation)<br>
>      return true;<br>
> -<br>
> +<br>
> +  assert(VFS && "VFS is null");<br>
> +<br>
>    // We'll manage file buffers ourselves.<br>
>    Invocation-><wbr>getPreprocessorOpts().<wbr>RetainRemappedFileBuffers = true;<br>
>    Invocation->getFrontendOpts().<wbr>DisableFree = false;<br>
> @@ -1877,19 +1910,19 @@ bool ASTUnit::<wbr>LoadFromCompilerInvocation<br>
>    if (<wbr>PrecompilePreambleAfterNParses > 0) {<br>
>      PreambleRebuildCounter = PrecompilePreambleAfterNParses<wbr>;<br>
>      OverrideMainBuffer =<br>
> -        getMainBufferWithPrecompiledPr<wbr>eamble(PCHContainerOps, *Invocation);<br>
> +        getMainBufferWithPrecompiledPr<wbr>eamble(PCHContainerOps, *Invocation, VFS);<br>
>      getDiagnostics().Reset();<br>
>      ProcessWarningOptions(<wbr>getDiagnostics(), Invocation->getDiagnosticOpts(<wbr>));<br>
>    }<br>
> -<br>
> +<br>
>    SimpleTimer ParsingTimer(WantTiming);<br>
>    ParsingTimer.setOutput("<wbr>Parsing " + getMainFileName());<br>
> -<br>
> +<br>
>    // Recover resources if we crash before exiting this method.<br>
>    llvm::<wbr>CrashRecoveryContextCleanupReg<wbr>istrar<llvm::MemoryBuffer><br>
>      MemBufferCleanup(<wbr>OverrideMainBuffer.get());<br>
><br>
> -  return Parse(std::move(<wbr>PCHContainerOps), std::move(OverrideMainBuffer))<wbr>;<br>
> +  return Parse(std::move(<wbr>PCHContainerOps), std::move(OverrideMainBuffer), VFS);<br>
>  }<br>
><br>
>  std::unique_ptr<ASTUnit> ASTUnit::<wbr>LoadFromCompilerInvocation(<br>
> @@ -1923,7 +1956,8 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFr<br>
>      DiagCleanup(Diags.get());<br>
><br>
>    if (AST-><wbr>LoadFromCompilerInvocation(<wbr>std::move(PCHContainerOps),<br>
> -                                      PrecompilePreambleAfterNParses<wbr>))<br>
> +                                      PrecompilePreambleAfterNParses<wbr>,<br>
> +                                      AST->FileMgr-><wbr>getVirtualFileSystem()))<br>
>      return nullptr;<br>
>    return AST;<br>
>  }<br>
> @@ -1938,7 +1972,8 @@ ASTUnit *ASTUnit::LoadFromCommandLine(<br>
>      bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeComp<wbr>letion,<br>
>      bool AllowPCHWithCompilerErrors, bool SkipFunctionBodies,<br>
>      bool UserFilesAreVolatile, bool ForSerialization,<br>
> -    llvm::Optional<StringRef> ModuleFormat, std::unique_ptr<ASTUnit> *ErrAST) {<br>
> +    llvm::Optional<StringRef> ModuleFormat, std::unique_ptr<ASTUnit> *ErrAST,<br>
> +    IntrusiveRefCntPtr<vfs::<wbr>FileSystem> VFS) {<br>
>    assert(Diags.get() && "no DiagnosticsEngine was provided");<br>
><br>
>    SmallVector<StoredDiagnostic, 4> StoredDiagnostics;<br>
> @@ -1979,8 +2014,9 @@ ASTUnit *ASTUnit::LoadFromCommandLine(<br>
>    ConfigureDiags(Diags, *AST, CaptureDiagnostics);<br>
>    AST->Diagnostics = Diags;<br>
>    AST->FileSystemOpts = CI->getFileSystemOpts();<br>
> -  IntrusiveRefCntPtr<vfs::<wbr>FileSystem> VFS =<br>
> -      createVFSFromCompilerInvocatio<wbr>n(*CI, *Diags);<br>
> +  if (!VFS)<br>
> +    VFS = vfs::getRealFileSystem();<br>
> +  VFS = createVFSFromCompilerInvocatio<wbr>n(*CI, *Diags, VFS);<br>
>    if (!VFS)<br>
>      return nullptr;<br>
>    AST->FileMgr = new FileManager(AST-><wbr>FileSystemOpts, VFS);<br>
> @@ -2006,7 +2042,8 @@ ASTUnit *ASTUnit::LoadFromCommandLine(<br>
>      ASTUnitCleanup(AST.get());<br>
><br>
>    if (AST-><wbr>LoadFromCompilerInvocation(<wbr>std::move(PCHContainerOps),<br>
> -                                      PrecompilePreambleAfterNParses<wbr>)) {<br>
> +                                      PrecompilePreambleAfterNParses<wbr>,<br>
> +                                      VFS)) {<br>
>      // Some error occurred, if caller wants to examine diagnostics, pass it the<br>
>      // ASTUnit.<br>
>      if (ErrAST) {<br>
> @@ -2020,10 +2057,16 @@ ASTUnit *ASTUnit::LoadFromCommandLine(<br>
>  }<br>
><br>
>  bool ASTUnit::Reparse(std::shared_<wbr>ptr<PCHContainerOperations> PCHContainerOps,<br>
> -                      ArrayRef<RemappedFile> RemappedFiles) {<br>
> +                      ArrayRef<RemappedFile> RemappedFiles,<br>
> +                      IntrusiveRefCntPtr<vfs::<wbr>FileSystem> VFS) {<br>
>    if (!Invocation)<br>
>      return true;<br>
><br>
> +  if (!VFS) {<br>
> +    assert(FileMgr && "FileMgr is null on Reparse call");<br>
> +    VFS = FileMgr->getVirtualFileSystem(<wbr>);<br>
> +  }<br>
> +<br>
>    clearFileLevelDecls();<br>
><br>
>    SimpleTimer ParsingTimer(WantTiming);<br>
> @@ -2045,7 +2088,8 @@ bool ASTUnit::Reparse(std::shared_<wbr>ptr<PC<br>
>    std::unique_ptr<llvm::<wbr>MemoryBuffer> OverrideMainBuffer;<br>
>    if (!getPreambleFile(this).empty(<wbr>) || PreambleRebuildCounter > 0)<br>
>      OverrideMainBuffer =<br>
> -        getMainBufferWithPrecompiledPr<wbr>eamble(PCHContainerOps, *Invocation);<br>
> +        getMainBufferWithPrecompiledPr<wbr>eamble(PCHContainerOps, *Invocation, VFS);<br>
> +<br>
><br>
>    // Clear out the diagnostics state.<br>
>    FileMgr.reset();<br>
> @@ -2056,7 +2100,7 @@ bool ASTUnit::Reparse(std::shared_<wbr>ptr<PC<br>
><br>
>    // Parse the sources<br>
>    bool Result =<br>
> -      Parse(std::move(<wbr>PCHContainerOps), std::move(OverrideMainBuffer))<wbr>;<br>
> +      Parse(std::move(<wbr>PCHContainerOps), std::move(OverrideMainBuffer), VFS);<br>
><br>
>    // If we're caching global code-completion results, and the top-level<br>
>    // declarations have changed, clear out the code-completion cache.<br>
> @@ -2414,15 +2458,19 @@ void ASTUnit::CodeComplete(<br>
>    std::unique_ptr<llvm::<wbr>MemoryBuffer> OverrideMainBuffer;<br>
>    if (!getPreambleFile(this).empty(<wbr>)) {<br>
>      std::string CompleteFilePath(File);<br>
> -    llvm::sys::fs::UniqueID CompleteFileID;<br>
><br>
> -    if (!llvm::sys::fs::getUniqueID(<wbr>CompleteFilePath, CompleteFileID)) {<br>
> +    auto VFS = FileMgr.getVirtualFileSystem()<wbr>;<br>
> +    auto CompleteFileStatus = VFS->status(CompleteFilePath);<br>
> +    if (CompleteFileStatus) {<br>
> +      llvm::sys::fs::UniqueID CompleteFileID = CompleteFileStatus-><wbr>getUniqueID();<br>
> +<br>
>        std::string MainPath(OriginalSourceFile);<br>
> -      llvm::sys::fs::UniqueID MainID;<br>
> -      if (!llvm::sys::fs::getUniqueID(<wbr>MainPath, MainID)) {<br>
> +      auto MainStatus = VFS->status(MainPath);<br>
> +      if (MainStatus) {<br>
> +        llvm::sys::fs::UniqueID MainID = MainStatus->getUniqueID();<br>
>          if (CompleteFileID == MainID && Line > 1)<br>
>            OverrideMainBuffer = getMainBufferWithPrecompiledPr<wbr>eamble(<br>
> -              PCHContainerOps, Inv, false, Line - 1);<br>
> +              PCHContainerOps, Inv, VFS, false, Line - 1);<br>
>        }<br>
>      }<br>
>    }<br>
><br>
> Modified: cfe/trunk/lib/Frontend/<wbr>CompilerInvocation.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=303630&r1=303629&r2=303630&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/<wbr>Frontend/CompilerInvocation.<wbr>cpp?rev=303630&r1=303629&r2=<wbr>303630&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/lib/Frontend/<wbr>CompilerInvocation.cpp (original)<br>
> +++ cfe/trunk/lib/Frontend/<wbr>CompilerInvocation.cpp Tue May 23 06:37:52 2017<br>
> @@ -2750,15 +2750,22 @@ void BuryPointer(const void *Ptr) {<br>
>  IntrusiveRefCntPtr<vfs::<wbr>FileSystem><br>
>  createVFSFromCompilerInvocatio<wbr>n(const CompilerInvocation &CI,<br>
>                                  DiagnosticsEngine &Diags) {<br>
> +  return createVFSFromCompilerInvocatio<wbr>n(CI, Diags, vfs::getRealFileSystem());<br>
> +}<br>
> +<br>
> +IntrusiveRefCntPtr<vfs::<wbr>FileSystem><br>
> +<wbr>createVFSFromCompilerInvocatio<wbr>n(const CompilerInvocation &CI,<br>
> +                                DiagnosticsEngine &Diags,<br>
> +                                IntrusiveRefCntPtr<vfs::<wbr>FileSystem> BaseFS) {<br>
>    if (CI.getHeaderSearchOpts().<wbr>VFSOverlayFiles.empty())<br>
> -    return vfs::getRealFileSystem();<br>
> +    return BaseFS;<br>
><br>
> -  IntrusiveRefCntPtr<vfs::<wbr>OverlayFileSystem><br>
> -    Overlay(new vfs::OverlayFileSystem(vfs::<wbr>getRealFileSystem()));<br>
> +  IntrusiveRefCntPtr<vfs::<wbr>OverlayFileSystem> Overlay(<br>
> +      new vfs::OverlayFileSystem(BaseFS)<wbr>);<br>
>    // earlier vfs files are on the bottom<br>
>    for (const std::string &File : CI.getHeaderSearchOpts().<wbr>VFSOverlayFiles) {<br>
>      llvm::ErrorOr<std::unique_ptr<<wbr>llvm::MemoryBuffer>> Buffer =<br>
> -        llvm::MemoryBuffer::getFile(<wbr>File);<br>
> +        BaseFS->getBufferForFile(File)<wbr>;<br>
>      if (!Buffer) {<br>
>        Diags.Report(diag::err_<wbr>missing_vfs_overlay_file) << File;<br>
>        return IntrusiveRefCntPtr<vfs::<wbr>FileSystem>();<br>
><br>
><br>
> ______________________________<wbr>_________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
<br>
<br>
<br>
</div></div><span class="HOEnZb"><font color="#888888">--<br>
Bruno Cardoso Lopes<br>
<a href="http://www.brunocardoso.cc" rel="noreferrer" target="_blank">http://www.brunocardoso.cc</a><br>
</font></span></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div>Regards,</div><div>Ilya Biryukov</div></div></div></div></div>
</div>