<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Fixed in r298414.<div class=""><br class=""><div class=""><div><blockquote type="cite" class=""><div class="">On 2017-Mar-21, at 11:26, Duncan P. N. Exon Smith via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org" class="">cfe-commits@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Looking.<div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On 2017-Mar-21, at 11:25, Russell Gallop <<a href="mailto:russell.gallop@gmail.com" class="">russell.gallop@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><span style="font-size:12.8px" class="">The unit test "MemoryBufferCacheTest.</span><wbr style="font-size:12.8px" class=""><span style="font-size:12.8px" class="">addBuffer" seems to be intermittently failing on Windows. I can see this on the buildbot:</span><div style="font-size:12.8px" class=""><a href="http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast/builds/7086/steps/test/logs/stdio" target="_blank" class="">http://lab.llvm.org:8011/<wbr class="">builders/llvm-clang-lld-x86_<wbr class="">64-scei-ps4-windows10pro-fast/<wbr class="">builds/7086/steps/test/logs/<wbr class="">stdio</a><br class=""><div class=""><br class=""></div><div class="">Please could you take a look?</div><div class=""><br class=""></div><div class="">Thanks</div><div class="">Russ<br class=""><div class=""><br class=""></div><div class=""><div class="">Note: Google Test filter = MemoryBufferCacheTest.<wbr class="">addBuffer</div><div class="">[==========] Running 1 test from 1 test case.</div><div class="">[----------] Global test environment set-up.</div><div class="">[----------] 1 test from MemoryBufferCacheTest</div><div class="">[ RUN      ] MemoryBufferCacheTest.<wbr class="">addBuffer</div><div class=""><snip>\llvm\tools\clang\<wbr class="">unittests\Basic\<wbr class="">MemoryBufferCacheTest.cpp(53): error: Expected: (RawB2) != (B2.get()), actual: 000000075B1FDB50 vs 000000075B1FDB50</div><div class="">[  FAILED  ] MemoryBufferCacheTest.<wbr class="">addBuffer (1 ms)</div><div class="">[----------] 1 test from MemoryBufferCacheTest (1 ms total)</div><div class=""><br class=""></div><div class="">[----------] Global test environment tear-down</div><div class="">[==========] 1 test from 1 test case ran. (1 ms total)</div><div class="">[  PASSED  ] 0 tests.</div><div class="">[  FAILED  ] 1 test, listed below:</div><div class="">[  FAILED  ] MemoryBufferCacheTest.<wbr class="">addBuffer</div><div class=""><br class=""></div><div class=""> 1 FAILED TEST</div></div></div></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On 20 March 2017 at 17:58, Duncan P. N. Exon Smith via cfe-commits <span dir="ltr" class=""><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank" class="">cfe-commits@lists.llvm.org</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: dexonsmith<br class="">
Date: Mon Mar 20 12:58:26 2017<br class="">
New Revision: 298278<br class="">
<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=298278&view=rev" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project?rev=298278&view=rev</a><br class="">
Log:<br class="">
Reapply "Modules: Cache PCMs in memory and avoid a use-after-free"<br class="">
<br class="">
This reverts commit r298185, effectively reapplying r298165, after fixing the<br class="">
new unit tests (PR32338).  The memory buffer generator doesn't null-terminate<br class="">
the MemoryBuffer it creates; this version of the commit informs getMemBuffer<br class="">
about that to avoid the assert.<br class="">
<br class="">
Original commit message follows:<br class="">
<br class="">
----<br class="">
<br class="">
Clang's internal build system for implicit modules uses lock files to<br class="">
ensure that after a process writes a PCM it will read the same one back<br class="">
in (without contention from other -cc1 commands).  Since PCMs are read<br class="">
from disk repeatedly while invalidating, building, and importing, the<br class="">
lock is not released quickly.  Furthermore, the LockFileManager is not<br class="">
robust in every environment.  Other -cc1 commands can stall until<br class="">
timeout (after about eight minutes).<br class="">
<br class="">
This commit changes the lock file from being necessary for correctness<br class="">
to a (possibly dubious) performance hack.  The remaining benefit is to<br class="">
reduce duplicate work in competing -cc1 commands which depend on the<br class="">
same module.  Follow-up commits will change the internal build system to<br class="">
continue after a timeout, and reduce the timeout.  Perhaps we should<br class="">
reconsider blocking at all.<br class="">
<br class="">
This also fixes a use-after-free, when one part of a compilation<br class="">
validates a PCM and starts using it, and another tries to swap out the<br class="">
PCM for something new.<br class="">
<br class="">
The PCMCache is a new type called MemoryBufferCache, which saves memory<br class="">
buffers based on their filename.  Its ownership is shared by the<br class="">
CompilerInstance and ModuleManager.<br class="">
<br class="">
- The ModuleManager stores PCMs there that it loads from disk, never<br class="">
touching the disk if the cache is hot.<br class="">
<br class="">
- When modules fail to validate, they're removed from the cache.<br class="">
<br class="">
- When a CompilerInstance is spawned to build a new module, each<br class="">
already-loaded PCM is assumed to be valid, and is frozen to avoid<br class="">
the use-after-free.<br class="">
<br class="">
- Any newly-built module is written directly to the cache to avoid the<br class="">
round-trip to the filesystem, making lock files unnecessary for<br class="">
correctness.<br class="">
<br class="">
Original patch by Manman Ren; most testcases by Adrian Prantl!<br class="">
<br class="">
Added:<br class="">
    cfe/trunk/include/clang/Basic/<wbr class="">MemoryBufferCache.h<br class="">
    cfe/trunk/lib/Basic/<wbr class="">MemoryBufferCache.cpp<br class="">
    cfe/trunk/test/Modules/Inputs/<wbr class="">system-out-of-date/X.h<br class="">
    cfe/trunk/test/Modules/Inputs/<wbr class="">system-out-of-date/Y.h<br class="">
    cfe/trunk/test/Modules/Inputs/<wbr class="">system-out-of-date/Z.h<br class="">
    cfe/trunk/test/Modules/Inputs/<wbr class="">system-out-of-date/module.map<br class="">
    cfe/trunk/test/Modules/Inputs/<wbr class="">warning-mismatch/Mismatch.h<br class="">
    cfe/trunk/test/Modules/Inputs/<wbr class="">warning-mismatch/System.h<br class="">
    cfe/trunk/test/Modules/Inputs/<wbr class="">warning-mismatch/module.<wbr class="">modulemap<br class="">
    cfe/trunk/test/Modules/<wbr class="">outofdate-rebuild.m<br class="">
    cfe/trunk/test/Modules/system-<wbr class="">out-of-date-test.m<br class="">
    cfe/trunk/test/Modules/<wbr class="">warning-mismatch.m<br class="">
    cfe/trunk/unittests/Basic/<wbr class="">MemoryBufferCacheTest.cpp<br class="">
Modified:<br class="">
    cfe/trunk/include/clang/Basic/<wbr class="">DiagnosticSerializationKinds.<wbr class="">td<br class="">
    cfe/trunk/include/clang/<wbr class="">Frontend/ASTUnit.h<br class="">
    cfe/trunk/include/clang/<wbr class="">Frontend/CompilerInstance.h<br class="">
    cfe/trunk/include/clang/Lex/<wbr class="">Preprocessor.h<br class="">
    cfe/trunk/include/clang/<wbr class="">Serialization/ASTReader.h<br class="">
    cfe/trunk/include/clang/<wbr class="">Serialization/ASTWriter.h<br class="">
    cfe/trunk/include/clang/<wbr class="">Serialization/Module.h<br class="">
    cfe/trunk/include/clang/<wbr class="">Serialization/ModuleManager.h<br class="">
    cfe/trunk/lib/Basic/<wbr class="">CMakeLists.txt<br class="">
    cfe/trunk/lib/Frontend/<wbr class="">ASTUnit.cpp<br class="">
    cfe/trunk/lib/Frontend/<wbr class="">CompilerInstance.cpp<br class="">
    cfe/trunk/lib/Lex/<wbr class="">Preprocessor.cpp<br class="">
    cfe/trunk/lib/Serialization/<wbr class="">ASTReader.cpp<br class="">
    cfe/trunk/lib/Serialization/<wbr class="">ASTWriter.cpp<br class="">
    cfe/trunk/lib/Serialization/<wbr class="">GeneratePCH.cpp<br class="">
    cfe/trunk/lib/Serialization/<wbr class="">ModuleManager.cpp<br class="">
    cfe/trunk/unittests/Basic/<wbr class="">CMakeLists.txt<br class="">
    cfe/trunk/unittests/Basic/<wbr class="">SourceManagerTest.cpp<br class="">
    cfe/trunk/unittests/Lex/<wbr class="">LexerTest.cpp<br class="">
    cfe/trunk/unittests/Lex/<wbr class="">PPCallbacksTest.cpp<br class="">
    cfe/trunk/unittests/Lex/<wbr class="">PPConditionalDirectiveRecordTe<wbr class="">st.cpp<br class="">
<br class="">
Modified: cfe/trunk/include/clang/Basic/<wbr class="">DiagnosticSerializationKinds.<wbr class="">td<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td?rev=298278&r1=298277&r2=298278&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/include/<wbr class="">clang/Basic/<wbr class="">DiagnosticSerializationKinds.<wbr class="">td?rev=298278&r1=298277&r2=<wbr class="">298278&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/include/clang/Basic/<wbr class="">DiagnosticSerializationKinds.<wbr class="">td (original)<br class="">
+++ cfe/trunk/include/clang/Basic/<wbr class="">DiagnosticSerializationKinds.<wbr class="">td Mon Mar 20 12:58:26 2017<br class="">
@@ -176,6 +176,11 @@ def warn_duplicate_module_file_<wbr class="">extension<br class="">
   "duplicate module file extension block name '%0'">,<br class="">
   InGroup<ModuleFileExtension>;<br class="">
<br class="">
+def warn_module_system_bit_<wbr class="">conflict : Warning<<br class="">
+  "module file '%0' was validated as a system module and is now being imported "<br class="">
+  "as a non-system module; any difference in diagnostic options will be ignored">,<br class="">
+  InGroup<ModuleConflict>;<br class="">
+<br class="">
 } // let CategoryName<br class="">
 } // let Component<br class="">
