<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>