<br class="">
<br class="">
Added: cfe/trunk/include/clang/Basic/<wbr class="">MemoryBufferCache.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/MemoryBufferCache.h?rev=298278&view=auto" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/include/<wbr class="">clang/Basic/MemoryBufferCache.<wbr class="">h?rev=298278&view=auto</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/include/clang/Basic/<wbr class="">MemoryBufferCache.h (added)<br class="">
+++ cfe/trunk/include/clang/Basic/<wbr class="">MemoryBufferCache.h Mon Mar 20 12:58:26 2017<br class="">
@@ -0,0 +1,80 @@<br class="">
+//===- MemoryBufferCache.h - Cache for loaded memory buffers ----*- C++ -*-===//<br class="">
+//<br class="">
+//                     The LLVM Compiler Infrastructure<br class="">
+//<br class="">
+// This file is distributed under the University of Illinois Open Source<br class="">
+// License. See LICENSE.TXT for details.<br class="">
+//<br class="">
+//===------------------------<wbr class="">------------------------------<wbr class="">----------------===//<br class="">
+<br class="">
+#ifndef LLVM_CLANG_BASIC_<wbr class="">MEMORYBUFFERCACHE_H<br class="">
+#define LLVM_CLANG_BASIC_<wbr class="">MEMORYBUFFERCACHE_H<br class="">
+<br class="">
+#include "llvm/ADT/IntrusiveRefCntPtr.<wbr class="">h"<br class="">
+#include "llvm/ADT/StringMap.h"<br class="">
+#include <memory><br class="">
+<br class="">
+namespace llvm {<br class="">
+class MemoryBuffer;<br class="">
+} // end namespace llvm<br class="">
+<br class="">
+namespace clang {<br class="">
+<br class="">
+/// Manage memory buffers across multiple users.<br class="">
+///<br class="">
+/// Ensures that multiple users have a consistent view of each buffer.  This is<br class="">
+/// used by \a CompilerInstance when building PCMs to ensure that each \a<br class="">
+/// ModuleManager sees the same files.<br class="">
+///<br class="">
+/// \a finalizeCurrentBuffers() should be called before creating a new user.<br class="">
+/// This locks in the current buffers, ensuring that no buffer that has already<br class="">
+/// been accessed can be purged, preventing use-after-frees.<br class="">
+class MemoryBufferCache : public llvm::RefCountedBase<<wbr class="">MemoryBufferCache> {<br class="">
+  struct BufferEntry {<br class="">
+    std::unique_ptr<llvm::<wbr class="">MemoryBuffer> Buffer;<br class="">
+<br class="">
+    /// Track the timeline of when this was added to the cache.<br class="">
+    unsigned Index;<br class="">
+  };<br class="">
+<br class="">
+  /// Cache of buffers.<br class="">
+  llvm::StringMap<BufferEntry> Buffers;<br class="">
+<br class="">
+  /// Monotonically increasing index.<br class="">
+  unsigned NextIndex = 0;<br class="">
+<br class="">
+  /// Bumped to prevent "older" buffers from being removed.<br class="">
+  unsigned FirstRemovableIndex = 0;<br class="">
+<br class="">
+public:<br class="">
+  /// Store the Buffer under the Filename.<br class="">
+  ///<br class="">
+  /// \pre There is not already buffer is not already in the cache.<br class="">
+  /// \return a reference to the buffer as a convenience.<br class="">
+  llvm::MemoryBuffer &addBuffer(llvm::StringRef Filename,<br class="">
+                                std::unique_ptr<llvm::<wbr class="">MemoryBuffer> Buffer);<br class="">
+<br class="">
+  /// Try to remove a buffer from the cache.<br class="">
+  ///<br class="">
+  /// \return false on success, iff \c !isBufferFinal().<br class="">
+  bool tryToRemoveBuffer(llvm::<wbr class="">StringRef Filename);<br class="">
+<br class="">
+  /// Get a pointer to the buffer if it exists; else nullptr.<br class="">
+  llvm::MemoryBuffer *lookupBuffer(llvm::StringRef Filename);<br class="">
+<br class="">
+  /// Check whether the buffer is final.<br class="">
+  ///<br class="">
+  /// \return true iff \a finalizeCurrentBuffers() has been called since the<br class="">
+  /// buffer was added.  This prevents buffers from being removed.<br class="">
+  bool isBufferFinal(llvm::StringRef Filename);<br class="">
+<br class="">
+  /// Finalize the current buffers in the cache.<br class="">
+  ///<br class="">
+  /// Should be called when creating a new user to ensure previous uses aren't<br class="">
+  /// invalidated.<br class="">
+  void finalizeCurrentBuffers();<br class="">
+};<br class="">
+<br class="">
+} // end namespace clang<br class="">
+<br class="">
+#endif // LLVM_CLANG_BASIC_<wbr class="">MEMORYBUFFERCACHE_H<br class="">
<br class="">
Modified: cfe/trunk/include/clang/<wbr class="">Frontend/ASTUnit.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/ASTUnit.h?rev=298278&r1=298277&r2=298278&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/include/<wbr class="">clang/Frontend/ASTUnit.h?rev=<wbr class="">298278&r1=298277&r2=298278&<wbr class="">view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/include/clang/<wbr class="">Frontend/ASTUnit.h (original)<br class="">
+++ cfe/trunk/include/clang/<wbr class="">Frontend/ASTUnit.h Mon Mar 20 12:58:26 2017<br class="">
@@ -51,6 +51,7 @@ class DiagnosticsEngine;<br class="">
 class FileEntry;<br class="">
 class FileManager;<br class="">
 class HeaderSearch;<br class="">
+class MemoryBufferCache;<br class="">
 class Preprocessor;<br class="">
 class PCHContainerOperations;<br class="">
 class PCHContainerReader;<br class="">
@@ -84,6 +85,7 @@ private:<br class="">
   IntrusiveRefCntPtr<<wbr class="">DiagnosticsEngine>   Diagnostics;<br class="">
   IntrusiveRefCntPtr<<wbr class="">FileManager>         FileMgr;<br class="">
   IntrusiveRefCntPtr<<wbr class="">SourceManager>       SourceMgr;<br class="">
+  IntrusiveRefCntPtr<<wbr class="">MemoryBufferCache>   PCMCache;<br class="">
   std::unique_ptr<HeaderSearch>           HeaderInfo;<br class="">
   IntrusiveRefCntPtr<TargetInfo>          Target;<br class="">
   std::shared_ptr<Preprocessor>           PP;<br class="">
<br class="">
Modified: cfe/trunk/include/clang/<wbr class="">Frontend/CompilerInstance.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CompilerInstance.h?rev=298278&r1=298277&r2=298278&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/include/<wbr class="">clang/Frontend/<wbr class="">CompilerInstance.h?rev=298278&<wbr class="">r1=298277&r2=298278&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/include/clang/<wbr class="">Frontend/CompilerInstance.h (original)<br class="">
+++ cfe/trunk/include/clang/<wbr class="">Frontend/CompilerInstance.h Mon Mar 20 12:58:26 2017<br class="">
@@ -44,6 +44,7 @@ class ExternalASTSource;<br class="">
 class FileEntry;<br class="">
 class FileManager;<br class="">
 class FrontendAction;<br class="">
+class MemoryBufferCache;<br class="">
 class Module;<br class="">
 class Preprocessor;<br class="">
 class Sema;<br class="">
@@ -90,6 +91,9 @@ class CompilerInstance : public ModuleLo<br class="">
   /// The source manager.<br class="">
   IntrusiveRefCntPtr<<wbr class="">SourceManager> SourceMgr;<br class="">
<br class="">
+  /// The cache of PCM files.<br class="">
+  IntrusiveRefCntPtr<<wbr class="">MemoryBufferCache> PCMCache;<br class="">
+<br class="">
   /// The preprocessor.<br class="">
   std::shared_ptr<Preprocessor> PP;<br class="">
<br class="">
@@ -178,7 +182,7 @@ public:<br class="">
   explicit CompilerInstance(<br class="">
       std::shared_ptr<<wbr class="">PCHContainerOperations> PCHContainerOps =<br class="">
           std::make_shared<<wbr class="">PCHContainerOperations>(),<br class="">
-      bool BuildingModule = false);<br class="">
+      MemoryBufferCache *SharedPCMCache = nullptr);<br class="">
   ~CompilerInstance() override;<br class="">
<br class="">
   /// @name High-Level Operations<br class="">
@@ -783,6 +787,8 @@ public:<br class="">
   }<br class="">
<br class="">
   void setExternalSemaSource(<wbr class="">IntrusiveRefCntPtr<<wbr class="">ExternalSemaSource> ESS);<br class="">
+<br class="">
+  MemoryBufferCache &getPCMCache() const { return *PCMCache; }<br class="">
 };<br class="">
<br class="">
 } // end namespace clang<br class="">
<br class="">
Modified: cfe/trunk/include/clang/Lex/<wbr class="">Preprocessor.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=298278&r1=298277&r2=298278&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/include/<wbr class="">clang/Lex/Preprocessor.h?rev=<wbr class="">298278&r1=298277&r2=298278&<wbr class="">view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/include/clang/Lex/<wbr class="">Preprocessor.h (original)<br class="">
+++ cfe/trunk/include/clang/Lex/<wbr class="">Preprocessor.h Mon Mar 20 12:58:26 2017<br class="">
@@ -47,6 +47,7 @@ class ExternalPreprocessorSource;<br class="">
 class FileManager;<br class="">
 class FileEntry;<br class="">
 class HeaderSearch;<br class="">
+class MemoryBufferCache;<br class="">
 class PragmaNamespace;<br class="">
 class PragmaHandler;<br class="">
 class CommentHandler;<br class="">
@@ -102,6 +103,7 @@ class Preprocessor {<br class="">
   const TargetInfo  *AuxTarget;<br class="">
   FileManager       &FileMgr;<br class="">
   SourceManager     &SourceMgr;<br class="">
+  MemoryBufferCache &PCMCache;<br class="">
   std::unique_ptr<ScratchBuffer> ScratchBuf;<br class="">
   HeaderSearch      &HeaderInfo;<br class="">
   ModuleLoader      &TheModuleLoader;<br class="">
@@ -652,6 +654,7 @@ class Preprocessor {<br class="">
 public:<br class="">
   Preprocessor(std::shared_ptr<<wbr class="">PreprocessorOptions> PPOpts,<br class="">
                DiagnosticsEngine &diags, LangOptions &opts, SourceManager &SM,<br class="">
+               MemoryBufferCache &PCMCache,<br class="">
                HeaderSearch &Headers, ModuleLoader &TheModuleLoader,<br class="">
                IdentifierInfoLookup *IILookup = nullptr,<br class="">
                bool OwnsHeaderSearch = false,<br class="">
@@ -691,6 +694,7 @@ public:<br class="">
   const TargetInfo *getAuxTargetInfo() const { return AuxTarget; }<br class="">
   FileManager &getFileManager() const { return FileMgr; }<br class="">
   SourceManager &getSourceManager() const { return SourceMgr; }<br class="">
+  MemoryBufferCache &getPCMCache() const { return PCMCache; }<br class="">
   HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; }<br class="">
<br class="">
   IdentifierTable &getIdentifierTable() { return Identifiers; }<br class="">
<br class="">
Modified: cfe/trunk/include/clang/<wbr class="">Serialization/ASTReader.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=298278&r1=298277&r2=298278&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/include/<wbr class="">clang/Serialization/ASTReader.<wbr class="">h?rev=298278&r1=298277&r2=<wbr class="">298278&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/include/clang/<wbr class="">Serialization/ASTReader.h (original)<br class="">
+++ cfe/trunk/include/clang/<wbr class="">Serialization/ASTReader.h Mon Mar 20 12:58:26 2017<br class="">
@@ -408,6 +408,9 @@ private:<br class="">
   /// \brief The module manager which manages modules and their dependencies<br class="">
   ModuleManager ModuleMgr;<br class="">
<br class="">
+  /// The cache that manages memory buffers for PCM files.<br class="">
+  MemoryBufferCache &PCMCache;<br class="">
+<br class="">
   /// \brief A dummy identifier resolver used to merge TU-scope declarations in<br class="">
   /// C, for the cases where we don't have a Sema object to provide a real<br class="">
   /// identifier resolver.<br class="">
<br class="">
Modified: cfe/trunk/include/clang/<wbr class="">Serialization/ASTWriter.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=298278&r1=298277&r2=298278&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/include/<wbr class="">clang/Serialization/ASTWriter.<wbr class="">h?rev=298278&r1=298277&r2=<wbr class="">298278&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/include/clang/<wbr class="">Serialization/ASTWriter.h (original)<br class="">
+++ cfe/trunk/include/clang/<wbr class="">Serialization/ASTWriter.h Mon Mar 20 12:58:26 2017<br class="">
@@ -54,6 +54,7 @@ class MacroInfo;<br class="">
 class OpaqueValueExpr;<br class="">
 class OpenCLOptions;<br class="">
 class ASTReader;<br class="">
+class MemoryBufferCache;<br class="">
 class Module;<br class="">
 class ModuleFileExtension;<br class="">
 class ModuleFileExtensionWriter;<br class="">
@@ -109,6 +110,9 @@ private:<br class="">
   /// The buffer associated with the bitstream.<br class="">
   const SmallVectorImpl<char> &Buffer;<br class="">
<br class="">
+  /// \brief The PCM manager which manages memory buffers for pcm files.<br class="">
+  MemoryBufferCache &PCMCache;<br class="">
+<br class="">
   /// \brief The ASTContext we're writing.<br class="">
   ASTContext *Context = nullptr;<br class="">
<br class="">
@@ -512,6 +516,7 @@ public:<br class="">
   /// \brief Create a new precompiled header writer that outputs to<br class="">
   /// the given bitstream.<br class="">
   ASTWriter(llvm::<wbr class="">BitstreamWriter &Stream, SmallVectorImpl<char> &Buffer,<br class="">
+            MemoryBufferCache &PCMCache,<br class="">
             ArrayRef<std::shared_ptr<<wbr class="">ModuleFileExtension>> Extensions,<br class="">
             bool IncludeTimestamps = true);<br class="">
   ~ASTWriter() override;<br class="">
<br class="">
Modified: cfe/trunk/include/clang/<wbr class="">Serialization/Module.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/Module.h?rev=298278&r1=298277&r2=298278&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/include/<wbr class="">clang/Serialization/Module.h?<wbr class="">rev=298278&r1=298277&r2=<wbr class="">298278&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/include/clang/<wbr class="">Serialization/Module.h (original)<br class="">
+++ cfe/trunk/include/clang/<wbr class="">Serialization/Module.h Mon Mar 20 12:58:26 2017<br class="">
@@ -163,9 +163,9 @@ public:<br class="">
   /// \brief The generation of which this module file is a part.<br class="">
   unsigned Generation;<br class="">
<br class="">
-  /// \brief The memory buffer that stores the data associated with<br class="">
-  /// this AST file.<br class="">
-  std::unique_ptr<llvm::<wbr class="">MemoryBuffer> Buffer;<br class="">
+  /// The memory buffer that stores the data associated with<br class="">
+  /// this AST file, owned by the PCMCache in the ModuleManager.<br class="">
+  llvm::MemoryBuffer *Buffer;<br class="">
<br class="">
   /// \brief The size of this file, in bits.<br class="">
   uint64_t SizeInBits = 0;<br class="">
<br class="">
Modified: cfe/trunk/include/clang/<wbr class="">Serialization/ModuleManager.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ModuleManager.h?rev=298278&r1=298277&r2=298278&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/include/<wbr class="">clang/Serialization/<wbr class="">ModuleManager.h?rev=298278&r1=<wbr class="">298277&r2=298278&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/include/clang/<wbr class="">Serialization/ModuleManager.h (original)<br class="">
+++ cfe/trunk/include/clang/<wbr class="">Serialization/ModuleManager.h Mon Mar 20 12:58:26 2017<br class="">
@@ -24,6 +24,7 @@<br class="">
 namespace clang {<br class="">
<br class="">
 class GlobalModuleIndex;<br class="">
+class MemoryBufferCache;<br class="">
 class ModuleMap;<br class="">
 class PCHContainerReader;<br class="">
<br class="">
@@ -51,6 +52,9 @@ class ModuleManager {<br class="">
   /// FileEntry *.<br class="">
   FileManager &FileMgr;<br class="">
<br class="">
+  /// Cache of PCM files.<br class="">
+  IntrusiveRefCntPtr<<wbr class="">MemoryBufferCache> PCMCache;<br class="">
+<br class="">
   /// \brief Knows how to unwrap module containers.<br class="">
   const PCHContainerReader &PCHContainerRdr;<br class="">
<br class="">
@@ -123,7 +127,7 @@ public:<br class="">
       ModuleReverseIterator;<br class="">
   typedef std::pair<uint32_t, StringRef> ModuleOffset;<br class="">
<br class="">
-  explicit ModuleManager(FileManager &FileMgr,<br class="">
+  explicit ModuleManager(FileManager &FileMgr, MemoryBufferCache &PCMCache,<br class="">
                          const PCHContainerReader &PCHContainerRdr);<br class="">
   ~ModuleManager();<br class="">
<br class="">
@@ -290,6 +294,8 @@ public:<br class="">
<br class="">
   /// \brief View the graphviz representation of the module graph.<br class="">
   void viewGraph();<br class="">
+<br class="">
+  MemoryBufferCache &getPCMCache() const { return *PCMCache; }<br class="">
 };<br class="">
<br class="">
 } } // end namespace clang::serialization<br class="">
<br class="">
Modified: cfe/trunk/lib/Basic/<wbr class="">CMakeLists.txt<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/CMakeLists.txt?rev=298278&r1=298277&r2=298278&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/Basic/<wbr class="">CMakeLists.txt?rev=298278&r1=<wbr class="">298277&r2=298278&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/Basic/<wbr class="">CMakeLists.txt (original)<br class="">
+++ cfe/trunk/lib/Basic/<wbr class="">CMakeLists.txt Mon Mar 20 12:58:26 2017<br class="">
@@ -74,6 +74,7 @@ add_clang_library(clangBasic<br class="">
   FileSystemStatCache.cpp<br class="">
   IdentifierTable.cpp<br class="">
   LangOptions.cpp<br class="">
+  MemoryBufferCache.cpp<br class="">
   Module.cpp<br class="">
   ObjCRuntime.cpp<br class="">
   OpenMPKinds.cpp<br class="">
<br class="">
Added: cfe/trunk/lib/Basic/<wbr class="">MemoryBufferCache.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/MemoryBufferCache.cpp?rev=298278&view=auto" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/Basic/<wbr class="">MemoryBufferCache.cpp?rev=<wbr class="">298278&view=auto</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/Basic/<wbr class="">MemoryBufferCache.cpp (added)<br class="">
+++ cfe/trunk/lib/Basic/<wbr class="">MemoryBufferCache.cpp Mon Mar 20 12:58:26 2017<br class="">
@@ -0,0 +1,48 @@<br class="">
+//===- MemoryBufferCache.cpp - Cache for loaded memory buffers ------------===//<br class="">
+//<br class="">
+//                     The LLVM Compiler Infrastructure<br class="">
+//<br class="">
+// This file is distributed under the University of Illinois Open Source<br class="">
+// License. See LICENSE.TXT for details.<br class="">
+//<br class="">
+//===------------------------<wbr class="">------------------------------<wbr class="">----------------===//<br class="">
+<br class="">
+#include "clang/Basic/<wbr class="">MemoryBufferCache.h"<br class="">
+#include "llvm/Support/MemoryBuffer.h"<br class="">
+<br class="">
+using namespace clang;<br class="">
+<br class="">
+llvm::MemoryBuffer &<br class="">
+MemoryBufferCache::addBuffer(<wbr class="">llvm::StringRef Filename,<br class="">
+                             std::unique_ptr<llvm::<wbr class="">MemoryBuffer> Buffer) {<br class="">
+  auto Insertion =<br class="">
+      Buffers.insert({Filename, BufferEntry{std::move(Buffer), NextIndex++}});<br class="">
+  assert(Insertion.second && "Already has a buffer");<br class="">
+  return *Insertion.first->second.<wbr class="">Buffer;<br class="">
+}<br class="">
+<br class="">
+llvm::MemoryBuffer *MemoryBufferCache::<wbr class="">lookupBuffer(llvm::StringRef Filename) {<br class="">
+  auto I = Buffers.find(Filename);<br class="">
+  if (I == Buffers.end())<br class="">
+    return nullptr;<br class="">
+  return I->second.Buffer.get();<br class="">
+}<br class="">
+<br class="">
+bool MemoryBufferCache::<wbr class="">isBufferFinal(llvm::StringRef Filename) {<br class="">
+  auto I = Buffers.find(Filename);<br class="">
+  if (I == Buffers.end())<br class="">
+    return false;<br class="">
+  return I->second.Index < FirstRemovableIndex;<br class="">
+}<br class="">
+<br class="">
+bool MemoryBufferCache::<wbr class="">tryToRemoveBuffer(llvm::<wbr class="">StringRef Filename) {<br class="">
+  auto I = Buffers.find(Filename);<br class="">
+  assert(I != Buffers.end() && "No buffer to remove...");<br class="">
+  if (I->second.Index < FirstRemovableIndex)<br class="">
+    return true;<br class="">
+<br class="">
+  Buffers.erase(I);<br class="">
+  return false;<br class="">
+}<br class="">
+<br class="">
+void MemoryBufferCache::<wbr class="">finalizeCurrentBuffers() { FirstRemovableIndex = NextIndex; }<br class="">
<br class="">
Modified: cfe/trunk/lib/Frontend/<wbr class="">ASTUnit.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=298278&r1=298277&r2=298278&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/<wbr class="">Frontend/ASTUnit.cpp?rev=<wbr class="">298278&r1=298277&r2=298278&<wbr class="">view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/Frontend/<wbr class="">ASTUnit.cpp (original)<br class="">
+++ cfe/trunk/lib/Frontend/<wbr class="">ASTUnit.cpp Mon Mar 20 12:58:26 2017<br class="">
@@ -18,6 +18,7 @@<br class="">
 #include "clang/AST/StmtVisitor.h"<br class="">
 #include "clang/AST/TypeOrdering.h"<br class="">
 #include "clang/Basic/Diagnostic.h"<br class="">
+#include "clang/Basic/<wbr class="">MemoryBufferCache.h"<br class="">
 #include "clang/Basic/TargetInfo.h"<br class="">
 #include "clang/Basic/TargetOptions.h"<br class="">
 #include "clang/Basic/<wbr class="">VirtualFileSystem.h"<br class="">
@@ -185,7 +186,8 @@ struct ASTUnit::ASTWriterData {<br class="">
   llvm::BitstreamWriter Stream;<br class="">
   ASTWriter Writer;<br class="">
<br class="">
-  ASTWriterData() : Stream(Buffer), Writer(Stream, Buffer, {}) {}<br class="">
+  ASTWriterData(<wbr class="">MemoryBufferCache &PCMCache)<br class="">
+      : Stream(Buffer), Writer(Stream, Buffer, PCMCache, {}) {}<br class="">
 };<br class="">
<br class="">
 void ASTUnit::clearFileLevelDecls() {<br class="">
@@ -681,6 +683,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFr<br class="">
   AST->SourceMgr = new SourceManager(AST-><wbr class="">getDiagnostics(),<br class="">
                                      AST->getFileManager(),<br class="">
                                      UserFilesAreVolatile);<br class="">
+  AST->PCMCache = new MemoryBufferCache;<br class="">
   AST->HSOpts = std::make_shared<<wbr class="">HeaderSearchOptions>();<br class="">
   AST->HSOpts->ModuleFormat = PCHContainerRdr.getFormat();<br class="">
   AST->HeaderInfo.reset(new HeaderSearch(AST->HSOpts,<br class="">
@@ -701,7 +704,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFr<br class="">
<br class="">
   AST->PP = std::make_shared<Preprocessor><wbr class="">(<br class="">
       std::move(PPOpts), AST->getDiagnostics(), AST->ASTFileLangOpts,<br class="">
-      AST->getSourceManager(), HeaderInfo, *AST,<br class="">
+      AST->getSourceManager(), *AST->PCMCache, HeaderInfo, *AST,<br class="">
       /*IILookup=*/nullptr,<br class="">
       /*OwnsHeaderSearch=*/false);<br class="">
   Preprocessor &PP = *AST->PP;<br class="">
@@ -1727,6 +1730,7 @@ ASTUnit::create(std::shared_<wbr class="">ptr<Compiler<br class="">
   AST->UserFilesAreVolatile = UserFilesAreVolatile;<br class="">
   AST->SourceMgr = new SourceManager(AST-><wbr class="">getDiagnostics(), *AST->FileMgr,<br class="">
                                      UserFilesAreVolatile);<br class="">
+  AST->PCMCache = new MemoryBufferCache;<br class="">
<br class="">
   return AST;<br class="">
 }<br class="">
@@ -1997,6 +2001,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine(<br class="">
   if (!VFS)<br class="">
     return nullptr;<br class="">
   AST->FileMgr = new FileManager(AST-><wbr class="">FileSystemOpts, VFS);<br class="">
+  AST->PCMCache = new MemoryBufferCache;<br class="">
   AST->OnlyLocalDecls = OnlyLocalDecls;<br class="">
   AST->CaptureDiagnostics = CaptureDiagnostics;<br class="">
   AST->TUKind = TUKind;<br class="">
@@ -2008,7 +2013,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine(<br class="">
   AST->StoredDiagnostics.swap(<wbr class="">StoredDiagnostics);<br class="">
   AST->Invocation = CI;<br class="">
   if (ForSerialization)<br class="">
-    AST->WriterData.reset(new ASTWriterData());<br class="">
+    AST->WriterData.reset(new ASTWriterData(*AST->PCMCache))<wbr class="">;<br class="">
   // Zero out now to ease cleanup during crash recovery.<br class="">
   CI = nullptr;<br class="">
   Diags = nullptr;<br class="">
@@ -2523,7 +2528,8 @@ bool ASTUnit::serialize(raw_ostream &OS)<br class="">
<br class="">
   SmallString<128> Buffer;<br class="">
   llvm::BitstreamWriter Stream(Buffer);<br class="">
-  ASTWriter Writer(Stream, Buffer, {});<br class="">
+  MemoryBufferCache PCMCache;<br class="">
+  ASTWriter Writer(Stream, Buffer, PCMCache, {});<br class="">
   return serializeUnit(Writer, Buffer, getSema(), hasErrors, OS);<br class="">
 }<br class="">
<br class="">
<br class="">
Modified: cfe/trunk/lib/Frontend/<wbr class="">CompilerInstance.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=298278&r1=298277&r2=298278&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/<wbr class="">Frontend/CompilerInstance.cpp?<wbr class="">rev=298278&r1=298277&r2=<wbr class="">298278&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/Frontend/<wbr class="">CompilerInstance.cpp (original)<br class="">
+++ cfe/trunk/lib/Frontend/<wbr class="">CompilerInstance.cpp Mon Mar 20 12:58:26 2017<br class="">
@@ -13,6 +13,7 @@<br class="">
 #include "clang/AST/Decl.h"<br class="">
 #include "clang/Basic/Diagnostic.h"<br class="">
 #include "clang/Basic/FileManager.h"<br class="">
+#include "clang/Basic/<wbr class="">MemoryBufferCache.h"<br class="">
 #include "clang/Basic/SourceManager.h"<br class="">
 #include "clang/Basic/TargetInfo.h"<br class="">
 #include "clang/Basic/Version.h"<br class="">
@@ -55,9 +56,15 @@ using namespace clang;<br class="">
<br class="">
 CompilerInstance::<wbr class="">CompilerInstance(<br class="">
     std::shared_ptr<<wbr class="">PCHContainerOperations> PCHContainerOps,<br class="">
-    bool BuildingModule)<br class="">
-    : ModuleLoader(BuildingModule), Invocation(new CompilerInvocation()),<br class="">
-      ThePCHContainerOperations(std:<wbr class="">:move(PCHContainerOps)) {}<br class="">
+    MemoryBufferCache *SharedPCMCache)<br class="">
+    : ModuleLoader(/* BuildingModule = */ SharedPCMCache),<br class="">
+      Invocation(new CompilerInvocation()),<br class="">
+      PCMCache(SharedPCMCache ? SharedPCMCache : new MemoryBufferCache),<br class="">
+      ThePCHContainerOperations(std:<wbr class="">:move(PCHContainerOps)) {<br class="">
+  // Don't allow this to invalidate buffers in use by others.<br class="">
+  if (SharedPCMCache)<br class="">
+    getPCMCache().<wbr class="">finalizeCurrentBuffers();<br class="">
+}<br class="">
<br class="">
 CompilerInstance::~<wbr class="">CompilerInstance() {<br class="">
   assert(OutputFiles.empty() && "Still output files in flight?");<br class="">
@@ -128,6 +135,8 @@ IntrusiveRefCntPtr<ASTReader> CompilerIn<br class="">
   return ModuleManager;<br class="">
 }<br class="">
 void CompilerInstance::<wbr class="">setModuleManager(<wbr class="">IntrusiveRefCntPtr<ASTReader> Reader) {<br class="">
+  assert(PCMCache.get() == &Reader->getModuleManager().<wbr class="">getPCMCache() &&<br class="">
+         "Expected ASTReader to use the same PCM cache");<br class="">
   ModuleManager = std::move(Reader);<br class="">
 }<br class="">
<br class="">
@@ -370,7 +379,7 @@ void CompilerInstance::<wbr class="">createPreprocesso<br class="">
                        getDiagnostics(), getLangOpts(), &getTarget());<br class="">
   PP = std::make_shared<Preprocessor><wbr class="">(<br class="">
       Invocation-><wbr class="">getPreprocessorOptsPtr(), getDiagnostics(), getLangOpts(),<br class="">
-      getSourceManager(), *HeaderInfo, *this, PTHMgr,<br class="">
+      getSourceManager(), getPCMCache(), *HeaderInfo, *this, PTHMgr,<br class="">
       /*OwnsHeaderSearch=*/true, TUKind);<br class="">
   PP->Initialize(getTarget(), getAuxTarget());<br class="">
<br class="">
@@ -1073,9 +1082,11 @@ static bool compileModuleImpl(CompilerIn<br class="">
          Invocation->getModuleHash() && "Module hash mismatch!");<br class="">
<br class="">
   // Construct a compiler instance that will be used to actually create the<br class="">
-  // module.<br class="">
+  // module.  Since we're sharing a PCMCache,<br class="">
+  // CompilerInstance::<wbr class="">CompilerInstance is responsible for finalizing the<br class="">
+  // buffers to prevent use-after-frees.<br class="">
   CompilerInstance Instance(ImportingInstance.<wbr class="">getPCHContainerOperations(),<br class="">
-                            /*BuildingModule=*/true);<br class="">
+                            &ImportingInstance.<wbr class="">getPreprocessor().getPCMCache(<wbr class="">));<br class="">
   auto &Inv = *Invocation;<br class="">
   Instance.setInvocation(std::<wbr class="">move(Invocation));<br class="">
<br class="">
<br class="">
Modified: cfe/trunk/lib/Lex/<wbr class="">Preprocessor.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=298278&r1=298277&r2=298278&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/Lex/<wbr class="">Preprocessor.cpp?rev=298278&<wbr class="">r1=298277&r2=298278&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/Lex/<wbr class="">Preprocessor.cpp (original)<br class="">
+++ cfe/trunk/lib/Lex/<wbr class="">Preprocessor.cpp Mon Mar 20 12:58:26 2017<br class="">
@@ -70,15 +70,15 @@ ExternalPreprocessorSource::~<wbr class="">ExternalPre<br class="">
<br class="">
 Preprocessor::Preprocessor(<wbr class="">std::shared_ptr<<wbr class="">PreprocessorOptions> PPOpts,<br class="">
                            DiagnosticsEngine &diags, LangOptions &opts,<br class="">
-                           SourceManager &SM, HeaderSearch &Headers,<br class="">
-                           ModuleLoader &TheModuleLoader,<br class="">
+                           SourceManager &SM, MemoryBufferCache &PCMCache,<br class="">
+                           HeaderSearch &Headers, ModuleLoader &TheModuleLoader,<br class="">
                            IdentifierInfoLookup *IILookup, bool OwnsHeaders,<br class="">
                            TranslationUnitKind TUKind)<br class="">
     : PPOpts(std::move(PPOpts)), Diags(&diags), LangOpts(opts), Target(nullptr),<br class="">
       AuxTarget(nullptr), FileMgr(Headers.getFileMgr()), SourceMgr(SM),<br class="">
-      ScratchBuf(new ScratchBuffer(SourceMgr)), HeaderInfo(Headers),<br class="">
-      TheModuleLoader(<wbr class="">TheModuleLoader), ExternalSource(nullptr),<br class="">
-      Identifiers(opts, IILookup),<br class="">
+      PCMCache(PCMCache), ScratchBuf(new ScratchBuffer(SourceMgr)),<br class="">
+      HeaderInfo(Headers), TheModuleLoader(<wbr class="">TheModuleLoader),<br class="">
+      ExternalSource(nullptr), Identifiers(opts, IILookup),<br class="">
       PragmaHandlers(new PragmaNamespace(StringRef())),<br class="">
       IncrementalProcessing(false), TUKind(TUKind), CodeComplete(nullptr),<br class="">
       CodeCompletionFile(nullptr), CodeCompletionOffset(0),<br class="">
<br class="">
Modified: cfe/trunk/lib/Serialization/<wbr class="">ASTReader.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=298278&r1=298277&r2=298278&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/<wbr class="">Serialization/ASTReader.cpp?<wbr class="">rev=298278&r1=298277&r2=<wbr class="">298278&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/Serialization/<wbr class="">ASTReader.cpp (original)<br class="">
+++ cfe/trunk/lib/Serialization/<wbr class="">ASTReader.cpp Mon Mar 20 12:58:26 2017<br class="">
@@ -37,6 +37,7 @@<br class="">
 #include "clang/Basic/FileManager.h"<br class="">
 #include "clang/Basic/<wbr class="">FileSystemOptions.h"<br class="">
 #include "clang/Basic/LangOptions.h"<br class="">
+#include "clang/Basic/<wbr class="">MemoryBufferCache.h"<br class="">
 #include "clang/Basic/ObjCRuntime.h"<br class="">
 #include "clang/Basic/OperatorKinds.h"<br class="">
 #include "clang/Basic/Sanitizers.h"<br class="">
@@ -463,19 +464,9 @@ static bool checkDiagnosticMappings(Diag<br class="">
   return checkDiagnosticGroupMappings(<wbr class="">StoredDiags, Diags, Complain);<br class="">
 }<br class="">
<br class="">
-bool PCHValidator::<wbr class="">ReadDiagnosticOptions(<br class="">
-    IntrusiveRefCntPtr<<wbr class="">DiagnosticOptions> DiagOpts, bool Complain) {<br class="">
-  DiagnosticsEngine &ExistingDiags = PP.getDiagnostics();<br class="">
-  IntrusiveRefCntPtr<<wbr class="">DiagnosticIDs> DiagIDs(ExistingDiags.<wbr class="">getDiagnosticIDs());<br class="">
-  IntrusiveRefCntPtr<<wbr class="">DiagnosticsEngine> Diags(<br class="">
-      new DiagnosticsEngine(DiagIDs, DiagOpts.get()));<br class="">
-  // This should never fail, because we would have processed these options<br class="">
-  // before writing them to an ASTFile.<br class="">
-  ProcessWarningOptions(*Diags, *DiagOpts, /*Report*/false);<br class="">
-<br class="">
-  ModuleManager &ModuleMgr = Reader.getModuleManager();<br class="">
-  assert(ModuleMgr.size() >= 1 && "what ASTFile is this then");<br class="">
-<br class="">
+/// Return the top import module if it is implicit, nullptr otherwise.<br class="">
+static Module *getTopImportImplicitModule(<wbr class="">ModuleManager &ModuleMgr,<br class="">
+                                          Preprocessor &PP) {<br class="">
   // If the original import came from a file explicitly generated by the user,<br class="">
   // don't check the diagnostic mappings.<br class="">
   // FIXME: currently this is approximated by checking whether this is not a<br class="">
@@ -487,17 +478,37 @@ bool PCHValidator::<wbr class="">ReadDiagnosticOptions<br class="">
   while (!TopImport->ImportedBy.empty(<wbr class="">))<br class="">
     TopImport = TopImport->ImportedBy[0];<br class="">
   if (TopImport->Kind != MK_ImplicitModule)<br class="">
-    return false;<br class="">
+    return nullptr;<br class="">
<br class="">
   StringRef ModuleName = TopImport->ModuleName;<br class="">
   assert(!ModuleName.empty() && "diagnostic options read before module name");<br class="">
<br class="">
   Module *M = PP.getHeaderSearchInfo().<wbr class="">lookupModule(ModuleName);<br class="">
   assert(M && "missing module");<br class="">
+  return M;<br class="">
+}<br class="">
+<br class="">
+bool PCHValidator::<wbr class="">ReadDiagnosticOptions(<br class="">
+    IntrusiveRefCntPtr<<wbr class="">DiagnosticOptions> DiagOpts, bool Complain) {<br class="">
+  DiagnosticsEngine &ExistingDiags = PP.getDiagnostics();<br class="">
+  IntrusiveRefCntPtr<<wbr class="">DiagnosticIDs> DiagIDs(ExistingDiags.<wbr class="">getDiagnosticIDs());<br class="">
+  IntrusiveRefCntPtr<<wbr class="">DiagnosticsEngine> Diags(<br class="">
+      new DiagnosticsEngine(DiagIDs, DiagOpts.get()));<br class="">
+  // This should never fail, because we would have processed these options<br class="">
+  // before writing them to an ASTFile.<br class="">
+  ProcessWarningOptions(*Diags, *DiagOpts, /*Report*/false);<br class="">
+<br class="">
+  ModuleManager &ModuleMgr = Reader.getModuleManager();<br class="">
+  assert(ModuleMgr.size() >= 1 && "what ASTFile is this then");<br class="">
+<br class="">
+  Module *TopM = getTopImportImplicitModule(<wbr class="">ModuleMgr, PP);<br class="">
+  if (!TopM)<br class="">
+    return false;<br class="">
<br class="">
   // FIXME: if the diagnostics are incompatible, save a DiagnosticOptions that<br class="">
   // contains the union of their flags.<br class="">
-  return checkDiagnosticMappings(*<wbr class="">Diags, ExistingDiags, M->IsSystem, Complain);<br class="">
+  return checkDiagnosticMappings(*<wbr class="">Diags, ExistingDiags, TopM->IsSystem,<br class="">
+                                 Complain);<br class="">
 }<br class="">
<br class="">
 /// \brief Collect the macro definitions provided by the given preprocessor<br class="">
@@ -4064,12 +4075,41 @@ ASTReader::<wbr class="">readUnhashedControlBlock(Modu<br class="">
       Listener.get(),<br class="">
       WasImportedBy ? false : HSOpts.<wbr class="">ModulesValidateDiagnosticOptio<wbr class="">ns);<br class="">
<br class="">
+  // If F was directly imported by another module, it's implicitly validated by<br class="">
+  // the importing module.<br class="">
   if (DisableValidation || WasImportedBy ||<br class="">
       (AllowConfigurationMismatch && Result == ConfigurationMismatch))<br class="">
     return Success;<br class="">
<br class="">
-  if (Result == Failure)<br class="">
+  if (Result == Failure) {<br class="">
     Error("malformed block record in AST file");<br class="">
+    return Failure;<br class="">
+  }<br class="">
+<br class="">
+  if (Result == OutOfDate && F.Kind == MK_ImplicitModule) {<br class="">
+    // If this module has already been finalized in the PCMCache, we're stuck<br class="">
+    // with it; we can only load a single version of each module.<br class="">
+    //<br class="">
+    // This can happen when a module is imported in two contexts: in one, as a<br class="">
+    // user module; in another, as a system module (due to an import from<br class="">
+    // another module marked with the [system] flag).  It usually indicates a<br class="">
+    // bug in the module map: this module should also be marked with [system].<br class="">
+    //<br class="">
+    // If -Wno-system-headers (the default), and the first import is as a<br class="">
+    // system module, then validation will fail during the as-user import,<br class="">
+    // since -Werror flags won't have been validated.  However, it's reasonable<br class="">
+    // to treat this consistently as a system module.<br class="">
+    //<br class="">
+    // If -Wsystem-headers, the PCM on disk was built with<br class="">
+    // -Wno-system-headers, and the first import is as a user module, then<br class="">
+    // validation will fail during the as-system import since the PCM on disk<br class="">
+    // doesn't guarantee that -Werror was respected.  However, the -Werror<br class="">
+    // flags were checked during the initial as-user import.<br class="">
+    if (PCMCache.isBufferFinal(F.<wbr class="">FileName)) {<br class="">
+      Diag(diag::warn_module_system_<wbr class="">bit_conflict) << F.FileName;<br class="">
+      return Success;<br class="">
+    }<br class="">
+  }<br class="">
<br class="">
   return Result;<br class="">
 }<br class="">
@@ -4122,7 +4162,7 @@ ASTReader::ASTReadResult ASTReader::read<br class="">
       if (Listener && ValidateDiagnosticOptions &&<br class="">
           !<wbr class="">AllowCompatibleConfigurationMi<wbr class="">smatch &&<br class="">
           ParseDiagnosticOptions(Record, Complain, *Listener))<br class="">
-        return OutOfDate;<br class="">
+        Result = OutOfDate; // Don't return early.  Read the signature.<br class="">
       break;<br class="">
     }<br class="">
     case DIAG_PRAGMA_MAPPINGS:<br class="">
@@ -7301,7 +7341,7 @@ LLVM_DUMP_METHOD void ASTReader::dump()<br class="">
 /// by heap-backed versus mmap'ed memory.<br class="">
 void ASTReader::<wbr class="">getMemoryBufferSizes(<wbr class="">MemoryBufferSizes &sizes) const {<br class="">
   for (ModuleFile &I : ModuleMgr) {<br class="">
-    if (llvm::MemoryBuffer *buf = I.Buffer.get()) {<br class="">
+    if (llvm::MemoryBuffer *buf = I.Buffer) {<br class="">
       size_t bytes = buf->getBufferSize();<br class="">
       switch (buf->getBufferKind()) {<br class="">
         case llvm::MemoryBuffer::<wbr class="">MemoryBuffer_Malloc:<br class="">
@@ -9628,8 +9668,10 @@ ASTReader::ASTReader(<wbr class="">Preprocessor &PP, A<br class="">
                    : cast<ASTReaderListener>(new PCHValidator(PP, *this))),<br class="">
       SourceMgr(PP.getSourceManager(<wbr class="">)), FileMgr(PP.getFileManager()),<br class="">
       PCHContainerRdr(<wbr class="">PCHContainerRdr), Diags(PP.getDiagnostics()), PP(PP),<br class="">
-      Context(Context), ModuleMgr(PP.getFileManager(), PCHContainerRdr),<br class="">
-      DummyIdResolver(PP), ReadTimer(std::move(ReadTimer)<wbr class="">), isysroot(isysroot),<br class="">
+      Context(Context),<br class="">
+      ModuleMgr(PP.getFileManager(), PP.getPCMCache(), PCHContainerRdr),<br class="">
+      PCMCache(PP.getPCMCache()), DummyIdResolver(PP),<br class="">
+      ReadTimer(std::move(ReadTimer)<wbr class="">), isysroot(isysroot),<br class="">
       DisableValidation(<wbr class="">DisableValidation),<br class="">
       AllowASTWithCompilerErrors(<wbr class="">AllowASTWithCompilerErrors),<br class="">
       AllowConfigurationMismatch(<wbr class="">AllowConfigurationMismatch),<br class="">
<br class="">
Modified: cfe/trunk/lib/Serialization/<wbr class="">ASTWriter.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=298278&r1=298277&r2=298278&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/<wbr class="">Serialization/ASTWriter.cpp?<wbr class="">rev=298278&r1=298277&r2=<wbr class="">298278&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/Serialization/<wbr class="">ASTWriter.cpp (original)<br class="">
+++ cfe/trunk/lib/Serialization/<wbr class="">ASTWriter.cpp Mon Mar 20 12:58:26 2017<br class="">
@@ -35,6 +35,7 @@<br class="">
 #include "clang/Basic/<wbr class="">FileSystemOptions.h"<br class="">
 #include "clang/Basic/LLVM.h"<br class="">
 #include "clang/Basic/LangOptions.h"<br class="">
+#include "clang/Basic/<wbr class="">MemoryBufferCache.h"<br class="">
 #include "clang/Basic/Module.h"<br class="">
 #include "clang/Basic/ObjCRuntime.h"<br class="">
 #include "clang/Basic/SourceManager.h"<br class="">
@@ -4304,10 +4305,11 @@ void ASTWriter::SetSelectorOffset(<wbr class="">Select<br class="">
 }<br class="">
<br class="">
 ASTWriter::ASTWriter(llvm::<wbr class="">BitstreamWriter &Stream,<br class="">
-                     SmallVectorImpl<char> &Buffer,<br class="">
+                     SmallVectorImpl<char> &Buffer, MemoryBufferCache &PCMCache,<br class="">
                      ArrayRef<std::shared_ptr<<wbr class="">ModuleFileExtension>> Extensions,<br class="">
                      bool IncludeTimestamps)<br class="">
-    : Stream(Stream), Buffer(Buffer), IncludeTimestamps(<wbr class="">IncludeTimestamps) {<br class="">
+    : Stream(Stream), Buffer(Buffer), PCMCache(PCMCache),<br class="">
+      IncludeTimestamps(<wbr class="">IncludeTimestamps) {<br class="">
   for (const auto &Ext : Extensions) {<br class="">
     if (auto Writer = Ext->createExtensionWriter(*<wbr class="">this))<br class="">
       ModuleFileExtensionWriters.<wbr class="">push_back(std::move(Writer));<br class="">
@@ -4354,6 +4356,12 @@ ASTFileSignature ASTWriter::WriteAST(Sem<br class="">
   this->BaseDirectory.clear();<br class="">
<br class="">
   WritingAST = false;<br class="">
+  if (SemaRef.Context.getLangOpts()<wbr class="">.ImplicitModules && WritingModule) {<br class="">
+    // Construct MemoryBuffer and update buffer manager.<br class="">
+    PCMCache.addBuffer(OutputFile,<br class="">
+                       llvm::MemoryBuffer::<wbr class="">getMemBufferCopy(<br class="">
+                           StringRef(Buffer.begin(), Buffer.size())));<br class="">
+  }<br class="">
   return Signature;<br class="">
 }<br class="">
<br class="">
<br class="">
Modified: cfe/trunk/lib/Serialization/<wbr class="">GeneratePCH.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/GeneratePCH.cpp?rev=298278&r1=298277&r2=298278&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/<wbr class="">Serialization/GeneratePCH.cpp?<wbr class="">rev=298278&r1=298277&r2=<wbr class="">298278&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/Serialization/<wbr class="">GeneratePCH.cpp (original)<br class="">
+++ cfe/trunk/lib/Serialization/<wbr class="">GeneratePCH.cpp Mon Mar 20 12:58:26 2017<br class="">
@@ -28,7 +28,8 @@ PCHGenerator::PCHGenerator(<br class="">
     bool AllowASTWithErrors, bool IncludeTimestamps)<br class="">
     : PP(PP), OutputFile(OutputFile), isysroot(isysroot.str()),<br class="">
       SemaPtr(nullptr), Buffer(Buffer), Stream(Buffer->Data),<br class="">
-      Writer(Stream, Buffer->Data, Extensions, IncludeTimestamps),<br class="">
+      Writer(Stream, Buffer->Data, PP.getPCMCache(), Extensions,<br class="">
+             IncludeTimestamps),<br class="">
       AllowASTWithErrors(<wbr class="">AllowASTWithErrors) {<br class="">
   Buffer->IsComplete = false;<br class="">
 }<br class="">
<br class="">
Modified: cfe/trunk/lib/Serialization/<wbr class="">ModuleManager.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ModuleManager.cpp?rev=298278&r1=298277&r2=298278&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/<wbr class="">Serialization/ModuleManager.<wbr class="">cpp?rev=298278&r1=298277&r2=<wbr class="">298278&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/Serialization/<wbr class="">ModuleManager.cpp (original)<br class="">
+++ cfe/trunk/lib/Serialization/<wbr class="">ModuleManager.cpp Mon Mar 20 12:58:26 2017<br class="">
@@ -12,6 +12,7 @@<br class="">
 //<br class="">
 //===-------------------------<wbr class="">------------------------------<wbr class="">---------------===//<br class="">
 #include "clang/Serialization/<wbr class="">ModuleManager.h"<br class="">
+#include "clang/Basic/<wbr class="">MemoryBufferCache.h"<br class="">
 #include "clang/Frontend/<wbr class="">PCHContainerOperations.h"<br class="">
 #include "clang/Lex/HeaderSearch.h"<br class="">
 #include "clang/Lex/ModuleMap.h"<br class="">
@@ -137,7 +138,9 @@ ModuleManager::addModule(<wbr class="">StringRef FileN<br class="">
   // Load the contents of the module<br class="">
   if (std::unique_ptr<llvm::<wbr class="">MemoryBuffer> Buffer = lookupBuffer(FileName)) {<br class="">
     // The buffer was already provided for us.<br class="">
-    NewModule->Buffer = std::move(Buffer);<br class="">
+    NewModule->Buffer = &PCMCache->addBuffer(FileName, std::move(Buffer));<br class="">
+  } else if (llvm::MemoryBuffer *Buffer = PCMCache->lookupBuffer(<wbr class="">FileName)) {<br class="">
+    NewModule->Buffer = Buffer;<br class="">
   } else {<br class="">
     // Open the AST file.<br class="">
     llvm::ErrorOr<std::unique_ptr<<wbr class="">llvm::MemoryBuffer>> Buf((std::error_code()));<br class="">
@@ -158,7 +161,7 @@ ModuleManager::addModule(<wbr class="">StringRef FileN<br class="">
       return Missing;<br class="">
     }<br class="">
<br class="">
-    NewModule->Buffer = std::move(*Buf);<br class="">
+    NewModule->Buffer = &PCMCache->addBuffer(FileName, std::move(*Buf));<br class="">
   }<br class="">
<br class="">
   // Initialize the stream.<br class="">
@@ -167,8 +170,13 @@ ModuleManager::addModule(<wbr class="">StringRef FileN<br class="">
   // Read the signature eagerly now so that we can check it.  Avoid calling<br class="">
   // ReadSignature unless there's something to check though.<br class="">
   if (ExpectedSignature && checkSignature(ReadSignature(<wbr class="">NewModule->Data),<br class="">
-                                          ExpectedSignature, ErrorStr))<br class="">
+                                          ExpectedSignature, ErrorStr)) {<br class="">
+    // Try to remove the buffer.  If it can't be removed, then it was already<br class="">
+    // validated by this process.<br class="">
+    if (!PCMCache->tryToRemoveBuffer(<wbr class="">NewModule->FileName))<br class="">
+      FileMgr.invalidateCache(<wbr class="">NewModule->File);<br class="">
     return OutOfDate;<br class="">
+  }<br class="">
<br class="">
   // We're keeping this module.  Store it everywhere.<br class="">
   Module = Modules[Entry] = NewModule.get();<br class="">
@@ -235,7 +243,12 @@ void ModuleManager::removeModules(<br class="">
     // Files that didn't make it through ReadASTCore successfully will be<br class="">
     // rebuilt (or there was an error). Invalidate them so that we can load the<br class="">
     // new files that will be renamed over the old ones.<br class="">
-    if (LoadedSuccessfully.count(&*<wbr class="">victim) == 0)<br class="">
+    //<br class="">
+    // The PCMCache tracks whether the module was succesfully loaded in another<br class="">
+    // thread/context; in that case, it won't need to be rebuilt (and we can't<br class="">
+    // safely invalidate it anyway).<br class="">
+    if (LoadedSuccessfully.count(&*<wbr class="">victim) == 0 &&<br class="">
+        !PCMCache->tryToRemoveBuffer(<wbr class="">victim->FileName))<br class="">
       FileMgr.invalidateCache(<wbr class="">victim->File);<br class="">
   }<br class="">
<br class="">
@@ -292,10 +305,10 @@ void ModuleManager::<wbr class="">moduleFileAccepted(M<br class="">
   ModulesInCommonWithGlobalIndex<wbr class="">.push_back(MF);<br class="">
 }<br class="">
<br class="">
-ModuleManager::ModuleManager(<wbr class="">FileManager &FileMgr,<br class="">
+ModuleManager::ModuleManager(<wbr class="">FileManager &FileMgr, MemoryBufferCache &PCMCache,<br class="">
                              const PCHContainerReader &PCHContainerRdr)<br class="">
-    : FileMgr(FileMgr), PCHContainerRdr(<wbr class="">PCHContainerRdr), GlobalIndex(),<br class="">
-      FirstVisitState(nullptr) {}<br class="">
+    : FileMgr(FileMgr), PCMCache(&PCMCache), PCHContainerRdr(<wbr class="">PCHContainerRdr),<br class="">
+      GlobalIndex(), FirstVisitState(nullptr) {}<br class="">
<br class="">
 ModuleManager::~ModuleManager(<wbr class="">) { delete FirstVisitState; }<br class="">
<br class="">
<br class="">
Added: cfe/trunk/test/Modules/Inputs/<wbr class="">system-out-of-date/X.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/system-out-of-date/X.h?rev=298278&view=auto" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/test/<wbr class="">Modules/Inputs/system-out-of-<wbr class="">date/X.h?rev=298278&view=auto</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/test/Modules/Inputs/<wbr class="">system-out-of-date/X.h (added)<br class="">
+++ cfe/trunk/test/Modules/Inputs/<wbr class="">system-out-of-date/X.h Mon Mar 20 12:58:26 2017<br class="">
@@ -0,0 +1 @@<br class="">
+#import <Y.h><br class="">
<br class="">
Added: cfe/trunk/test/Modules/Inputs/<wbr class="">system-out-of-date/Y.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/system-out-of-date/Y.h?rev=298278&view=auto" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/test/<wbr class="">Modules/Inputs/system-out-of-<wbr class="">date/Y.h?rev=298278&view=auto</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/test/Modules/Inputs/<wbr class="">system-out-of-date/Y.h (added)<br class="">
+++ cfe/trunk/test/Modules/Inputs/<wbr class="">system-out-of-date/Y.h Mon Mar 20 12:58:26 2017<br class="">
@@ -0,0 +1 @@<br class="">
+//empty<br class="">
<br class="">
Added: cfe/trunk/test/Modules/Inputs/<wbr class="">system-out-of-date/Z.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/system-out-of-date/Z.h?rev=298278&view=auto" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/test/<wbr class="">Modules/Inputs/system-out-of-<wbr class="">date/Z.h?rev=298278&view=auto</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/test/Modules/Inputs/<wbr class="">system-out-of-date/Z.h (added)<br class="">
+++ cfe/trunk/test/Modules/Inputs/<wbr class="">system-out-of-date/Z.h Mon Mar 20 12:58:26 2017<br class="">
@@ -0,0 +1 @@<br class="">
+#import <Y.h><br class="">
<br class="">
Added: cfe/trunk/test/Modules/Inputs/<wbr class="">system-out-of-date/module.map<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/system-out-of-date/module.map?rev=298278&view=auto" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/test/<wbr class="">Modules/Inputs/system-out-of-<wbr class="">date/module.map?rev=298278&<wbr class="">view=auto</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/test/Modules/Inputs/<wbr class="">system-out-of-date/module.map (added)<br class="">
+++ cfe/trunk/test/Modules/Inputs/<wbr class="">system-out-of-date/module.map Mon Mar 20 12:58:26 2017<br class="">
@@ -0,0 +1,12 @@<br class="">
+module X [system] {<br class="">
+  header "X.h" // imports Y<br class="">
+  export *<br class="">
+}<br class="">
+module Y {<br class="">
+  header "Y.h"<br class="">
+  export *<br class="">
+}<br class="">
+module Z {<br class="">
+  header "Z.h" // imports Y<br class="">
+  export *<br class="">
+}<br class="">
<br class="">
Added: cfe/trunk/test/Modules/Inputs/<wbr class="">warning-mismatch/Mismatch.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/warning-mismatch/Mismatch.h?rev=298278&view=auto" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/test/<wbr class="">Modules/Inputs/warning-<wbr class="">mismatch/Mismatch.h?rev=<wbr class="">298278&view=auto</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/test/Modules/Inputs/<wbr class="">warning-mismatch/Mismatch.h (added)<br class="">
+++ cfe/trunk/test/Modules/Inputs/<wbr class="">warning-mismatch/Mismatch.h Mon Mar 20 12:58:26 2017<br class="">
@@ -0,0 +1 @@<br class="">
+struct Mismatch { int i; };<br class="">
<br class="">
Added: cfe/trunk/test/Modules/Inputs/<wbr class="">warning-mismatch/System.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/warning-mismatch/System.h?rev=298278&view=auto" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/test/<wbr class="">Modules/Inputs/warning-<wbr class="">mismatch/System.h?rev=298278&<wbr class="">view=auto</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/test/Modules/Inputs/<wbr class="">warning-mismatch/System.h (added)<br class="">
+++ cfe/trunk/test/Modules/Inputs/<wbr class="">warning-mismatch/System.h Mon Mar 20 12:58:26 2017<br class="">
@@ -0,0 +1,2 @@<br class="">
+#import "Mismatch.h"<br class="">
+struct System { int i; };<br class="">
<br class="">
Added: cfe/trunk/test/Modules/Inputs/<wbr class="">warning-mismatch/module.<wbr class="">modulemap<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/warning-mismatch/module.modulemap?rev=298278&view=auto" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/test/<wbr class="">Modules/Inputs/warning-<wbr class="">mismatch/module.modulemap?rev=<wbr class="">298278&view=auto</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/test/Modules/Inputs/<wbr class="">warning-mismatch/module.<wbr class="">modulemap (added)<br class="">
+++ cfe/trunk/test/Modules/Inputs/<wbr class="">warning-mismatch/module.<wbr class="">modulemap Mon Mar 20 12:58:26 2017<br class="">
@@ -0,0 +1,7 @@<br class="">
+module System [system] {<br class="">
+  header "System.h"<br class="">
+}<br class="">
+<br class="">
+module Mismatch {<br class="">
+  header "Mismatch.h"<br class="">
+}<br class="">
<br class="">
Added: cfe/trunk/test/Modules/<wbr class="">outofdate-rebuild.m<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/outofdate-rebuild.m?rev=298278&view=auto" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/test/<wbr class="">Modules/outofdate-rebuild.m?<wbr class="">rev=298278&view=auto</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/test/Modules/<wbr class="">outofdate-rebuild.m (added)<br class="">
+++ cfe/trunk/test/Modules/<wbr class="">outofdate-rebuild.m Mon Mar 20 12:58:26 2017<br class="">
@@ -0,0 +1,15 @@<br class="">
+// RUN: rm -rf %t.cache<br class="">
+// RUN: echo "@import CoreText;" > %t.m<br class="">
+// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t.cache \<br class="">
+// RUN:   -fmodules -fimplicit-module-maps -I%S/Inputs/outofdate-rebuild %s \<br class="">
+// RUN:   -fsyntax-only<br class="">
+// RUN: %clang_cc1 -DMISMATCH -Werror -fdisable-module-hash \<br class="">
+// RUN:   -fmodules-cache-path=%t.cache -fmodules -fimplicit-module-maps \<br class="">
+// RUN:   -I%S/Inputs/outofdate-rebuild %t.m -fsyntax-only<br class="">
+// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t.cache \<br class="">
+// RUN:   -fmodules -fimplicit-module-maps -I%S/Inputs/outofdate-rebuild %s \<br class="">
+// RUN:   -fsyntax-only<br class="">
+<br class="">
+// This testcase reproduces a use-after-free in when ModuleManager removes an<br class="">
+// entry from the PCMCache without notifying its parent ASTReader.<br class="">
+@import Cocoa;<br class="">
<br class="">
Added: cfe/trunk/test/Modules/system-<wbr class="">out-of-date-test.m<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/system-out-of-date-test.m?rev=298278&view=auto" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/test/<wbr class="">Modules/system-out-of-date-<wbr class="">test.m?rev=298278&view=auto</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/test/Modules/system-<wbr class="">out-of-date-test.m (added)<br class="">
+++ cfe/trunk/test/Modules/system-<wbr class="">out-of-date-test.m Mon Mar 20 12:58:26 2017<br class="">
@@ -0,0 +1,17 @@<br class="">
+// RUN: rm -rf %t.cache<br class="">
+// RUN: echo '@import X;' | \<br class="">
+// RUN:   %clang_cc1 -fmodules -fimplicit-module-maps \<br class="">
+// RUN:     -fmodules-cache-path=%t.cache -I%S/Inputs/system-out-of-date \<br class="">
+// RUN:     -fsyntax-only -x objective-c -<br class="">
+//<br class="">
+// Build something with different diagnostic options.<br class="">
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps \<br class="">
+// RUN:   -fmodules-cache-path=%t.cache -I%S/Inputs/system-out-of-date \<br class="">
+// RUN:   -fsyntax-only %s -Wnon-modular-include-in-<wbr class="">framework-module \<br class="">
+// RUN:   -Werror=non-modular-include-<wbr class="">in-framework-module 2>&1 \<br class="">
+// RUN: | FileCheck %s<br class="">
+@import X;<br class="">
+<br class="">
+#import <Z.h><br class="">
+// CHECK: While building module 'Z' imported from<br class="">
+// CHECK: {{.*}}Y-{{.*}}pcm' was validated as a system module and is now being imported as a non-system module<br class="">
<br class="">
Added: cfe/trunk/test/Modules/<wbr class="">warning-mismatch.m<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/warning-mismatch.m?rev=298278&view=auto" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/test/<wbr class="">Modules/warning-mismatch.m?<wbr class="">rev=298278&view=auto</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/test/Modules/<wbr class="">warning-mismatch.m (added)<br class="">
+++ cfe/trunk/test/Modules/<wbr class="">warning-mismatch.m Mon Mar 20 12:58:26 2017<br class="">
@@ -0,0 +1,13 @@<br class="">
+// RUN: rm -rf %t.cache<br class="">
+// RUN: echo "@import Mismatch;" >%t.m<br class="">
+// RUN: %clang_cc1 -Wno-system-headers -fdisable-module-hash \<br class="">
+// RUN:   -fmodules-cache-path=%t.cache -fmodules -fimplicit-module-maps \<br class="">
+// RUN:   -I%S/Inputs/warning-mismatch %t.m -fsyntax-only<br class="">
+// RUN: %clang_cc1 -Wsystem-headers -fdisable-module-hash \<br class="">
+// RUN:   -fmodules-cache-path=%t.cache -fmodules -fimplicit-module-maps \<br class="">
+// RUN:   -I%S/Inputs/warning-mismatch %s -fsyntax-only<br class="">
+<br class="">
+// This testcase triggers a warning flag mismatch in an already validated<br class="">
+// header.<br class="">
+@import Mismatch;<br class="">
+@import System;<br class="">
<br class="">
Modified: cfe/trunk/unittests/Basic/<wbr class="">CMakeLists.txt<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Basic/CMakeLists.txt?rev=298278&r1=298277&r2=298278&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/unittests/<wbr class="">Basic/CMakeLists.txt?rev=<wbr class="">298278&r1=298277&r2=298278&<wbr class="">view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/unittests/Basic/<wbr class="">CMakeLists.txt (original)<br class="">
+++ cfe/trunk/unittests/Basic/<wbr class="">CMakeLists.txt Mon Mar 20 12:58:26 2017<br class="">
@@ -6,6 +6,7 @@ add_clang_unittest(BasicTests<br class="">
   CharInfoTest.cpp<br class="">
   DiagnosticTest.cpp<br class="">
   FileManagerTest.cpp<br class="">
+  MemoryBufferCacheTest.cpp<br class="">
   SourceManagerTest.cpp<br class="">
   VirtualFileSystemTest.cpp<br class="">
   )<br class="">
<br class="">
Added: cfe/trunk/unittests/Basic/<wbr class="">MemoryBufferCacheTest.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Basic/MemoryBufferCacheTest.cpp?rev=298278&view=auto" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/unittests/<wbr class="">Basic/MemoryBufferCacheTest.<wbr class="">cpp?rev=298278&view=auto</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/unittests/Basic/<wbr class="">MemoryBufferCacheTest.cpp (added)<br class="">
+++ cfe/trunk/unittests/Basic/<wbr class="">MemoryBufferCacheTest.cpp Mon Mar 20 12:58:26 2017<br class="">
@@ -0,0 +1,95 @@<br class="">
+//===- MemoryBufferCacheTest.cpp - MemoryBufferCache tests ----------------===//<br class="">
+//<br class="">
+//                     The LLVM Compiler Infrastructure<br class="">
+//<br class="">
+// This file is distributed under the University of Illinois Open Source<br class="">
+// License. See LICENSE.TXT for details.<br class="">
+//<br class="">
+//===------------------------<wbr class="">------------------------------<wbr class="">----------------===//<br class="">
+<br class="">
+#include "clang/Basic/<wbr class="">MemoryBufferCache.h"<br class="">
+#include "llvm/Support/MemoryBuffer.h"<br class="">
+#include "gtest/gtest.h"<br class="">
+<br class="">
+using namespace llvm;<br class="">
+using namespace clang;<br class="">
+<br class="">
+namespace {<br class="">
+<br class="">
+std::unique_ptr<MemoryBuffer> getBuffer(int I) {<br class="">
+  SmallVector<char, 8> Bytes;<br class="">
+  raw_svector_ostream(Bytes) << "data:" << I;<br class="">
+  return MemoryBuffer::getMemBuffer(<wbr class="">StringRef(Bytes.data(), Bytes.size()), "",<br class="">
+                                    /* RequiresNullTerminator = */ false);<br class="">
+}<br class="">
+<br class="">
+TEST(MemoryBufferCacheTest, addBuffer) {<br class="">
+  auto B1 = getBuffer(1);<br class="">
+  auto B2 = getBuffer(2);<br class="">
+  auto B3 = getBuffer(3);<br class="">
+  auto *RawB1 = B1.get();<br class="">
+  auto *RawB2 = B2.get();<br class="">
+  auto *RawB3 = B3.get();<br class="">
+<br class="">
+  // Add a few buffers.<br class="">
+  MemoryBufferCache Cache;<br class="">
+  EXPECT_EQ(RawB1, &Cache.addBuffer("1", std::move(B1)));<br class="">
+  EXPECT_EQ(RawB2, &Cache.addBuffer("2", std::move(B2)));<br class="">
+  EXPECT_EQ(RawB3, &Cache.addBuffer("3", std::move(B3)));<br class="">
+  EXPECT_EQ(RawB1, Cache.lookupBuffer("1"));<br class="">
+  EXPECT_EQ(RawB2, Cache.lookupBuffer("2"));<br class="">
+  EXPECT_EQ(RawB3, Cache.lookupBuffer("3"));<br class="">
+  EXPECT_FALSE(Cache.<wbr class="">isBufferFinal("1"));<br class="">
+  EXPECT_FALSE(Cache.<wbr class="">isBufferFinal("2"));<br class="">
+  EXPECT_FALSE(Cache.<wbr class="">isBufferFinal("3"));<br class="">
+<br class="">
+  // Remove the middle buffer.<br class="">
+  EXPECT_FALSE(Cache.<wbr class="">tryToRemoveBuffer("2"));<br class="">
+  EXPECT_EQ(nullptr, Cache.lookupBuffer("2"));<br class="">
+  EXPECT_FALSE(Cache.<wbr class="">isBufferFinal("2"));<br class="">
+<br class="">
+  // Replace the middle buffer.<br class="">
+  B2 = getBuffer(2);<br class="">
+  ASSERT_NE(RawB2, B2.get());<br class="">
+  RawB2 = B2.get();<br class="">
+  EXPECT_EQ(RawB2, &Cache.addBuffer("2", std::move(B2)));<br class="">
+<br class="">
+  // Check that nothing is final.<br class="">
+  EXPECT_FALSE(Cache.<wbr class="">isBufferFinal("1"));<br class="">
+  EXPECT_FALSE(Cache.<wbr class="">isBufferFinal("2"));<br class="">
+  EXPECT_FALSE(Cache.<wbr class="">isBufferFinal("3"));<br class="">
+}<br class="">
+<br class="">
+TEST(MemoryBufferCacheTest, finalizeCurrentBuffers) {<br class="">
+  // Add a buffer.<br class="">
+  MemoryBufferCache Cache;<br class="">
+  auto B1 = getBuffer(1);<br class="">
+  auto *RawB1 = B1.get();<br class="">
+  Cache.addBuffer("1", std::move(B1));<br class="">
+  ASSERT_FALSE(Cache.<wbr class="">isBufferFinal("1"));<br class="">
+<br class="">
+  // Finalize it.<br class="">
+  Cache.finalizeCurrentBuffers()<wbr class="">;<br class="">
+  EXPECT_TRUE(Cache.<wbr class="">isBufferFinal("1"));<br class="">
+  EXPECT_TRUE(Cache.<wbr class="">tryToRemoveBuffer("1"));<br class="">
+  EXPECT_EQ(RawB1, Cache.lookupBuffer("1"));<br class="">
+  EXPECT_TRUE(Cache.<wbr class="">isBufferFinal("1"));<br class="">
+<br class="">
+  // Repeat.<br class="">
+  auto B2 = getBuffer(2);<br class="">
+  auto *RawB2 = B2.get();<br class="">
+  Cache.addBuffer("2", std::move(B2));<br class="">
+  EXPECT_FALSE(Cache.<wbr class="">isBufferFinal("2"));<br class="">
+<br class="">
+  Cache.finalizeCurrentBuffers()<wbr class="">;<br class="">
+  EXPECT_TRUE(Cache.<wbr class="">isBufferFinal("1"));<br class="">
+  EXPECT_TRUE(Cache.<wbr class="">isBufferFinal("2"));<br class="">
+  EXPECT_TRUE(Cache.<wbr class="">tryToRemoveBuffer("1"));<br class="">
+  EXPECT_TRUE(Cache.<wbr class="">tryToRemoveBuffer("2"));<br class="">
+  EXPECT_EQ(RawB1, Cache.lookupBuffer("1"));<br class="">
+  EXPECT_EQ(RawB2, Cache.lookupBuffer("2"));<br class="">
+  EXPECT_TRUE(Cache.<wbr class="">isBufferFinal("1"));<br class="">
+  EXPECT_TRUE(Cache.<wbr class="">isBufferFinal("2"));<br class="">
+}<br class="">
+<br class="">
+} // namespace<br class="">
<br class="">
Modified: cfe/trunk/unittests/Basic/<wbr class="">SourceManagerTest.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Basic/SourceManagerTest.cpp?rev=298278&r1=298277&r2=298278&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/unittests/<wbr class="">Basic/SourceManagerTest.cpp?<wbr class="">rev=298278&r1=298277&r2=<wbr class="">298278&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/unittests/Basic/<wbr class="">SourceManagerTest.cpp (original)<br class="">
+++ cfe/trunk/unittests/Basic/<wbr class="">SourceManagerTest.cpp Mon Mar 20 12:58:26 2017<br class="">
@@ -12,6 +12,7 @@<br class="">
 #include "clang/Basic/<wbr class="">DiagnosticOptions.h"<br class="">
 #include "clang/Basic/FileManager.h"<br class="">
 #include "clang/Basic/LangOptions.h"<br class="">
+#include "clang/Basic/<wbr class="">MemoryBufferCache.h"<br class="">
 #include "clang/Basic/TargetInfo.h"<br class="">
 #include "clang/Basic/TargetOptions.h"<br class="">
 #include "clang/Lex/HeaderSearch.h"<br class="">
@@ -78,10 +79,11 @@ TEST_F(SourceManagerTest, isBeforeInTran<br class="">
   SourceMgr.setMainFileID(<wbr class="">mainFileID);<br class="">
<br class="">
   VoidModuleLoader ModLoader;<br class="">
+  MemoryBufferCache PCMCache;<br class="">
   HeaderSearch HeaderInfo(std::make_shared<<wbr class="">HeaderSearchOptions>(), SourceMgr,<br class="">
                           Diags, LangOpts, &*Target);<br class="">
   Preprocessor PP(std::make_shared<<wbr class="">PreprocessorOptions>(), Diags, LangOpts,<br class="">
-                  SourceMgr, HeaderInfo, ModLoader,<br class="">
+                  SourceMgr, PCMCache, HeaderInfo, ModLoader,<br class="">
                   /*IILookup =*/nullptr,<br class="">
                   /*OwnsHeaderSearch =*/false);<br class="">
   PP.Initialize(*Target);<br class="">
@@ -198,10 +200,11 @@ TEST_F(SourceManagerTest, getMacroArgExp<br class="">
   SourceMgr.<wbr class="">overrideFileContents(<wbr class="">headerFile, std::move(HeaderBuf));<br class="">
<br class="">
   VoidModuleLoader ModLoader;<br class="">
+  MemoryBufferCache PCMCache;<br class="">
   HeaderSearch HeaderInfo(std::make_shared<<wbr class="">HeaderSearchOptions>(), SourceMgr,<br class="">
                           Diags, LangOpts, &*Target);<br class="">
   Preprocessor PP(std::make_shared<<wbr class="">PreprocessorOptions>(), Diags, LangOpts,<br class="">
-                  SourceMgr, HeaderInfo, ModLoader,<br class="">
+                  SourceMgr, PCMCache, HeaderInfo, ModLoader,<br class="">
                   /*IILookup =*/nullptr,<br class="">
                   /*OwnsHeaderSearch =*/false);<br class="">
   PP.Initialize(*Target);<br class="">
@@ -298,10 +301,11 @@ TEST_F(SourceManagerTest, isBeforeInTran<br class="">
   SourceMgr.<wbr class="">overrideFileContents(<wbr class="">headerFile, std::move(HeaderBuf));<br class="">
<br class="">
   VoidModuleLoader ModLoader;<br class="">
+  MemoryBufferCache PCMCache;<br class="">
   HeaderSearch HeaderInfo(std::make_shared<<wbr class="">HeaderSearchOptions>(), SourceMgr,<br class="">
                           Diags, LangOpts, &*Target);<br class="">
   Preprocessor PP(std::make_shared<<wbr class="">PreprocessorOptions>(), Diags, LangOpts,<br class="">
-                  SourceMgr, HeaderInfo, ModLoader,<br class="">
+                  SourceMgr, PCMCache, HeaderInfo, ModLoader,<br class="">
                   /*IILookup =*/nullptr,<br class="">
                   /*OwnsHeaderSearch =*/false);<br class="">
   PP.Initialize(*Target);<br class="">
<br class="">
Modified: cfe/trunk/unittests/Lex/<wbr class="">LexerTest.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Lex/LexerTest.cpp?rev=298278&r1=298277&r2=298278&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/unittests/<wbr class="">Lex/LexerTest.cpp?rev=298278&<wbr class="">r1=298277&r2=298278&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/unittests/Lex/<wbr class="">LexerTest.cpp (original)<br class="">
+++ cfe/trunk/unittests/Lex/<wbr class="">LexerTest.cpp Mon Mar 20 12:58:26 2017<br class="">
@@ -12,6 +12,7 @@<br class="">
 #include "clang/Basic/<wbr class="">DiagnosticOptions.h"<br class="">
 #include "clang/Basic/FileManager.h"<br class="">
 #include "clang/Basic/LangOptions.h"<br class="">
+#include "clang/Basic/<wbr class="">MemoryBufferCache.h"<br class="">
 #include "clang/Basic/SourceManager.h"<br class="">
 #include "clang/Basic/TargetInfo.h"<br class="">
 #include "clang/Basic/TargetOptions.h"<br class="">
@@ -64,10 +65,12 @@ protected:<br class="">
     SourceMgr.setMainFileID(<wbr class="">SourceMgr.createFileID(std::<wbr class="">move(Buf)));<br class="">
<br class="">
     VoidModuleLoader ModLoader;<br class="">
+    MemoryBufferCache PCMCache;<br class="">
     HeaderSearch HeaderInfo(std::make_shared<<wbr class="">HeaderSearchOptions>(), SourceMgr,<br class="">
                             Diags, LangOpts, Target.get());<br class="">
     Preprocessor PP(std::make_shared<<wbr class="">PreprocessorOptions>(), Diags, LangOpts,<br class="">
-                    SourceMgr, HeaderInfo, ModLoader, /*IILookup =*/nullptr,<br class="">
+                    SourceMgr, PCMCache, HeaderInfo, ModLoader,<br class="">
+                    /*IILookup =*/nullptr,<br class="">
                     /*OwnsHeaderSearch =*/false);<br class="">
     PP.Initialize(*Target);<br class="">
     PP.EnterMainSourceFile();<br class="">
<br class="">
Modified: cfe/trunk/unittests/Lex/<wbr class="">PPCallbacksTest.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Lex/PPCallbacksTest.cpp?rev=298278&r1=298277&r2=298278&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/unittests/<wbr class="">Lex/PPCallbacksTest.cpp?rev=<wbr class="">298278&r1=298277&r2=298278&<wbr class="">view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/unittests/Lex/<wbr class="">PPCallbacksTest.cpp (original)<br class="">
+++ cfe/trunk/unittests/Lex/<wbr class="">PPCallbacksTest.cpp Mon Mar 20 12:58:26 2017<br class="">
@@ -14,6 +14,7 @@<br class="">
 #include "clang/Basic/<wbr class="">DiagnosticOptions.h"<br class="">
 #include "clang/Basic/FileManager.h"<br class="">
 #include "clang/Basic/LangOptions.h"<br class="">
+#include "clang/Basic/<wbr class="">MemoryBufferCache.h"<br class="">
 #include "clang/Basic/SourceManager.h"<br class="">
 #include "clang/Basic/TargetInfo.h"<br class="">
 #include "clang/Basic/TargetOptions.h"<br class="">
@@ -161,13 +162,14 @@ protected:<br class="">
     SourceMgr.setMainFileID(<wbr class="">SourceMgr.createFileID(std::<wbr class="">move(Buf)));<br class="">
<br class="">
     VoidModuleLoader ModLoader;<br class="">
+    MemoryBufferCache PCMCache;<br class="">
<br class="">
     HeaderSearch HeaderInfo(std::make_shared<<wbr class="">HeaderSearchOptions>(), SourceMgr,<br class="">
                             Diags, LangOpts, Target.get());<br class="">
     AddFakeHeader(HeaderInfo, HeaderPath, SystemHeader);<br class="">
<br class="">
     Preprocessor PP(std::make_shared<<wbr class="">PreprocessorOptions>(), Diags, LangOpts,<br class="">
-                    SourceMgr, HeaderInfo, ModLoader,<br class="">
+                    SourceMgr, PCMCache, HeaderInfo, ModLoader,<br class="">
                     /*IILookup =*/nullptr,<br class="">
                     /*OwnsHeaderSearch =*/false);<br class="">
     PP.Initialize(*Target);<br class="">
@@ -198,11 +200,12 @@ protected:<br class="">
     SourceMgr.setMainFileID(<wbr class="">SourceMgr.createFileID(std::<wbr class="">move(SourceBuf)));<br class="">
<br class="">
     VoidModuleLoader ModLoader;<br class="">
+    MemoryBufferCache PCMCache;<br class="">
     HeaderSearch HeaderInfo(std::make_shared<<wbr class="">HeaderSearchOptions>(), SourceMgr,<br class="">
                             Diags, OpenCLLangOpts, Target.get());<br class="">
<br class="">
     Preprocessor PP(std::make_shared<<wbr class="">PreprocessorOptions>(), Diags,<br class="">
-                    OpenCLLangOpts, SourceMgr, HeaderInfo, ModLoader,<br class="">
+                    OpenCLLangOpts, SourceMgr, PCMCache, HeaderInfo, ModLoader,<br class="">
                     /*IILookup =*/nullptr,<br class="">
                     /*OwnsHeaderSearch =*/false);<br class="">
     PP.Initialize(*Target);<br class="">
<br class="">
Modified: cfe/trunk/unittests/Lex/<wbr class="">PPConditionalDirectiveRecordTe<wbr class="">st.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Lex/PPConditionalDirectiveRecordTest.cpp?rev=298278&r1=298277&r2=298278&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/unittests/<wbr class="">Lex/<wbr class="">PPConditionalDirectiveRecordTe<wbr class="">st.cpp?rev=298278&r1=298277&<wbr class="">r2=298278&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/unittests/Lex/<wbr class="">PPConditionalDirectiveRecordTe<wbr class="">st.cpp (original)<br class="">
+++ cfe/trunk/unittests/Lex/<wbr class="">PPConditionalDirectiveRecordTe<wbr class="">st.cpp Mon Mar 20 12:58:26 2017<br class="">
@@ -12,6 +12,7 @@<br class="">
 #include "clang/Basic/<wbr class="">DiagnosticOptions.h"<br class="">
 #include "clang/Basic/FileManager.h"<br class="">
 #include "clang/Basic/LangOptions.h"<br class="">
+#include "clang/Basic/<wbr class="">MemoryBufferCache.h"<br class="">
 #include "clang/Basic/SourceManager.h"<br class="">
 #include "clang/Basic/TargetInfo.h"<br class="">
 #include "clang/Basic/TargetOptions.h"<br class="">
@@ -93,10 +94,11 @@ TEST_F(<wbr class="">PPConditionalDirectiveRecordTe<wbr class="">st,<br class="">
   SourceMgr.setMainFileID(<wbr class="">SourceMgr.createFileID(std::<wbr class="">move(Buf)));<br class="">
<br class="">
   VoidModuleLoader ModLoader;<br class="">
+  MemoryBufferCache PCMCache;<br class="">
   HeaderSearch HeaderInfo(std::make_shared<<wbr class="">HeaderSearchOptions>(), SourceMgr,<br class="">
                           Diags, LangOpts, Target.get());<br class="">
   Preprocessor PP(std::make_shared<<wbr class="">PreprocessorOptions>(), Diags, LangOpts,<br class="">
-                  SourceMgr, HeaderInfo, ModLoader,<br class="">
+                  SourceMgr, PCMCache, HeaderInfo, ModLoader,<br class="">
                   /*IILookup =*/nullptr,<br class="">
                   /*OwnsHeaderSearch =*/false);<br class="">
   PP.Initialize(*Target);<br class="">
<br class="">
<br class="">
______________________________<wbr class="">_________________<br class="">
cfe-commits mailing list<br class="">
<a href="mailto:cfe-commits@lists.llvm.org" class="">cfe-commits@lists.llvm.org</a><br class="">
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank" class="">http://lists.llvm.org/cgi-bin/<wbr class="">mailman/listinfo/cfe-commits</a><br class="">
</blockquote></div><br class=""></div>
</div></blockquote></div><br class=""></div></div>_______________________________________________<br class="">cfe-commits mailing list<br class=""><a href="mailto:cfe-commits@lists.llvm.org" class="">cfe-commits@lists.llvm.org</a><br class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits<br class=""></div></blockquote></div><br class=""></div></div></body></html>