[clang-tools-extra] r189689 - cpp11-migrate: Refactor for driver model of operation

Michael Gottesman mgottesman at apple.com
Fri Aug 30 14:22:28 PDT 2013


Hey Edwin!

I think this broke builtbots:

Phased Builder (blame list):
http://lab.llvm.org:8013/builders/phase1%20-%20sanity/builds/11001

Child Builder:
http://lab.llvm.org:8013/builders/clang-x86_64-darwin11-nobootstrap-RAincremental/builds/6550

Can you fix/revert.

Thanks,
Michael

On Aug 30, 2013, at 12:29 PM, Edwin Vane <edwin.vane at intel.com> wrote:

> Author: revane
> Date: Fri Aug 30 14:28:59 2013
> New Revision: 189689
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=189689&view=rev
> Log:
> cpp11-migrate: Refactor for driver model of operation
> 
> Massive simplification of how replacements and file overrides are handled by
> the migrator:
> * Sources and headers are all treated the same.
> * All replacements for a given translation unit are stored in the same
>  TranslationUnitReplacements structure.
> * Change tracking is updated only from main file; no need for
>  propagating "is tracking" flag around.
> * Transform base class no longer responsible for applying replacements.
>  They are simply stored and main() looks after deduplication and
>  application.
> * Renamed -yaml-only to -serialize-replacements. Same restrictions apply:
>  Can only request one transform. New restriction: formatting cannot also
>  be turned on since it's basically a transform.
> * If -serialize-replacements is requested, changes to files will not be
>  applied on disk.
> * Changed behaviour of function generating names for serialized
>  replacements: Only the main source file goes into the name of the file
>  since a file may contain changes for multiple different files.
> * Updated HeaderReplacements LIT test for new serialization behaviour.
>  * Replaced old test that ensures replacements are not serialized if
>    -serialize-replacements is not provided. New version ensures changes
>    are made directly to all files in the translation unit.
> * Updated unit tests.
>  * Due to major simplification of structures in FileOverrides.h, the
>    FileOverridesTest is quite a bit simpler now.
> 
> Differential Revision: http://llvm-reviews.chandlerc.com/D1545
> 
> Added:
>    clang-tools-extra/trunk/cpp11-migrate/Core/Refactoring.h
>    clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/Inputs/
>    clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/Inputs/no_yaml.h
>    clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/common_expected.yaml
>    clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/main_expected.yaml
>    clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/no_yaml.cpp
> Removed:
>    clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/common.h.yaml
> Modified:
>    clang-tools-extra/trunk/cpp11-migrate/AddOverride/AddOverride.cpp
>    clang-tools-extra/trunk/cpp11-migrate/AddOverride/AddOverride.h
>    clang-tools-extra/trunk/cpp11-migrate/AddOverride/AddOverrideActions.cpp
>    clang-tools-extra/trunk/cpp11-migrate/AddOverride/AddOverrideActions.h
>    clang-tools-extra/trunk/cpp11-migrate/CMakeLists.txt
>    clang-tools-extra/trunk/cpp11-migrate/Core/FileOverrides.cpp
>    clang-tools-extra/trunk/cpp11-migrate/Core/FileOverrides.h
>    clang-tools-extra/trunk/cpp11-migrate/Core/Reformatting.cpp
>    clang-tools-extra/trunk/cpp11-migrate/Core/Reformatting.h
>    clang-tools-extra/trunk/cpp11-migrate/Core/SyntaxCheck.cpp
>    clang-tools-extra/trunk/cpp11-migrate/Core/Transform.cpp
>    clang-tools-extra/trunk/cpp11-migrate/Core/Transform.h
>    clang-tools-extra/trunk/cpp11-migrate/LoopConvert/LoopActions.cpp
>    clang-tools-extra/trunk/cpp11-migrate/LoopConvert/LoopActions.h
>    clang-tools-extra/trunk/cpp11-migrate/LoopConvert/LoopConvert.cpp
>    clang-tools-extra/trunk/cpp11-migrate/LoopConvert/LoopConvert.h
>    clang-tools-extra/trunk/cpp11-migrate/PassByValue/PassByValue.cpp
>    clang-tools-extra/trunk/cpp11-migrate/PassByValue/PassByValue.h
>    clang-tools-extra/trunk/cpp11-migrate/PassByValue/PassByValueActions.cpp
>    clang-tools-extra/trunk/cpp11-migrate/PassByValue/PassByValueActions.h
>    clang-tools-extra/trunk/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.cpp
>    clang-tools-extra/trunk/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.h
>    clang-tools-extra/trunk/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.cpp
>    clang-tools-extra/trunk/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.h
>    clang-tools-extra/trunk/cpp11-migrate/UseAuto/UseAuto.cpp
>    clang-tools-extra/trunk/cpp11-migrate/UseAuto/UseAuto.h
>    clang-tools-extra/trunk/cpp11-migrate/UseAuto/UseAutoActions.cpp
>    clang-tools-extra/trunk/cpp11-migrate/UseAuto/UseAutoActions.h
>    clang-tools-extra/trunk/cpp11-migrate/UseNullptr/NullptrActions.cpp
>    clang-tools-extra/trunk/cpp11-migrate/UseNullptr/NullptrActions.h
>    clang-tools-extra/trunk/cpp11-migrate/UseNullptr/UseNullptr.cpp
>    clang-tools-extra/trunk/cpp11-migrate/UseNullptr/UseNullptr.h
>    clang-tools-extra/trunk/cpp11-migrate/tool/CMakeLists.txt
>    clang-tools-extra/trunk/cpp11-migrate/tool/Cpp11Migrate.cpp
>    clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/main.cpp
>    clang-tools-extra/trunk/unittests/cpp11-migrate/CMakeLists.txt
>    clang-tools-extra/trunk/unittests/cpp11-migrate/FileOverridesTest.cpp
>    clang-tools-extra/trunk/unittests/cpp11-migrate/PerfSupportTest.cpp
>    clang-tools-extra/trunk/unittests/cpp11-migrate/ReformattingTest.cpp
>    clang-tools-extra/trunk/unittests/cpp11-migrate/TransformTest.cpp
>    clang-tools-extra/trunk/unittests/cpp11-migrate/UniqueHeaderNameTest.cpp
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/AddOverride/AddOverride.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/AddOverride/AddOverride.cpp?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/AddOverride/AddOverride.cpp (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/AddOverride/AddOverride.cpp Fri Aug 30 14:28:59 2013
> @@ -29,13 +29,13 @@ static cl::opt<bool> DetectMacros(
>     cl::desc("Detect and use macros that expand to the 'override' keyword."),
>     cl::cat(TransformsOptionsCategory));
> 
> -int AddOverrideTransform::apply(FileOverrides &InputStates,
> +int AddOverrideTransform::apply(const FileOverrides &InputStates,
>                                 const CompilationDatabase &Database,
>                                 const std::vector<std::string> &SourcePaths) {
>   ClangTool AddOverrideTool(Database, SourcePaths);
>   unsigned AcceptedChanges = 0;
>   MatchFinder Finder;
> -  AddOverrideFixer Fixer(getReplacements(), AcceptedChanges, DetectMacros,
> +  AddOverrideFixer Fixer(AcceptedChanges, DetectMacros,
>                          /*Owner=*/ *this);
>   Finder.addMatcher(makeCandidateForOverrideAttrMatcher(), &Fixer);
> 
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/AddOverride/AddOverride.h
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/AddOverride/AddOverride.h?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/AddOverride/AddOverride.h (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/AddOverride/AddOverride.h Fri Aug 30 14:28:59 2013
> @@ -31,7 +31,7 @@ public:
>       : Transform("AddOverride", Options) {}
> 
>   /// \see Transform::run().
> -  virtual int apply(FileOverrides &InputStates,
> +  virtual int apply(const FileOverrides &InputStates,
>                     const clang::tooling::CompilationDatabase &Database,
>                     const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE;
> 
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/AddOverride/AddOverrideActions.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/AddOverride/AddOverrideActions.cpp?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/AddOverride/AddOverrideActions.cpp (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/AddOverride/AddOverrideActions.cpp Fri Aug 30 14:28:59 2013
> @@ -95,6 +95,7 @@ void AddOverrideFixer::run(const MatchFi
>     if (!MacroName.empty())
>       ReplacementText = (" " + MacroName).str();
>   }
> -  Replace.insert(tooling::Replacement(SM, StartLoc, 0, ReplacementText));
> +  Owner.addReplacementForCurrentTU(
> +      tooling::Replacement(SM, StartLoc, 0, ReplacementText));
>   ++AcceptedChanges;
> }
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/AddOverride/AddOverrideActions.h
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/AddOverride/AddOverrideActions.h?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/AddOverride/AddOverrideActions.h (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/AddOverride/AddOverrideActions.h Fri Aug 30 14:28:59 2013
> @@ -25,11 +25,10 @@ class Transform;
> ///
> class AddOverrideFixer : public clang::ast_matchers::MatchFinder::MatchCallback {
> public:
> -  AddOverrideFixer(clang::tooling::Replacements &Replace,
> -                   unsigned &AcceptedChanges, bool DetectMacros,
> -                   const Transform &Owner)
> -      : Replace(Replace), AcceptedChanges(AcceptedChanges),
> -        DetectMacros(DetectMacros), Owner(Owner) {}
> +  AddOverrideFixer(unsigned &AcceptedChanges, bool DetectMacros,
> +                   Transform &Owner)
> +      : AcceptedChanges(AcceptedChanges), DetectMacros(DetectMacros),
> +        Owner(Owner) {}
> 
>   /// \brief Entry point to the callback called when matches are made.
>   virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result);
> @@ -38,10 +37,9 @@ public:
> 
> private:
>   clang::Preprocessor *PP;
> -  clang::tooling::Replacements &Replace;
>   unsigned &AcceptedChanges;
>   bool DetectMacros;
> -  const Transform &Owner;
> +  Transform &Owner;
> };
> 
> #endif // CPP11_MIGRATE_ADD_OVERRIDE_ACTIONS_H
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/CMakeLists.txt?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/CMakeLists.txt (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/CMakeLists.txt Fri Aug 30 14:28:59 2013
> @@ -1,4 +1,10 @@
> -include_directories(${CMAKE_CURRENT_SOURCE_DIR})
> +get_filename_component(ClangReplaceLocation
> +  "${CMAKE_CURRENT_SOURCE_DIR}/../clang-replace/include" ABSOLUTE)
> +
> +include_directories(
> +  ${CMAKE_CURRENT_SOURCE_DIR}
> +  ${ClangReplaceLocation}
> +  )
> 
> add_subdirectory(tool)
> add_subdirectory(Core)
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/Core/FileOverrides.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/Core/FileOverrides.cpp?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/Core/FileOverrides.cpp (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/Core/FileOverrides.cpp Fri Aug 30 14:28:59 2013
> @@ -29,157 +29,14 @@
> using namespace clang;
> using namespace clang::tooling;
> 
> -void HeaderOverride::recordReplacements(
> -    const clang::tooling::Replacements &Replaces) {
> -  Replacements.Replacements.resize(Replaces.size());
> -  std::copy(Replaces.begin(), Replaces.end(),
> -            Replacements.Replacements.begin());
> -}
> -
> -SourceOverrides::SourceOverrides(llvm::StringRef MainFileName,
> -                                 bool TrackChanges)
> -    : MainFileName(MainFileName), TrackChanges(TrackChanges) {}
> -
> -void
> -SourceOverrides::applyReplacements(clang::tooling::Replacements &Replaces) {
> -  llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts(
> -      new DiagnosticOptions());
> -  DiagnosticsEngine Diagnostics(
> -      llvm::IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
> -      DiagOpts.getPtr());
> -  FileManager Files((FileSystemOptions()));
> -  SourceManager SM(Diagnostics, Files);
> -  applyReplacements(Replaces, SM);
> -}
> -
> -void SourceOverrides::applyReplacements(clang::tooling::Replacements &Replaces,
> -                                        clang::SourceManager &SM) {
> -  applyOverrides(SM);
> -
> -  Rewriter Rewrites(SM, LangOptions());
> -
> -  // FIXME: applyAllReplacements will indicate if it couldn't apply all
> -  // replacements. Handle that case.
> -  bool Success = tooling::applyAllReplacements(Replaces, Rewrites);
> -
> -  if (!Success)
> -    llvm::errs() << "error: failed to apply some replacements.";
> -
> -  std::string ResultBuf;
> -
> -  for (Rewriter::buffer_iterator I = Rewrites.buffer_begin(),
> -                                 E = Rewrites.buffer_end();
> -       I != E; ++I) {
> -    const FileEntry *Entry =
> -        Rewrites.getSourceMgr().getFileEntryForID(I->first);
> -    assert(Entry != NULL && "unexpected null FileEntry");
> -    assert(Entry->getName() != NULL &&
> -           "unexpected null return from FileEntry::getName()");
> -    llvm::StringRef FileName = Entry->getName();
> -
> -    // Get a copy of the rewritten buffer from the Rewriter.
> -    ResultBuf.clear();
> -    llvm::raw_string_ostream StringStream(ResultBuf);
> -    I->second.write(StringStream);
> -    StringStream.flush();
> -
> -    if (MainFileName == FileName) {
> -      MainFileOverride.swap(ResultBuf);
> -      continue;
> -    }
> -
> -    // Header overrides are treated differently. Eventually, raw replacements
> -    // will be stored as well for later output to disk. Applying replacements
> -    // in memory will always be necessary as the source goes down the transform
> -    // pipeline.
> -    HeaderOverride &HeaderOv = Headers[FileName];
> -    // "Create" HeaderOverride if not already existing
> -    if (HeaderOv.getHeaderPath().empty())
> -      HeaderOv = HeaderOverride(FileName, MainFileName);
> -
> -    HeaderOv.swapContentOverride(ResultBuf);
> -  }
> -
> -  // Separate replacements to header files
> -  Replacements MainFileReplaces;
> -  ReplacementsMap HeadersReplaces;
> -  for (Replacements::const_iterator I = Replaces.begin(), E = Replaces.end();
> -      I != E; ++I) {
> -    llvm::StringRef ReplacementFileName = I->getFilePath();
> -
> -    if (ReplacementFileName == MainFileName) {
> -      MainFileReplaces.insert(*I);
> -      continue;
> -    }
> -
> -    HeadersReplaces[ReplacementFileName].insert(*I);
> -  }
> -
> -  // Record all replacements to headers.
> -  for (ReplacementsMap::const_iterator I = HeadersReplaces.begin(),
> -                                       E = HeadersReplaces.end();
> -       I != E; ++I) {
> -    HeaderOverride &HeaderOv = Headers[I->getKey()];
> -    HeaderOv.recordReplacements(I->getValue());
> -  }
> -
> -  if (TrackChanges)
> -    adjustChangedRanges(MainFileReplaces, HeadersReplaces);
> -}
> -
> -void
> -SourceOverrides::adjustChangedRanges(const Replacements &MainFileReplaces,
> -                                     const ReplacementsMap &HeadersReplaces) {
> -  // Adjust the changed ranges for each individual file
> -  MainFileChanges.adjustChangedRanges(MainFileReplaces);
> -  for (ReplacementsMap::const_iterator I = HeadersReplaces.begin(),
> -                                       E = HeadersReplaces.end();
> -       I != E; ++I) {
> -    Headers[I->getKey()].adjustChangedRanges(I->getValue());
> -  }
> -}
> -
> -void SourceOverrides::applyOverrides(SourceManager &SM) const {
> -  FileManager &FM = SM.getFileManager();
> -
> -  if (isSourceOverriden())
> -    SM.overrideFileContents(FM.getFile(MainFileName),
> -                            llvm::MemoryBuffer::getMemBuffer(MainFileOverride));
> -
> -  for (HeaderOverrides::const_iterator I = Headers.begin(), E = Headers.end();
> -       I != E; ++I) {
> -    assert(!I->second.getContentOverride().empty() &&
> -           "Header override should not be empty!");
> -    SM.overrideFileContents(
> -        FM.getFile(I->second.getHeaderPath()),
> -        llvm::MemoryBuffer::getMemBuffer(I->second.getContentOverride()));
> -  }
> -}
> -
> -bool generateReplacementsFileName(llvm::StringRef SourceFile,
> -                                    llvm::StringRef HeaderFile,
> -                                    llvm::SmallVectorImpl<char> &Result,
> -                                    llvm::SmallVectorImpl<char> &Error) {
> +bool generateReplacementsFileName(const llvm::StringRef MainSourceFile,
> +                                  llvm::SmallVectorImpl<char> &Result,
> +                                  llvm::SmallVectorImpl<char> &Error) {
>   using namespace llvm::sys;
> -  std::string UniqueHeaderNameModel;
> -
> -  // Get the filename portion of the path.
> -  llvm::StringRef SourceFileRef(path::filename(SourceFile));
> -  llvm::StringRef HeaderFileRef(path::filename(HeaderFile));
> -
> -  // Get the actual path for the header file.
> -  llvm::SmallString<128> HeaderPath(HeaderFile);
> -  path::remove_filename(HeaderPath);
> -
> -  // Build the model of the filename.
> -  llvm::raw_string_ostream UniqueHeaderNameStream(UniqueHeaderNameModel);
> -  UniqueHeaderNameStream << SourceFileRef << "_" << HeaderFileRef
> -                         << "_%%_%%_%%_%%_%%_%%" << ".yaml";
> -  path::append(HeaderPath, UniqueHeaderNameStream.str());
> 
>   Error.clear();
> -  if (llvm::error_code EC =
> -          fs::createUniqueFile(HeaderPath.c_str(), Result)) {
> +  if (llvm::error_code EC = fs::createUniqueFile(
> +          MainSourceFile + "_%%_%%_%%_%%_%%_%%.yaml", Result)) {
>     Error.append(EC.message().begin(), EC.message().end());
>     return false;
>   }
> @@ -187,20 +44,6 @@ bool generateReplacementsFileName(llvm::
>   return true;
> }
> 
> -FileOverrides::~FileOverrides() {
> -  for (SourceOverridesMap::iterator I = Overrides.begin(), E = Overrides.end();
> -       I != E; ++I)
> -    delete I->getValue();
> -}
> -
> -SourceOverrides &FileOverrides::getOrCreate(llvm::StringRef Filename) {
> -  SourceOverrides *&Override = Overrides[Filename];
> -
> -  if (Override == NULL)
> -    Override = new SourceOverrides(Filename, TrackChanges);
> -  return *Override;
> -}
> -
> namespace {
> 
> /// \brief Comparator to be able to order tooling::Range based on their offset.
> @@ -247,10 +90,11 @@ struct RangeReplacedAdjuster {
> 
> } // end anonymous namespace
> 
> -void ChangedRanges::adjustChangedRanges(const tooling::Replacements &Replaces) {
> +void
> +ChangedRanges::adjustChangedRanges(const tooling::ReplacementsVec &Replaces) {
>   // first adjust existing ranges in case they overlap with the replacements
> -  for (Replacements::iterator I = Replaces.begin(), E = Replaces.end(); I != E;
> -       ++I) {
> +  for (ReplacementsVec::const_iterator I = Replaces.begin(), E = Replaces.end();
> +       I != E; ++I) {
>     const tooling::Replacement &Replace = *I;
> 
>     std::transform(Ranges.begin(), Ranges.end(), Ranges.begin(),
> @@ -265,8 +109,8 @@ void ChangedRanges::adjustChangedRanges(
>   }
> 
>   // then generate the new ranges from the replacements
> -  for (Replacements::iterator I = Replaces.begin(), E = Replaces.end(); I != E;
> -       ++I) {
> +  for (ReplacementsVec::const_iterator I = Replaces.begin(), E = Replaces.end();
> +       I != E; ++I) {
>     const tooling::Replacement &R = *I;
>     unsigned Offset = tooling::shiftedCodePosition(Replaces, R.getOffset());
>     unsigned Length = R.getReplacementText().size();
> @@ -303,3 +147,52 @@ void ChangedRanges::coalesceRanges() {
>                            std::mem_fun_ref(&Range::contains)),
>                Ranges.end());
> }
> +
> +void FileOverrides::applyOverrides(clang::SourceManager &SM) const {
> +  FileManager &FM = SM.getFileManager();
> +
> +  for (FileStateMap::const_iterator I = FileStates.begin(),
> +                                    E = FileStates.end();
> +       I != E; ++I) {
> +    SM.overrideFileContents(FM.getFile(I->getKey()),
> +                            llvm::MemoryBuffer::getMemBuffer(I->getValue()));
> +  }
> +}
> +
> +void FileOverrides::adjustChangedRanges(
> +    const clang::replace::FileToReplacementsMap &Replaces) {
> +
> +  for (replace::FileToReplacementsMap::const_iterator I = Replaces.begin(),
> +       E = Replaces.end(); I != E; ++I) {
> +    ChangeTracking[I->getKey()].adjustChangedRanges(I->getValue());
> +  }
> +}
> +
> +void FileOverrides::updateState(const clang::Rewriter &Rewrites) {
> +  for (Rewriter::const_buffer_iterator BufferI = Rewrites.buffer_begin(),
> +                                       BufferE = Rewrites.buffer_end();
> +       BufferI != BufferE; ++BufferI) {
> +    const char *FileName =
> +        Rewrites.getSourceMgr().getFileEntryForID(BufferI->first)->getName();
> +    const RewriteBuffer &RewriteBuf = BufferI->second;
> +    FileStates[FileName].assign(RewriteBuf.begin(), RewriteBuf.end());
> +  }
> +}
> +
> +bool FileOverrides::writeToDisk(DiagnosticsEngine &Diagnostics) const {
> +  bool Errors = false;
> +  for (FileStateMap::const_iterator I = FileStates.begin(),
> +                                    E = FileStates.end();
> +       I != E; ++I) {
> +    std::string ErrorInfo;
> +    // The extra transform through std::string is to ensure null-termination
> +    // of the filename stored as the key of the StringMap.
> +    llvm::raw_fd_ostream FileStream(I->getKey().str().c_str(), ErrorInfo);
> +    if (!ErrorInfo.empty()) {
> +      llvm::errs() << "Failed to write new state for " << I->getKey() << ".\n";
> +      Errors = true;
> +    }
> +    FileStream << I->getValue();
> +  }
> +  return !Errors;
> +}
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/Core/FileOverrides.h
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/Core/FileOverrides.h?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/Core/FileOverrides.h (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/Core/FileOverrides.h Fri Aug 30 14:28:59 2013
> @@ -16,7 +16,8 @@
> #ifndef CPP11_MIGRATE_FILE_OVERRIDES_H
> #define CPP11_MIGRATE_FILE_OVERRIDES_H
> 
> -#include "clang/Tooling/Refactoring.h"
> +#include "Core/Refactoring.h"
> +#include "clang-replace/Tooling/ApplyReplacements.h"
> #include "clang/Tooling/ReplacementsYaml.h"
> #include "llvm/ADT/StringMap.h"
> 
> @@ -44,13 +45,13 @@ public:
>   /// to remove replaced parts.
>   ///
>   /// Note that all replacements should come from the same file.
> -  void adjustChangedRanges(const clang::tooling::Replacements &Replaces);
> +  void adjustChangedRanges(const clang::tooling::ReplacementsVec &Replaces);
> 
>   /// \brief Iterators.
> -  /// @{
> +  /// \{
>   const_iterator begin() const { return Ranges.begin(); }
>   const_iterator end() const { return Ranges.end(); }
> -  /// @}
> +  /// \}
> 
> private:
>   void coalesceRanges();
> @@ -58,178 +59,71 @@ private:
>   RangeVec Ranges;
> };
> 
> -/// \brief Container for storing override information for a single headers.
> -class HeaderOverride {
> -public:
> -  /// \brief Constructors.
> -  /// @{
> -  HeaderOverride() {}
> -  HeaderOverride(llvm::StringRef HeaderPath,
> -                 llvm::StringRef MainSourceFile) : HeaderPath(HeaderPath) {
> -    Replacements.MainSourceFile = MainSourceFile;
> -  }
> -  /// @}
> -
> -  /// \brief Getter for HeaderPath.
> -  llvm::StringRef getHeaderPath() const {
> -    return HeaderPath;
> -  }
> -
> -  /// \brief Accessor for ContentOverride.
> -  /// @{
> -  llvm::StringRef getContentOverride() const { return ContentOverride; }
> -  void setContentOverride(const llvm::StringRef S) { ContentOverride = S; }
> -  /// @}
> -
> -  /// \brief Getter for Changes.
> -  const ChangedRanges &getChanges() const { return Changes; }
> -
> -  /// \brief Swaps the content of ContentOverride with \p S.
> -  void swapContentOverride(std::string &S) { ContentOverride.swap(S); }
> -
> -  /// \brief Getter for Replacements.
> -  const clang::tooling::TranslationUnitReplacements &getReplacements() const {
> -    return Replacements;
> -  }
> -
> -  /// \brief Stores the replacements made by a transform to the header this
> -  /// object represents.
> -  void recordReplacements(const clang::tooling::Replacements &Replaces);
> -
> -  /// \brief Helper function to adjust the changed ranges.
> -  void adjustChangedRanges(const clang::tooling::Replacements &Replaces) {
> -    Changes.adjustChangedRanges(Replaces);
> -  }
> -
> -private:
> -  std::string ContentOverride;
> -  ChangedRanges Changes;
> -  std::string HeaderPath;
> -  clang::tooling::TranslationUnitReplacements Replacements;
> -};
> -
> -/// \brief Container mapping header file names to override information.
> -typedef llvm::StringMap<HeaderOverride> HeaderOverrides;
> -
> -/// \brief Container storing the file content overrides for a source file and
> -/// any headers included by the source file either directly or indirectly to
> -/// which changes have been made.
> -class SourceOverrides {
> +/// \brief Maintains current state of transformed files and tracks source ranges
> +/// where changes have been made.
> +class FileOverrides {
> public:
> -  SourceOverrides(llvm::StringRef MainFileName, bool TrackChanges);
> -
> -  /// \brief Accessors.
> -  /// @{
> -  llvm::StringRef getMainFileName() const { return MainFileName; }
> -  llvm::StringRef getMainFileContent() const { return MainFileOverride; }
> -  const ChangedRanges &getChangedRanges() const { return MainFileChanges; }
> +  /// \brief Maps file names to file contents.
> +  typedef llvm::StringMap<std::string> FileStateMap;
> 
> -  /// \brief Is file change tracking enabled?
> -  ///
> -  /// Tracking file changes can be useful to reformat the code for example.
> -  bool isTrackingFileChanges() const { return TrackChanges; }
> -  /// @}
> +  /// \brief Maps file names to change tracking info for a file.
> +  typedef llvm::StringMap<ChangedRanges> ChangeMap;
> 
> -  /// \brief Indicates if the source file has been overridden.
> -  ///
> -  /// It's possible for a source to remain unchanged while only headers are
> -  /// changed.
> -  bool isSourceOverriden() const { return !MainFileOverride.empty(); }
> 
> -  /// \brief Override the file contents by applying all the replacements.
> -  ///
> -  /// \param Replaces The replacements to apply.
> -  /// \param SM A user provided SourceManager to be used when applying rewrites.
> -  void applyReplacements(clang::tooling::Replacements &Replaces,
> -                         clang::SourceManager &SM);
> -  void applyReplacements(clang::tooling::Replacements &Replaces);
> -
> -  /// \brief Convenience function for applying this source's overrides to
> -  /// the given SourceManager.
> +  /// \brief Override file contents seen by \c SM for all files stored by this
> +  /// object.
>   void applyOverrides(clang::SourceManager &SM) const;
> 
> -  /// \brief Iterators.
> -  /// @{
> -  HeaderOverrides::iterator headers_begin() { return Headers.begin(); }
> -  HeaderOverrides::iterator headers_end() { return Headers.end(); }
> -  HeaderOverrides::const_iterator headers_begin() const {
> -    return Headers.begin();
> +  /// \brief Update change tracking information based on replacements stored in
> +  /// \c Replaces.
> +  void
> +  adjustChangedRanges(const clang::replace::FileToReplacementsMap &Replaces);
> +
> +  /// \brief Accessor for change tracking information.
> +  const ChangeMap &getChangedRanges() const {
> +    return ChangeTracking;
>   }
> -  HeaderOverrides::const_iterator headers_end() const { return Headers.end(); }
> -  /// @}
> -
> -private:
> -  typedef llvm::StringMap<clang::tooling::Replacements> ReplacementsMap;
> -
> -  /// \brief Flatten the Rewriter buffers of \p Rewrite and store results as
> -  /// file content overrides.
> -  void applyRewrites(clang::Rewriter &Rewrite);
> -
> -  /// \brief Adjust the changed ranges to reflect the parts of the files that
> -  /// have been replaced.
> -  void adjustChangedRanges(const clang::tooling::Replacements &Replaces,
> -                           const ReplacementsMap &HeadersReplaces);
> -
> -  const std::string MainFileName;
> -  std::string MainFileOverride;
> -  const bool TrackChanges;
> -  ChangedRanges MainFileChanges;
> -  HeaderOverrides Headers;
> -};
> -
> -/// \brief Maps source file names to content override information.
> -class FileOverrides {
> -public:
> -  typedef llvm::StringMap<SourceOverrides *> SourceOverridesMap;
> -  typedef SourceOverridesMap::const_iterator const_iterator;
> 
> -  /// \brief Construct the SourceOverrides manager.
> +  /// \brief Coalesce changes stored in \c Rewrites and replace file contents 
> +  /// overrides stored in this object.
>   ///
> -  /// \param TrackChanges Wether or not the \c SourceOverrides should keep track
> -  /// of changes. See \c SourceOverrides::isTrackingFileChanges().
> -  FileOverrides(bool TrackChanges) : TrackChanges(TrackChanges) {}
> -  ~FileOverrides();
> -
> -  const_iterator find(llvm::StringRef Filename) const {
> -    return Overrides.find(Filename);
> -  }
> +  /// \param Rewrites Rewriter containing changes to files.
> +  void updateState(const clang::Rewriter &Rewrites);
> 
> -  /// \brief Get the \c SourceOverrides for \p Filename, creating it if
> -  /// necessary.
> -  SourceOverrides &getOrCreate(llvm::StringRef Filename);
> +  /// \brief Accessor for current file state.
> +  const FileStateMap &getState() const { return FileStates; }
> 
> -  /// \brief Iterators.
> -  /// @{
> -  const_iterator begin() const { return Overrides.begin(); }
> -  const_iterator end() const { return Overrides.end(); }
> -  /// @}
> +  /// \brief Write all file contents overrides to disk.
> +  ///
> +  /// \param Diagnostics DiagnosticsEngine for error output.
> +  ///
> +  /// \returns \li true if all files with overridden file contents were written
> +  ///              to disk successfully.
> +  ///          \li false if any failure occurred.
> +  bool writeToDisk(clang::DiagnosticsEngine &Diagnostics) const;
> 
> private:
> -  FileOverrides(const FileOverrides &) LLVM_DELETED_FUNCTION;
> -  FileOverrides &operator=(const FileOverrides &) LLVM_DELETED_FUNCTION;
> -
> -  SourceOverridesMap Overrides;
> -  const bool TrackChanges;
> +  FileStateMap FileStates;
> +  ChangeMap ChangeTracking;
> };
> 
> /// \brief Generate a unique filename to store the replacements.
> ///
> -/// Generates a unique filename in the same directory as the header file. The
> -/// filename is based on the following model:
> +/// Generates a unique filename in the same directory as \c MainSourceFile. The
> +/// filename is generated following this pattern:
> ///
> -/// source.cpp_header.h_%%_%%_%%_%%_%%_%%.yaml
> +/// MainSourceFile_%%_%%_%%_%%_%%_%%.yaml
> ///
> /// where all '%' will be replaced by a randomly chosen hex number.
> ///
> -/// @param SourceFile Full path to the source file.
> -/// @param HeaderFile Full path to the header file.
> -/// @param Result The resulting unique filename in the same directory as the
> -///        header file.
> -/// @param Error Description of the error if there is any.
> -/// @returns true if succeeded, false otherwise.
> -bool generateReplacementsFileName(llvm::StringRef SourceFile,
> -                                    llvm::StringRef HeaderFile,
> -                                    llvm::SmallVectorImpl<char> &Result,
> -                                    llvm::SmallVectorImpl<char> &Error);
> +/// \param[in] MainSourceFile Full path to the source file.
> +/// \param[out] Result The resulting unique filename in the same directory as
> +///             the \c MainSourceFile.
> +/// \param[out] Error If an error occurs a description of that error is
> +///             placed in this string.
> +/// \returns true on success, false if a unique file name could not be created.
> +bool generateReplacementsFileName(const llvm::StringRef MainSourceFile,
> +                                  llvm::SmallVectorImpl<char> &Result,
> +                                  llvm::SmallVectorImpl<char> &Error);
> 
> #endif // CPP11_MIGRATE_FILE_OVERRIDES_H
> 
> Added: clang-tools-extra/trunk/cpp11-migrate/Core/Refactoring.h
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/Core/Refactoring.h?rev=189689&view=auto
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/Core/Refactoring.h (added)
> +++ clang-tools-extra/trunk/cpp11-migrate/Core/Refactoring.h Fri Aug 30 14:28:59 2013
> @@ -0,0 +1,31 @@
> +//===-- Core/Refactoring.h - Stand-in for Tooling/Refactoring.h -*- C++ -*-===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +///
> +/// \file
> +/// \brief This file is meant to be used instead of clang/Tooling/Refactoring.h
> +/// until such time as clang::tooling::Replacements is re-implemented as a
> +/// vector instead of a set.
> +///
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef CPP11_MIGRATE_REPLACEMENTS_VEC_H
> +#define CPP11_MIGRATE_REPLACEMENTS_VEC_H
> +
> +#include "clang/Tooling/Refactoring.h"
> +
> +// FIXME: Remove this file when clang::tooling::Replacements becomes a vector
> +// instead of a set.
> +
> +namespace clang {
> +namespace tooling {
> +typedef std::vector<clang::tooling::Replacement> ReplacementsVec;
> +}
> +}
> +
> +#endif // CPP11_MIGRATE_REPLACEMENTS_VEC_H
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/Core/Reformatting.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/Core/Reformatting.cpp?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/Core/Reformatting.cpp (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/Core/Reformatting.cpp Fri Aug 30 14:28:59 2013
> @@ -22,39 +22,23 @@
> 
> using namespace clang;
> 
> -void Reformatter::reformatChanges(SourceOverrides &Overrides) {
> -  llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts(
> -      new DiagnosticOptions());
> -  DiagnosticsEngine Diagnostics(
> -      llvm::IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
> -      DiagOpts.getPtr());
> -  FileManager Files((FileSystemOptions()));
> -  SourceManager SM(Diagnostics, Files);
> -
> -  reformatChanges(Overrides, SM);
> -}
> -
> -void Reformatter::reformatChanges(SourceOverrides &Overrides,
> -                                  clang::SourceManager &SM) {
> -  tooling::Replacements Replaces;
> -  Overrides.applyOverrides(SM);
> -  if (Overrides.isSourceOverriden())
> -    Replaces = reformatSingleFile(Overrides.getMainFileName(),
> -                                  Overrides.getChangedRanges(), SM);
> -
> -  for (HeaderOverrides::const_iterator I = Overrides.headers_begin(),
> -                                       E = Overrides.headers_end();
> +void Reformatter::reformatChanges(const FileOverrides &FileStates,
> +                                  clang::SourceManager &SM,
> +                                  clang::tooling::ReplacementsVec &Replaces) {
> +  FileStates.applyOverrides(SM);
> +
> +  for (FileOverrides::ChangeMap::const_iterator
> +           I = FileStates.getChangedRanges().begin(),
> +           E = FileStates.getChangedRanges().end();
>        I != E; ++I) {
> -    const HeaderOverride &Header = I->getValue();
> -    const tooling::Replacements &HeaderReplaces =
> -        reformatSingleFile(Header.getHeaderPath(), Header.getChanges(), SM);
> -    Replaces.insert(HeaderReplaces.begin(), HeaderReplaces.end());
> +    reformatSingleFile(I->getKey(), I->getValue(), SM, Replaces);
>   }
> -  Overrides.applyReplacements(Replaces, SM);
> }
> 
> -tooling::Replacements Reformatter::reformatSingleFile(
> -    llvm::StringRef FileName, const ChangedRanges &Changes, SourceManager &SM) {
> +void Reformatter::reformatSingleFile(
> +    const llvm::StringRef FileName, const ChangedRanges &Changes,
> +    SourceManager &SM, clang::tooling::ReplacementsVec &FormatReplacements) {
> +
>   const clang::FileEntry *Entry = SM.getFileManager().getFile(FileName);
>   assert(Entry && "expected an existing file");
> 
> @@ -72,5 +56,7 @@ tooling::Replacements Reformatter::refor
>   }
> 
>   Lexer Lex(ID, SM.getBuffer(ID), SM, getFormattingLangOpts(Style.Standard));
> -  return format::reformat(Style, Lex, SM, ReformatRanges);
> +  const tooling::Replacements &R =
> +      format::reformat(Style, Lex, SM, ReformatRanges);
> +  std::copy(R.begin(), R.end(), std::back_inserter(FormatReplacements));
> }
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/Core/Reformatting.h
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/Core/Reformatting.h?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/Core/Reformatting.h (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/Core/Reformatting.h Fri Aug 30 14:28:59 2013
> @@ -16,9 +16,10 @@
> #ifndef CPP11_MIGRATE_REFORMATTING_H
> #define CPP11_MIGRATE_REFORMATTING_H
> 
> +#include "Core/Refactoring.h"
> #include "clang/Format/Format.h"
> 
> -class SourceOverrides;
> +class FileOverrides;
> class ChangedRanges;
> 
> class Reformatter {
> @@ -27,31 +28,30 @@ public:
> 
>   /// \brief Reformat the changes made to the file overrides.
>   ///
> -  /// \param Overrides Overriden source files to reformat. Note that since only
> -  /// the changes are reformatted, file change tracking has to be enabled.
> -  /// \param SM A SourceManager where the overridens files can be found.
> +  /// This function will apply the state of files stored in \c FileState to \c
> +  /// SM.
>   ///
> -  /// \sa \c SourceOverrides::isTrackingFileChanges()
> -  void reformatChanges(SourceOverrides &Overrides, clang::SourceManager &SM);
> -
> -  /// \brief Overload of \c reformatChanges() providing it's own
> -  /// \c SourceManager.
> -  void reformatChanges(SourceOverrides &Overrides);
> +  /// \param[in] FileState Files to reformat.
> +  /// \param[in] SM SourceManager for access to source files.
> +  /// \param[out] Replaces Container to store all reformatting replacements.
> +  void reformatChanges(const FileOverrides &FileState, clang::SourceManager &SM,
> +                       clang::tooling::ReplacementsVec &Replaces);
> 
>   /// \brief Produce a list of replacements to apply on \p FileName, only the
>   /// ranges in \p Changes are replaced.
>   ///
> -  /// Since this routine use \c clang::format::reformat() the rules that applies
> -  /// on the ranges are identical:
> +  /// Since this routine use \c clang::format::reformat() the rules that
> +  /// function applies to ranges also apply here.
>   ///
> -  /// \par
> -  /// Each range is extended on either end to its next bigger logic
> -  /// unit, i.e. everything that might influence its formatting or might be
> -  /// influenced by its formatting.
> -  /// -- \c clang::format::reformat()
> -  clang::tooling::Replacements reformatSingleFile(llvm::StringRef FileName,
> -                                                  const ChangedRanges &Changes,
> -                                                  clang::SourceManager &SM);
> +  /// \param[in] FileName Name of file to reformat.
> +  /// \param[in] Changes Description of where changes were made to the file.
> +  /// \param[in] SM SourceManager required to create replacements.
> +  /// \param[out] FormatReplacements New reformatting replacements are appended
> +  /// to this container.
> +  void reformatSingleFile(const llvm::StringRef FileName,
> +                          const ChangedRanges &Changes,
> +                          clang::SourceManager &SM,
> +                          clang::tooling::ReplacementsVec &FormatReplacements);
> 
> private:
>   clang::format::FormatStyle Style;
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/Core/SyntaxCheck.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/Core/SyntaxCheck.cpp?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/Core/SyntaxCheck.cpp (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/Core/SyntaxCheck.cpp Fri Aug 30 14:28:59 2013
> @@ -30,9 +30,7 @@ public:
>     if (!SyntaxOnlyAction::BeginSourceFileAction(CI, Filename))
>       return false;
> 
> -    FileOverrides::const_iterator I = Overrides.find(Filename);
> -    if (I != Overrides.end())
> -      I->second->applyOverrides(CI.getSourceManager());
> +    Overrides.applyOverrides(CI.getSourceManager());
> 
>     return true;
>   }
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/Core/Transform.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/Core/Transform.cpp?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/Core/Transform.cpp (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/Core/Transform.cpp Fri Aug 30 14:28:59 2013
> @@ -100,13 +100,8 @@ bool Transform::isFileModifiable(const S
> bool Transform::handleBeginSource(CompilerInstance &CI, StringRef Filename) {
>   assert(Overrides != 0 && "Subclass transform didn't provide InputState");
> 
> -  CurrentSource = Filename.str();
> -
> -  FileOverrides::const_iterator I = Overrides->find(CurrentSource);
> -  if (I != Overrides->end())
> -    I->second->applyOverrides(CI.getSourceManager());
> -
> -  Replace.clear();
> +  Overrides->applyOverrides(CI.getSourceManager());
> +  CurrentSource = Filename;
> 
>   if (Options().EnableTiming) {
>     Timings.push_back(std::make_pair(Filename.str(), llvm::TimeRecord()));
> @@ -116,11 +111,7 @@ bool Transform::handleBeginSource(Compil
> }
> 
> void Transform::handleEndSource() {
> -  if (!getReplacements().empty()) {
> -    SourceOverrides &SO = Overrides->getOrCreate(CurrentSource);
> -    SO.applyReplacements(getReplacements());
> -  }
> -
> +  CurrentSource.clear();
>   if (Options().EnableTiming)
>     Timings.back().second += llvm::TimeRecord::getCurrentTime(false);
> }
> @@ -129,6 +120,19 @@ void Transform::addTiming(llvm::StringRe
>   Timings.push_back(std::make_pair(Label.str(), Duration));
> }
> 
> +bool
> +Transform::addReplacementForCurrentTU(const clang::tooling::Replacement &R) {
> +  if (CurrentSource.empty())
> +    return false;
> +
> +  TranslationUnitReplacements &TU = Replacements[CurrentSource];
> +  if (TU.MainSourceFile.empty())
> +    TU.MainSourceFile = CurrentSource;
> +  TU.Replacements.push_back(R);
> +
> +  return true;
> +}
> +
> FrontendActionFactory *Transform::createActionFactory(MatchFinder &Finder) {
>   return new ActionFactory(Finder, /*Owner=*/ *this);
> }
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/Core/Transform.h
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/Core/Transform.h?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/Core/Transform.h (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/Core/Transform.h Fri Aug 30 14:28:59 2013
> @@ -17,7 +17,7 @@
> #define CPP11_MIGRATE_TRANSFORM_H
> 
> #include "Core/IncludeExcludeInfo.h"
> -#include "clang/Tooling/Refactoring.h"
> +#include "Core/Refactoring.h"
> #include "llvm/ADT/OwningPtr.h"
> #include "llvm/Support/CommandLine.h"
> #include "llvm/Support/Registry.h"
> @@ -52,6 +52,12 @@ class MatchFinder;
> 
> class FileOverrides;
> 
> +
> +// \brief Maps main source file names to a TranslationUnitReplacements
> +// structure storing replacements for that translation unit.
> +typedef llvm::StringMap<clang::tooling::TranslationUnitReplacements>
> +TUReplacementsMap;
> +
> /// \brief To group transforms' options together when printing the help.
> extern llvm::cl::OptionCategory TransformsOptionsCategory;
> 
> @@ -99,7 +105,7 @@ public:
>   /// SourcePaths and should take precedence over content of files on disk.
>   /// Upon return, \p ResultStates shall contain the result of performing this
>   /// transform on the files listed in \p SourcePaths.
> -  virtual int apply(FileOverrides &InputStates,
> +  virtual int apply(const FileOverrides &InputStates,
>                     const clang::tooling::CompilationDatabase &Database,
>                     const std::vector<std::string> &SourcePaths) = 0;
> 
> @@ -172,6 +178,17 @@ public:
>   /// \brief Return an iterator to the start of collected timing data.
>   TimingVec::const_iterator timing_end() const { return Timings.end(); }
> 
> +  /// \brief Add a Replacement to the list for the current translation unit.
> +  ///
> +  /// \returns \li true on success
> +  ///          \li false if there is no current translation unit
> +  bool addReplacementForCurrentTU(const clang::tooling::Replacement &R);
> +
> +  /// \brief Accessor to Replacements across all transformed translation units.
> +  const TUReplacementsMap &getAllReplacements() const {
> +    return Replacements;
> +  }
> +
> protected:
> 
>   void setAcceptedChanges(unsigned Changes) {
> @@ -195,16 +212,12 @@ protected:
>   /// created with.
>   const TransformOptions &Options() { return GlobalOptions; }
> 
> -  /// \brief Provide access for subclasses for the container to store
> -  /// translation unit replacements.
> -  clang::tooling::Replacements &getReplacements() { return Replace; }
> -
>   /// \brief Affords a subclass to provide file contents overrides before
>   /// applying frontend actions.
>   ///
>   /// It is an error not to call this function before calling ClangTool::run()
>   /// with the factory provided by createActionFactory().
> -  void setOverrides(FileOverrides &Overrides) {
> +  void setOverrides(const FileOverrides &Overrides) {
>     this->Overrides = &Overrides;
>   }
> 
> @@ -219,8 +232,8 @@ protected:
> private:
>   const std::string Name;
>   const TransformOptions &GlobalOptions;
> -  FileOverrides *Overrides;
> -  clang::tooling::Replacements Replace;
> +  const FileOverrides *Overrides;
> +  TUReplacementsMap Replacements;
>   std::string CurrentSource;
>   TimingVec Timings;
>   unsigned AcceptedChanges;
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/LoopConvert/LoopActions.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/LoopConvert/LoopActions.cpp?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/LoopConvert/LoopActions.cpp (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/LoopConvert/LoopActions.cpp Fri Aug 30 14:28:59 2013
> @@ -815,9 +815,9 @@ void LoopFixer::doConversion(ASTContext
>       // the declaration of the alias variable. This is probably a bug.
>       ReplacementText = ";";
> 
> -    Replace->insert(Replacement(Context->getSourceManager(),
> -                                CharSourceRange::getTokenRange(ReplaceRange),
> -                                ReplacementText));
> +    Owner.addReplacementForCurrentTU(Replacement(
> +        Context->getSourceManager(),
> +        CharSourceRange::getTokenRange(ReplaceRange), ReplacementText));
>     // No further replacements are made to the loop, since the iterator or index
>     // was used exactly once - in the initialization of AliasVar.
>   } else {
> @@ -830,10 +830,9 @@ void LoopFixer::doConversion(ASTContext
>          I != E; ++I) {
>       std::string ReplaceText = I->IsArrow ? VarName + "." : VarName;
>       ReplacedVarRanges->insert(std::make_pair(TheLoop, IndexVar));
> -      Replace->insert(
> +      Owner.addReplacementForCurrentTU(
>           Replacement(Context->getSourceManager(),
> -                      CharSourceRange::getTokenRange(I->Range),
> -                      ReplaceText));
> +                      CharSourceRange::getTokenRange(I->Range), ReplaceText));
>     }
>   }
> 
> @@ -862,9 +861,9 @@ void LoopFixer::doConversion(ASTContext
>   std::string TypeString = AutoRefType.getAsString();
>   std::string Range = ("(" + TypeString + " " + VarName + " : "
>                            + MaybeDereference + ContainerString + ")").str();
> -  Replace->insert(Replacement(Context->getSourceManager(),
> -                              CharSourceRange::getTokenRange(ParenRange),
> -                              Range));
> +  Owner.addReplacementForCurrentTU(
> +      Replacement(Context->getSourceManager(),
> +                  CharSourceRange::getTokenRange(ParenRange), Range));
>   GeneratedDecls->insert(make_pair(TheLoop, VarName));
> }
> 
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/LoopConvert/LoopActions.h
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/LoopConvert/LoopActions.h?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/LoopConvert/LoopActions.h (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/LoopConvert/LoopActions.h Fri Aug 30 14:28:59 2013
> @@ -41,12 +41,11 @@ enum LoopFixerKind {
> class LoopFixer : public clang::ast_matchers::MatchFinder::MatchCallback {
>  public:
>    LoopFixer(StmtAncestorASTVisitor *ParentFinder,
> -             clang::tooling::Replacements *Replace,
>              StmtGeneratedVarNameMap *GeneratedDecls,
>              ReplacedVarsMap *ReplacedVarRanges, unsigned *AcceptedChanges,
>              unsigned *DeferredChanges, unsigned *RejectedChanges,
> -             RiskLevel MaxRisk, LoopFixerKind FixerKind, const Transform &Owner)
> -       : ParentFinder(ParentFinder), Replace(Replace),
> +             RiskLevel MaxRisk, LoopFixerKind FixerKind, Transform &Owner)
> +       : ParentFinder(ParentFinder),
>          GeneratedDecls(GeneratedDecls), ReplacedVarRanges(ReplacedVarRanges),
>          AcceptedChanges(AcceptedChanges), DeferredChanges(DeferredChanges),
>          RejectedChanges(RejectedChanges), MaxRisk(MaxRisk),
> @@ -57,7 +56,6 @@ class LoopFixer : public clang::ast_matc
> 
>  private:
>   StmtAncestorASTVisitor *ParentFinder;
> -  clang::tooling::Replacements *Replace;
>   StmtGeneratedVarNameMap *GeneratedDecls;
>   ReplacedVarsMap *ReplacedVarRanges;
>   unsigned *AcceptedChanges;
> @@ -65,7 +63,7 @@ class LoopFixer : public clang::ast_matc
>   unsigned *RejectedChanges;
>   RiskLevel MaxRisk;
>   LoopFixerKind FixerKind;
> -  const Transform &Owner;
> +  Transform &Owner;
> 
>   /// \brief Computes the changes needed to convert a given for loop, and
>   /// applies it.
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/LoopConvert/LoopConvert.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/LoopConvert/LoopConvert.cpp?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/LoopConvert/LoopConvert.cpp (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/LoopConvert/LoopConvert.cpp Fri Aug 30 14:28:59 2013
> @@ -24,7 +24,7 @@ using clang::ast_matchers::MatchFinder;
> using namespace clang::tooling;
> using namespace clang;
> 
> -int LoopConvertTransform::apply(FileOverrides &InputStates,
> +int LoopConvertTransform::apply(const FileOverrides &InputStates,
>                                 const CompilationDatabase &Database,
>                                 const std::vector<std::string> &SourcePaths) {
>   ClangTool LoopTool(Database, SourcePaths);
> @@ -37,20 +37,20 @@ int LoopConvertTransform::apply(FileOver
>   unsigned RejectedChanges = 0;
> 
>   MatchFinder Finder;
> -  LoopFixer ArrayLoopFixer(&ParentFinder, &getReplacements(), &GeneratedDecls,
> -                           &ReplacedVars, &AcceptedChanges, &DeferredChanges,
> -                           &RejectedChanges, Options().MaxRiskLevel, LFK_Array,
> +  LoopFixer ArrayLoopFixer(&ParentFinder, &GeneratedDecls, &ReplacedVars,
> +                           &AcceptedChanges, &DeferredChanges, &RejectedChanges,
> +                           Options().MaxRiskLevel, LFK_Array,
>                            /*Owner=*/ *this);
>   Finder.addMatcher(makeArrayLoopMatcher(), &ArrayLoopFixer);
> -  LoopFixer IteratorLoopFixer(
> -      &ParentFinder, &getReplacements(), &GeneratedDecls, &ReplacedVars,
> -      &AcceptedChanges, &DeferredChanges, &RejectedChanges,
> -      Options().MaxRiskLevel, LFK_Iterator, /*Owner=*/ *this);
> +  LoopFixer IteratorLoopFixer(&ParentFinder, &GeneratedDecls, &ReplacedVars,
> +                              &AcceptedChanges, &DeferredChanges,
> +                              &RejectedChanges, Options().MaxRiskLevel,
> +                              LFK_Iterator, /*Owner=*/ *this);
>   Finder.addMatcher(makeIteratorLoopMatcher(), &IteratorLoopFixer);
> -  LoopFixer PseudoarrrayLoopFixer(
> -      &ParentFinder, &getReplacements(), &GeneratedDecls, &ReplacedVars,
> -      &AcceptedChanges, &DeferredChanges, &RejectedChanges,
> -      Options().MaxRiskLevel, LFK_PseudoArray, /*Owner=*/ *this);
> +  LoopFixer PseudoarrrayLoopFixer(&ParentFinder, &GeneratedDecls, &ReplacedVars,
> +                                  &AcceptedChanges, &DeferredChanges,
> +                                  &RejectedChanges, Options().MaxRiskLevel,
> +                                  LFK_PseudoArray, /*Owner=*/ *this);
>   Finder.addMatcher(makePseudoArrayLoopMatcher(), &PseudoarrrayLoopFixer);
> 
>   setOverrides(InputStates);
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/LoopConvert/LoopConvert.h
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/LoopConvert/LoopConvert.h?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/LoopConvert/LoopConvert.h (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/LoopConvert/LoopConvert.h Fri Aug 30 14:28:59 2013
> @@ -28,7 +28,7 @@ public:
>       : Transform("LoopConvert", Options) {}
> 
>   /// \see Transform::run().
> -  virtual int apply(FileOverrides &InputStates,
> +  virtual int apply(const FileOverrides &InputStates,
>                     const clang::tooling::CompilationDatabase &Database,
>                     const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE;
> };
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/PassByValue/PassByValue.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/PassByValue/PassByValue.cpp?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/PassByValue/PassByValue.cpp (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/PassByValue/PassByValue.cpp Fri Aug 30 14:28:59 2013
> @@ -21,15 +21,14 @@ using namespace clang;
> using namespace clang::tooling;
> using namespace clang::ast_matchers;
> 
> -int PassByValueTransform::apply(
> -    FileOverrides &InputStates, const tooling::CompilationDatabase &Database,
> -    const std::vector<std::string> &SourcePaths) {
> +int PassByValueTransform::apply(const FileOverrides &InputStates,
> +                                const tooling::CompilationDatabase &Database,
> +                                const std::vector<std::string> &SourcePaths) {
>   ClangTool Tool(Database, SourcePaths);
>   unsigned AcceptedChanges = 0;
>   unsigned RejectedChanges = 0;
>   MatchFinder Finder;
> -  ConstructorParamReplacer Replacer(getReplacements(), AcceptedChanges,
> -                                    RejectedChanges,
> +  ConstructorParamReplacer Replacer(AcceptedChanges, RejectedChanges,
>                                     /*Owner=*/ *this);
> 
>   Finder.addMatcher(makePassByValueCtorParamMatcher(), &Replacer);
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/PassByValue/PassByValue.h
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/PassByValue/PassByValue.h?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/PassByValue/PassByValue.h (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/PassByValue/PassByValue.h Fri Aug 30 14:28:59 2013
> @@ -58,7 +58,7 @@ public:
>       : Transform("PassByValue", Options), Replacer(0) {}
> 
>   /// \see Transform::apply().
> -  virtual int apply(FileOverrides &InputStates,
> +  virtual int apply(const FileOverrides &InputStates,
>                     const clang::tooling::CompilationDatabase &Database,
>                     const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE;
> 
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/PassByValue/PassByValueActions.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/PassByValue/PassByValueActions.cpp?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/PassByValue/PassByValueActions.cpp (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/PassByValue/PassByValueActions.cpp Fri Aug 30 14:28:59 2013
> @@ -151,17 +151,21 @@ void ConstructorParamReplacer::run(const
>   const tooling::Replacement &IncludeReplace =
>       IncludeManager->addAngledInclude(STDMoveFile, "utility");
>   if (IncludeReplace.isApplicable()) {
> -    Replaces.insert(IncludeReplace);
> +    Owner.addReplacementForCurrentTU(IncludeReplace);
>     AcceptedChanges++;
>   }
> 
>   // const-ref params becomes values (const Foo & -> Foo)
> -  Replaces.insert(ParamReplaces.begin(), ParamReplaces.end());
> +  for (const Replacement *I = ParamReplaces.begin(), *E = ParamReplaces.end();
> +       I != E; ++I) {
> +    Owner.addReplacementForCurrentTU(*I);
> +  }
>   AcceptedChanges += ParamReplaces.size();
> 
>   // move the value in the init-list
> -  Replaces.insert(Replacement(
> +  Owner.addReplacementForCurrentTU(Replacement(
>       SM, Initializer->getLParenLoc().getLocWithOffset(1), 0, "std::move("));
> -  Replaces.insert(Replacement(SM, Initializer->getRParenLoc(), 0, ")"));
> +  Owner.addReplacementForCurrentTU(
> +      Replacement(SM, Initializer->getRParenLoc(), 0, ")"));
>   AcceptedChanges += 2;
> }
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/PassByValue/PassByValueActions.h
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/PassByValue/PassByValueActions.h?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/PassByValue/PassByValueActions.h (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/PassByValue/PassByValueActions.h Fri Aug 30 14:28:59 2013
> @@ -51,11 +51,10 @@ class IncludeDirectives;
> class ConstructorParamReplacer
>     : public clang::ast_matchers::MatchFinder::MatchCallback {
> public:
> -  ConstructorParamReplacer(clang::tooling::Replacements &Replaces,
> -                           unsigned &AcceptedChanges, unsigned &RejectedChanges,
> -                           const Transform &Owner)
> -      : Replaces(Replaces), AcceptedChanges(AcceptedChanges),
> -        RejectedChanges(RejectedChanges), Owner(Owner), IncludeManager(0) {}
> +  ConstructorParamReplacer(unsigned &AcceptedChanges, unsigned &RejectedChanges,
> +                           Transform &Owner)
> +      : AcceptedChanges(AcceptedChanges), RejectedChanges(RejectedChanges),
> +        Owner(Owner), IncludeManager(0) {}
> 
>   void setIncludeDirectives(IncludeDirectives *Includes) {
>     IncludeManager = Includes;
> @@ -66,10 +65,9 @@ private:
>   virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result)
>       LLVM_OVERRIDE;
> 
> -  clang::tooling::Replacements &Replaces;
>   unsigned &AcceptedChanges;
>   unsigned &RejectedChanges;
> -  const Transform &Owner;
> +  Transform &Owner;
>   IncludeDirectives *IncludeManager;
> };
> 
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.cpp?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.cpp (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.cpp Fri Aug 30 14:28:59 2013
> @@ -22,16 +22,14 @@ using namespace clang::tooling;
> using namespace clang::ast_matchers;
> 
> int
> -ReplaceAutoPtrTransform::apply(FileOverrides &InputStates,
> +ReplaceAutoPtrTransform::apply(const FileOverrides &InputStates,
>                                const CompilationDatabase &Database,
>                                const std::vector<std::string> &SourcePaths) {
>   ClangTool Tool(Database, SourcePaths);
>   unsigned AcceptedChanges = 0;
>   MatchFinder Finder;
> -  AutoPtrReplacer Replacer(getReplacements(), AcceptedChanges,
> -                           /*Owner=*/*this);
> -  OwnershipTransferFixer Fixer(getReplacements(), AcceptedChanges,
> -                                   /*Owner=*/*this);
> +  AutoPtrReplacer Replacer(AcceptedChanges, /*Owner=*/ *this);
> +  OwnershipTransferFixer Fixer(AcceptedChanges, /*Owner=*/ *this);
> 
>   Finder.addMatcher(makeAutoPtrTypeLocMatcher(), &Replacer);
>   Finder.addMatcher(makeAutoPtrUsingDeclMatcher(), &Replacer);
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.h
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.h?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.h (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.h Fri Aug 30 14:28:59 2013
> @@ -47,7 +47,7 @@ public:
>       : Transform("ReplaceAutoPtr", Options) {}
> 
>   /// \see Transform::run().
> -  virtual int apply(FileOverrides &InputStates,
> +  virtual int apply(const FileOverrides &InputStates,
>                     const clang::tooling::CompilationDatabase &Database,
>                     const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE;
> };
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.cpp?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.cpp (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.cpp Fri Aug 30 14:28:59 2013
> @@ -66,7 +66,7 @@ void AutoPtrReplacer::run(const MatchFin
>   if (!checkTokenIsAutoPtr(IdentifierLoc, SM, LangOptions()))
>     return;
> 
> -  Replace.insert(
> +  Owner.addReplacementForCurrentTU(
>       Replacement(SM, IdentifierLoc, strlen("auto_ptr"), "unique_ptr"));
>   ++AcceptedChanges;
> }
> @@ -101,7 +101,8 @@ void OwnershipTransferFixer::run(const M
>   if (!Owner.isFileModifiable(SM, Range.getBegin()))
>     return;
> 
> -  Replace.insert(Replacement(SM, Range.getBegin(), 0, "std::move("));
> -  Replace.insert(Replacement(SM, Range.getEnd(), 0, ")"));
> +  Owner.addReplacementForCurrentTU(
> +      Replacement(SM, Range.getBegin(), 0, "std::move("));
> +  Owner.addReplacementForCurrentTU(Replacement(SM, Range.getEnd(), 0, ")"));
>   AcceptedChanges += 2;
> }
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.h
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.h?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.h (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.h Fri Aug 30 14:28:59 2013
> @@ -25,9 +25,8 @@ class Transform;
> /// using declarations.
> class AutoPtrReplacer : public clang::ast_matchers::MatchFinder::MatchCallback {
> public:
> -  AutoPtrReplacer(clang::tooling::Replacements &Replace,
> -                  unsigned &AcceptedChanges, const Transform &Owner)
> -      : Replace(Replace), AcceptedChanges(AcceptedChanges), Owner(Owner) {}
> +  AutoPtrReplacer(unsigned &AcceptedChanges, Transform &Owner)
> +      : AcceptedChanges(AcceptedChanges), Owner(Owner) {}
> 
>   /// \brief Entry point to the callback called when matches are made.
>   virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result)
> @@ -63,9 +62,8 @@ private:
>                       const clang::SourceManager &SM);
> 
> private:
> -  clang::tooling::Replacements &Replace;
>   unsigned &AcceptedChanges;
> -  const Transform &Owner;
> +  Transform &Owner;
> };
> 
> /// \brief The callback to be used to fix the ownership transfers of
> @@ -86,18 +84,16 @@ private:
> class OwnershipTransferFixer
>     : public clang::ast_matchers::MatchFinder::MatchCallback {
> public:
> -  OwnershipTransferFixer(clang::tooling::Replacements &Replace,
> -                         unsigned &AcceptedChanges, const Transform &Owner)
> -      : Replace(Replace), AcceptedChanges(AcceptedChanges), Owner(Owner) {}
> +  OwnershipTransferFixer(unsigned &AcceptedChanges, Transform &Owner)
> +      : AcceptedChanges(AcceptedChanges), Owner(Owner) {}
> 
>   /// \brief Entry point to the callback called when matches are made.
>   virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result)
>       LLVM_OVERRIDE;
> 
> private:
> -  clang::tooling::Replacements &Replace;
>   unsigned &AcceptedChanges;
> -  const Transform &Owner;
> +  Transform &Owner;
> };
> 
> #endif // CPP11_MIGRATE_REPLACE_AUTO_PTR_ACTIONS_H
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/UseAuto/UseAuto.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/UseAuto/UseAuto.cpp?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/UseAuto/UseAuto.cpp (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/UseAuto/UseAuto.cpp Fri Aug 30 14:28:59 2013
> @@ -20,7 +20,7 @@ using clang::ast_matchers::MatchFinder;
> using namespace clang;
> using namespace clang::tooling;
> 
> -int UseAutoTransform::apply(FileOverrides &InputStates,
> +int UseAutoTransform::apply(const FileOverrides &InputStates,
>                             const clang::tooling::CompilationDatabase &Database,
>                             const std::vector<std::string> &SourcePaths) {
>   ClangTool UseAutoTool(Database, SourcePaths);
> @@ -28,10 +28,11 @@ int UseAutoTransform::apply(FileOverride
>   unsigned AcceptedChanges = 0;
> 
>   MatchFinder Finder;
> -  IteratorReplacer ReplaceIterators(getReplacements(), AcceptedChanges,
> -                                    Options().MaxRiskLevel, /*Owner=*/ *this);
> -  NewReplacer ReplaceNew(getReplacements(), AcceptedChanges,
> -                         Options().MaxRiskLevel, /*Owner=*/ *this);
> +  ReplacementsVec Replaces;
> +  IteratorReplacer ReplaceIterators(AcceptedChanges, Options().MaxRiskLevel,
> +                                    /*Owner=*/ *this);
> +  NewReplacer ReplaceNew(AcceptedChanges, Options().MaxRiskLevel,
> +                         /*Owner=*/ *this);
> 
>   Finder.addMatcher(makeIteratorDeclMatcher(), &ReplaceIterators);
>   Finder.addMatcher(makeDeclWithNewMatcher(), &ReplaceNew);
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/UseAuto/UseAuto.h
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/UseAuto/UseAuto.h?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/UseAuto/UseAuto.h (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/UseAuto/UseAuto.h Fri Aug 30 14:28:59 2013
> @@ -34,7 +34,7 @@ public:
>       : Transform("UseAuto", Options) {}
> 
>   /// \see Transform::run().
> -  virtual int apply(FileOverrides &InputStates,
> +  virtual int apply(const FileOverrides &InputStates,
>                     const clang::tooling::CompilationDatabase &Database,
>                     const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE;
> };
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/UseAuto/UseAutoActions.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/UseAuto/UseAutoActions.cpp?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/UseAuto/UseAutoActions.cpp (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/UseAuto/UseAutoActions.cpp Fri Aug 30 14:28:59 2013
> @@ -73,7 +73,7 @@ void IteratorReplacer::run(const MatchFi
>   // iterators but something to keep in mind in the future.
> 
>   CharSourceRange Range(TL.getSourceRange(), true);
> -  Replace.insert(tooling::Replacement(SM, Range, "auto"));
> +  Owner.addReplacementForCurrentTU(tooling::Replacement(SM, Range, "auto"));
>   ++AcceptedChanges;
> }
> 
> @@ -131,8 +131,9 @@ void NewReplacer::run(const MatchFinder:
>   for (std::vector<SourceLocation>::iterator I = StarLocations.begin(),
>                                              E = StarLocations.end();
>        I != E; ++I) {
> -    Replace.insert(tooling::Replacement(SM, *I, 1, ""));
> +    Owner.addReplacementForCurrentTU(tooling::Replacement(SM, *I, 1, ""));
>   }
> +
>   // FIXME: There is, however, one case we can address: when the VarDecl
>   // pointee is the same as the initializer, just more CV-qualified. However,
>   // TypeLoc information is not reliable where CV qualifiers are concerned so
> @@ -141,6 +142,6 @@ void NewReplacer::run(const MatchFinder:
>       FirstDecl->getTypeSourceInfo()->getTypeLoc().getSourceRange(), true);
>   // Space after 'auto' to handle cases where the '*' in the pointer type
>   // is next to the identifier. This avoids changing 'int *p' into 'autop'.
> -  Replace.insert(tooling::Replacement(SM, Range, "auto "));
> +  Owner.addReplacementForCurrentTU(tooling::Replacement(SM, Range, "auto "));
>   ++AcceptedChanges;
> }
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/UseAuto/UseAutoActions.h
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/UseAuto/UseAutoActions.h?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/UseAuto/UseAutoActions.h (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/UseAuto/UseAutoActions.h Fri Aug 30 14:28:59 2013
> @@ -25,36 +25,32 @@
> class IteratorReplacer
>     : public clang::ast_matchers::MatchFinder::MatchCallback {
> public:
> -  IteratorReplacer(clang::tooling::Replacements &Replace,
> -                   unsigned &AcceptedChanges, RiskLevel, const Transform &Owner)
> -      : Replace(Replace), AcceptedChanges(AcceptedChanges), Owner(Owner) {}
> +  IteratorReplacer(unsigned &AcceptedChanges, RiskLevel, Transform &Owner)
> +      : AcceptedChanges(AcceptedChanges), Owner(Owner) {}
> 
>   /// \brief Entry point to the callback called when matches are made.
>   virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result)
>       LLVM_OVERRIDE;
> 
> private:
> -  clang::tooling::Replacements &Replace;
>   unsigned &AcceptedChanges;
> -  const Transform &Owner;
> +  Transform &Owner;
> };
> 
> /// \brief The callback used when replacing type specifiers of variable
> /// declarations initialized by a C++ new expression.
> class NewReplacer : public clang::ast_matchers::MatchFinder::MatchCallback {
> public:
> -  NewReplacer(clang::tooling::Replacements &Replace, unsigned &AcceptedChanges,
> -              RiskLevel, const Transform &Owner)
> -      : Replace(Replace), AcceptedChanges(AcceptedChanges), Owner(Owner) {}
> +  NewReplacer(unsigned &AcceptedChanges, RiskLevel, Transform &Owner)
> +      : AcceptedChanges(AcceptedChanges), Owner(Owner) {}
> 
>   /// \brief Entry point to the callback called when matches are made.
>   virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result)
>       LLVM_OVERRIDE;
> 
> private:
> -  clang::tooling::Replacements &Replace;
>   unsigned &AcceptedChanges;
> -  const Transform &Owner;
> +  Transform &Owner;
> };
> 
> #endif // CPP11_MIGRATE_USE_AUTO_ACTIONS_H
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/UseNullptr/NullptrActions.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/UseNullptr/NullptrActions.cpp?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/UseNullptr/NullptrActions.cpp (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/UseNullptr/NullptrActions.cpp Fri Aug 30 14:28:59 2013
> @@ -47,7 +47,7 @@ bool isReplaceableRange(SourceLocation S
> /// \brief Replaces the provided range with the text "nullptr", but only if
> /// the start and end location are both in main file.
> /// Returns true if and only if a replacement was made.
> -void ReplaceWithNullptr(tooling::Replacements &Replace, SourceManager &SM,
> +void ReplaceWithNullptr(Transform &Owner, SourceManager &SM,
>                         SourceLocation StartLoc, SourceLocation EndLoc) {
>   CharSourceRange Range(SourceRange(StartLoc, EndLoc), true);
>   // Add a space if nullptr follows an alphanumeric character. This happens
> @@ -55,9 +55,11 @@ void ReplaceWithNullptr(tooling::Replace
>   // parentheses and right beside a return statement.
>   SourceLocation PreviousLocation = StartLoc.getLocWithOffset(-1);
>   if (isAlphanumeric(*FullSourceLoc(PreviousLocation, SM).getCharacterData()))
> -    Replace.insert(tooling::Replacement(SM, Range, " nullptr"));
> +    Owner.addReplacementForCurrentTU(
> +        tooling::Replacement(SM, Range, " nullptr"));
>   else
> -    Replace.insert(tooling::Replacement(SM, Range, "nullptr"));
> +    Owner.addReplacementForCurrentTU(
> +        tooling::Replacement(SM, Range, "nullptr"));
> }
> 
> /// \brief Returns the name of the outermost macro.
> @@ -153,10 +155,9 @@ private:
> /// ambiguities.
> class CastSequenceVisitor : public RecursiveASTVisitor<CastSequenceVisitor> {
> public:
> -  CastSequenceVisitor(tooling::Replacements &R, ASTContext &Context,
> -                      const UserMacroNames &UserNullMacros,
> -                      unsigned &AcceptedChanges, const Transform &Owner)
> -      : Replace(R), SM(Context.getSourceManager()), Context(Context),
> +  CastSequenceVisitor(ASTContext &Context, const UserMacroNames &UserNullMacros,
> +                      unsigned &AcceptedChanges, Transform &Owner)
> +      : SM(Context.getSourceManager()), Context(Context),
>         UserNullMacros(UserNullMacros), AcceptedChanges(AcceptedChanges),
>         Owner(Owner), FirstSubExpr(0), PruneSubtree(false) {}
> 
> @@ -196,7 +197,7 @@ public:
>                        FileLocEnd = SM.getFileLoc(EndLoc);
>         if (isReplaceableRange(FileLocStart, FileLocEnd, SM, Owner) &&
>             allArgUsesValid(C)) {
> -          ReplaceWithNullptr(Replace, SM, FileLocStart, FileLocEnd);
> +          ReplaceWithNullptr(Owner, SM, FileLocStart, FileLocEnd);
>           ++AcceptedChanges;
>         }
>         return skipSubTree();
> @@ -220,7 +221,7 @@ public:
>       if (!isReplaceableRange(StartLoc, EndLoc, SM, Owner)) {
>         return skipSubTree();
>       }
> -      ReplaceWithNullptr(Replace, SM, StartLoc, EndLoc);
> +      ReplaceWithNullptr(Owner, SM, StartLoc, EndLoc);
>       ++AcceptedChanges;
> 
>       return skipSubTree();
> @@ -417,21 +418,19 @@ private:
>   }
> 
> private:
> -  tooling::Replacements &Replace;
>   SourceManager &SM;
>   ASTContext &Context;
>   const UserMacroNames &UserNullMacros;
>   unsigned &AcceptedChanges;
> -  const Transform &Owner;
> +  Transform &Owner;
>   Expr *FirstSubExpr;
>   bool PruneSubtree;
> };
> } // namespace
> 
> -NullptrFixer::NullptrFixer(clang::tooling::Replacements &Replace,
> -                           unsigned &AcceptedChanges, RiskLevel,
> -                           const Transform &Owner)
> -    : Replace(Replace), AcceptedChanges(AcceptedChanges), Owner(Owner) {
> +NullptrFixer::NullptrFixer(unsigned &AcceptedChanges, RiskLevel,
> +                           Transform &Owner)
> +    : AcceptedChanges(AcceptedChanges), Owner(Owner) {
>   if (!UserNullMacroNames.empty()) {
>     llvm::StringRef S = UserNullMacroNames;
>     S.split(UserNullMacros, ",");
> @@ -445,7 +444,7 @@ void NullptrFixer::run(const ast_matcher
>   // Given an implicit null-ptr cast or an explicit cast with an implicit
>   // null-to-pointer cast within use CastSequenceVisitor to identify sequences
>   // of explicit casts that can be converted into 'nullptr'.
> -  CastSequenceVisitor Visitor(Replace, *Result.Context, UserNullMacros,
> -                              AcceptedChanges, Owner);
> +  CastSequenceVisitor Visitor(*Result.Context, UserNullMacros, AcceptedChanges,
> +                              Owner);
>   Visitor.TraverseStmt(const_cast<CastExpr *>(NullCast));
> }
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/UseNullptr/NullptrActions.h
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/UseNullptr/NullptrActions.h?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/UseNullptr/NullptrActions.h (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/UseNullptr/NullptrActions.h Fri Aug 30 14:28:59 2013
> @@ -27,17 +27,15 @@ typedef llvm::SmallVector<llvm::StringRe
> ///
> class NullptrFixer : public clang::ast_matchers::MatchFinder::MatchCallback {
> public:
> -  NullptrFixer(clang::tooling::Replacements &Replace, unsigned &AcceptedChanges,
> -               RiskLevel, const Transform &Owner);
> +  NullptrFixer(unsigned &AcceptedChanges, RiskLevel, Transform &Owner);
> 
>   /// \brief Entry point to the callback called when matches are made.
>   virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result);
> 
> private:
> -  clang::tooling::Replacements &Replace;
>   unsigned &AcceptedChanges;
>   UserMacroNames UserNullMacros;
> -  const Transform &Owner;
> +  Transform &Owner;
> };
> 
> #endif // CPP11_MIGRATE_NULLPTR_ACTIONS_H
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/UseNullptr/UseNullptr.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/UseNullptr/UseNullptr.cpp?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/UseNullptr/UseNullptr.cpp (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/UseNullptr/UseNullptr.cpp Fri Aug 30 14:28:59 2013
> @@ -24,7 +24,7 @@ using clang::ast_matchers::MatchFinder;
> using namespace clang::tooling;
> using namespace clang;
> 
> -int UseNullptrTransform::apply(FileOverrides &InputStates,
> +int UseNullptrTransform::apply(const FileOverrides &InputStates,
>                                const CompilationDatabase &Database,
>                                const std::vector<std::string> &SourcePaths) {
>   ClangTool UseNullptrTool(Database, SourcePaths);
> @@ -32,8 +32,7 @@ int UseNullptrTransform::apply(FileOverr
>   unsigned AcceptedChanges = 0;
> 
>   MatchFinder Finder;
> -  NullptrFixer Fixer(getReplacements(), AcceptedChanges, Options().MaxRiskLevel,
> -                     /*Owner=*/ *this);
> +  NullptrFixer Fixer(AcceptedChanges, Options().MaxRiskLevel, /*Owner=*/ *this);
> 
>   Finder.addMatcher(makeCastSequenceMatcher(), &Fixer);
> 
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/UseNullptr/UseNullptr.h
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/UseNullptr/UseNullptr.h?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/UseNullptr/UseNullptr.h (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/UseNullptr/UseNullptr.h Fri Aug 30 14:28:59 2013
> @@ -28,7 +28,7 @@ public:
>       : Transform("UseNullptr", Options) {}
> 
>   /// \see Transform::run().
> -  virtual int apply(FileOverrides &InputStates,
> +  virtual int apply(const FileOverrides &InputStates,
>                     const clang::tooling::CompilationDatabase &Database,
>                     const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE;
> };
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/tool/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/tool/CMakeLists.txt?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/tool/CMakeLists.txt (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/tool/CMakeLists.txt Fri Aug 30 14:28:59 2013
> @@ -34,6 +34,7 @@ add_dependencies(cpp11-migrate
>   )
> 
> target_link_libraries(cpp11-migrate
> +  clangReplace
>   migrateCore
>   )
> 
> 
> Modified: clang-tools-extra/trunk/cpp11-migrate/tool/Cpp11Migrate.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/tool/Cpp11Migrate.cpp?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/cpp11-migrate/tool/Cpp11Migrate.cpp (original)
> +++ clang-tools-extra/trunk/cpp11-migrate/tool/Cpp11Migrate.cpp Fri Aug 30 14:28:59 2013
> @@ -21,9 +21,14 @@
> #include "Core/Transform.h"
> #include "Core/Transforms.h"
> #include "Core/Reformatting.h"
> +#include "clang/Basic/Diagnostic.h"
> +#include "clang/Basic/DiagnosticOptions.h"
> +#include "clang/Basic/SourceManager.h"
> #include "clang/Frontend/FrontendActions.h"
> +#include "clang/Rewrite/Core/Rewriter.h"
> #include "clang/Tooling/CommonOptionsParser.h"
> #include "clang/Tooling/Tooling.h"
> +#include "clang-replace/Tooling/ApplyReplacements.h"
> #include "llvm/ADT/STLExtras.h"
> #include "llvm/ADT/StringSwitch.h"
> #include "llvm/Support/MemoryBuffer.h"
> @@ -122,12 +127,12 @@ static cl::opt<bool, /*ExternalStorage=*
>     cl::location(GlobalOptions.EnableHeaderModifications),
>     cl::init(false));
> 
> -static cl::opt<bool> YAMLOnly("yaml-only",
> -                              cl::Hidden, // Associated with -headers
> -                              cl::desc("Don't change headers on disk. Write "
> -                                       "changes to change description files "
> -                                       "only."),
> -                              cl::init(false));
> +static cl::opt<bool>
> +SerializeReplacements("serialize-replacements",
> +                      cl::Hidden, // Associated with -headers
> +                      cl::desc("Serialize translation unit replacements to "
> +                               "disk instead of changing files."),
> +                      cl::init(false));
> 
> cl::opt<std::string> SupportedCompilers(
>     "for-compilers", cl::value_desc("string"),
> @@ -225,6 +230,68 @@ static Reformatter *handleFormatStyle(co
>   return 0;
> }
> 
> +/// \brief Use \c ChangesReformatter to reformat all changed regions of all
> +/// files stored in \c Overrides and write the result to disk.
> +///
> +/// \returns \li true if reformatting replacements were successfully applied
> +///              without conflicts and all files were successfully written to
> +///              disk.
> +///          \li false if reformatting could not be successfully applied or
> +///              if at least one file failed to write to disk.
> +bool reformat(Reformatter &ChangesReformatter, const FileOverrides &Overrides,
> +              DiagnosticsEngine &Diagnostics) {
> +  FileManager Files((FileSystemOptions()));
> +  SourceManager SM(Diagnostics, Files);
> +
> +  replace::TUReplacements AllReplacements(1);
> +  ChangesReformatter.reformatChanges(Overrides, SM,
> +                                     AllReplacements.front().Replacements);
> +
> +  replace::FileToReplacementsMap GroupedReplacements;
> +  if (!replace::mergeAndDeduplicate(AllReplacements, GroupedReplacements, SM)) {
> +    llvm::errs() << "Warning: Reformatting produced conflicts.\n";
> +    return false;
> +  }
> +
> +  Rewriter DestRewriter(SM, LangOptions());
> +  if (!replace::applyReplacements(GroupedReplacements, DestRewriter)) {
> +    llvm::errs() << "Warning: Failed to apply reformatting conflicts!\n";
> +    return false;
> +  }
> +
> +  return replace::writeFiles(DestRewriter);
> +}
> +
> +bool serializeReplacements(const replace::TUReplacements &Replacements) {
> +  bool Errors = false;
> +  for (replace::TUReplacements::const_iterator I = Replacements.begin(),
> +                                               E = Replacements.end();
> +       I != E; ++I) {
> +    llvm::SmallString<128> ReplacementsFileName;
> +    llvm::SmallString<64> Error;
> +    bool Result = generateReplacementsFileName(I->MainSourceFile,
> +                                               ReplacementsFileName, Error);
> +    if (!Result) {
> +      llvm::errs() << "Failed to generate replacements filename:" << Error
> +                   << "\n";
> +      Errors = true;
> +      continue;
> +    }
> +
> +    std::string ErrorInfo;
> +    llvm::raw_fd_ostream ReplacementsFile(ReplacementsFileName.c_str(),
> +                                          ErrorInfo, llvm::sys::fs::F_Binary);
> +    if (!ErrorInfo.empty()) {
> +      llvm::errs() << "Error opening file: " << ErrorInfo << "\n";
> +      Errors = true;
> +      continue;
> +    }
> +    llvm::yaml::Output YAML(ReplacementsFile);
> +    YAML << const_cast<TranslationUnitReplacements &>(*I);
> +  }
> +  return !Errors;
> +}
> +
> int main(int argc, const char **argv) {
>   llvm::sys::PrintStackTraceOnErrorSignal();
>   Transforms TransformManager;
> @@ -280,6 +347,15 @@ int main(int argc, const char **argv) {
> 
>   TransformManager.createSelectedTransforms(GlobalOptions, RequiredVersions);
> 
> +  llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts(
> +      new DiagnosticOptions());
> +  DiagnosticsEngine Diagnostics(
> +      llvm::IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
> +      DiagOpts.getPtr());
> +
> +  // FIXME: Make this DiagnosticsEngine available to all Transforms probably via
> +  // GlobalOptions.
> +
>   if (TransformManager.begin() == TransformManager.end()) {
>     if (SupportedCompilers.empty())
>       llvm::errs() << argv[0] << ": no selected transforms\n";
> @@ -289,21 +365,22 @@ int main(int argc, const char **argv) {
>     return 1;
>   }
> 
> -  if (std::distance(TransformManager.begin(), TransformManager.end()) > 1 &&
> -      YAMLOnly) {
> -    llvm::errs() << "Header change description files requested for multiple "
> +  // If SerializeReplacements is requested, then change reformatting must be
> +  // turned off and only one transform should be requested. Reformatting is
> +  // basically another transform so even if there's only one other transform,
> +  // the reformatting pass would make two.
> +  if (SerializeReplacements &&
> +      (std::distance(TransformManager.begin(), TransformManager.end()) > 1 ||
> +       ChangesReformatter)) {
> +    llvm::errs() << "Serialization of replacements requested for multiple "
>                     "transforms.\nChanges from only one transform can be "
> -                    "recorded in a change description file.\n";
> +                    "serialized.\n";
>     return 1;
>   }
> 
> -  // if reformatting is enabled we wants to track file changes so that it's
> -  // possible to reformat them.
> -  bool TrackReplacements = static_cast<bool>(ChangesReformatter);
> -  FileOverrides FileStates(TrackReplacements);
>   SourcePerfData PerfData;
> +  FileOverrides FileStates;
> 
> -  // Apply transforms.
>   for (Transforms::const_iterator I = TransformManager.begin(),
>                                   E = TransformManager.end();
>        I != E; ++I) {
> @@ -326,79 +403,67 @@ int main(int argc, const char **argv) {
>       }
>       llvm::outs() << "\n";
>     }
> -  }
> 
> -  // Reformat changes if a reformatter is provided.
> -  if (ChangesReformatter)
> -    for (FileOverrides::const_iterator I = FileStates.begin(),
> -                                       E = FileStates.end();
> -         I != E; ++I) {
> -      SourceOverrides &Overrides = *I->second;
> -      ChangesReformatter->reformatChanges(Overrides);
> +    // Collect all TranslationUnitReplacements generated from the translation
> +    // units the transform worked on and store them in AllReplacements.
> +    replace::TUReplacements AllReplacements;
> +    const TUReplacementsMap &ReplacementsMap = T->getAllReplacements();
> +    const TranslationUnitReplacements &(
> +        TUReplacementsMap::value_type::*getValue)() const =
> +        &TUReplacementsMap::value_type::getValue;
> +    std::transform(ReplacementsMap.begin(), ReplacementsMap.end(),
> +                   std::back_inserter(AllReplacements),
> +                   std::mem_fun_ref(getValue));
> +
> +    if (SerializeReplacements)
> +      serializeReplacements(AllReplacements);
> +
> +    FileManager Files((FileSystemOptions()));
> +    SourceManager SM(Diagnostics, Files);
> +
> +    // Make sure SourceManager is updated to have the same initial state as the
> +    // transforms.
> +    FileStates.applyOverrides(SM);
> +
> +    replace::FileToReplacementsMap GroupedReplacements;
> +    if (!replace::mergeAndDeduplicate(AllReplacements, GroupedReplacements,
> +                                      SM)) {
> +      llvm::outs() << "Transform " << T->getName()
> +                   << " resulted in conflicts. Discarding all "
> +                   << "replacements.\n";
> +      continue;
> +    }
> +
> +    // Apply replacements and update FileStates with new state.
> +    Rewriter DestRewriter(SM, LangOptions());
> +    if (!replace::applyReplacements(GroupedReplacements, DestRewriter)) {
> +      llvm::outs() << "Some replacements failed to apply. Discarding "
> +                      "all replacements.\n";
> +      continue;
>     }
> 
> +    // Update contents of files in memory to serve as initial state for next
> +    // transform.
> +    FileStates.updateState(DestRewriter);
> +
> +    // Update changed ranges for reformatting
> +    if (ChangesReformatter)
> +      FileStates.adjustChangedRanges(GroupedReplacements);
> +  }
> +
> +  // Skip writing final file states to disk if we were asked to serialize
> +  // replacements. Otherwise reformat changes if reformatting is enabled. If
> +  // not enabled or if reformatting fails write un-formated changes to disk
> +  // instead. reformat() takes care of writing successfully formatted changes.
> +  if (!SerializeReplacements &&
> +      (!ChangesReformatter ||
> +       !reformat(*ChangesReformatter, FileStates, Diagnostics)))
> +    FileStates.writeToDisk(Diagnostics);
> +
>   if (FinalSyntaxCheck)
>     if (!doSyntaxCheck(*Compilations, SourcePaths, FileStates))
>       return 1;
> 
> -  // Write results to file.
> -  for (FileOverrides::const_iterator I = FileStates.begin(),
> -                                     E = FileStates.end();
> -       I != E; ++I) {
> -    const SourceOverrides &Overrides = *I->second;
> -    if (Overrides.isSourceOverriden()) {
> -      std::string ErrorInfo;
> -      std::string MainFileName = I->getKey();
> -      llvm::raw_fd_ostream FileStream(MainFileName.c_str(), ErrorInfo,
> -                                      llvm::sys::fs::F_Binary);
> -      FileStream << Overrides.getMainFileContent();
> -    }
> -
> -    for (HeaderOverrides::const_iterator HeaderI = Overrides.headers_begin(),
> -                                         HeaderE = Overrides.headers_end();
> -         HeaderI != HeaderE; ++HeaderI) {
> -      std::string ErrorInfo;
> -      if (YAMLOnly) {
> -        // Replacements for header files need to be written in a YAML file for
> -        // every transform and will be merged together with an external tool.
> -        llvm::SmallString<128> ReplacementsHeaderName;
> -        llvm::SmallString<64> Error;
> -        bool Result =
> -            generateReplacementsFileName(I->getKey(), HeaderI->getKey().data(),
> -                                         ReplacementsHeaderName, Error);
> -        if (!Result) {
> -          llvm::errs() << "Failed to generate replacements filename:" << Error
> -                       << "\n";
> -          continue;
> -        }
> -
> -        llvm::raw_fd_ostream ReplacementsFile(
> -            ReplacementsHeaderName.c_str(), ErrorInfo, llvm::sys::fs::F_Binary);
> -        if (!ErrorInfo.empty()) {
> -          llvm::errs() << "Error opening file: " << ErrorInfo << "\n";
> -          continue;
> -        }
> -        llvm::yaml::Output YAML(ReplacementsFile);
> -        YAML << const_cast<TranslationUnitReplacements &>(
> -                    HeaderI->getValue().getReplacements());
> -      } else {
> -        // If -yaml-only was not specified, then change headers on disk.
> -        // FIXME: This is transitional behaviour. Remove this functionality
> -        // when header change description tool is ready.
> -        assert(!HeaderI->second.getContentOverride().empty() &&
> -               "A header override should not be empty");
> -        std::string HeaderFileName = HeaderI->getKey();
> -        llvm::raw_fd_ostream HeaderStream(HeaderFileName.c_str(), ErrorInfo,
> -                                          llvm::sys::fs::F_Binary);
> -        if (!ErrorInfo.empty()) {
> -          llvm::errs() << "Error opening file: " << ErrorInfo << "\n";
> -          continue;
> -        }
> -        HeaderStream << HeaderI->second.getContentOverride();
> -      }
> -    }
> -  }
> -
>   // Report execution times.
>   if (GlobalOptions.EnableTiming && !PerfData.empty()) {
>     std::string DirectoryName = TimingDirectoryName;
> 
> Added: clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/Inputs/no_yaml.h
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/Inputs/no_yaml.h?rev=189689&view=auto
> ==============================================================================
> --- clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/Inputs/no_yaml.h (added)
> +++ clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/Inputs/no_yaml.h Fri Aug 30 14:28:59 2013
> @@ -0,0 +1,8 @@
> +void update(int (&arr)[10]) {
> +  int val = 1;
> +  for (unsigned i = 0; i < sizeof(arr)/sizeof(int); ++i) {
> +    arr[i] = val++;
> +    // CHECK: for (auto & elem : arr) {
> +    // CHECK-NEXT: elem = val++;
> +  }
> +}
> 
> Removed: clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/common.h.yaml
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/common.h.yaml?rev=189688&view=auto
> ==============================================================================
> --- clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/common.h.yaml (original)
> +++ clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/common.h.yaml (removed)
> @@ -1,12 +0,0 @@
> ----
> -MainSourceFile:      "$(path)/main.cpp"
> -Replacements:
> -  - FilePath:        "$(path)/common.h"
> -    Offset:          432
> -    Length:          61
> -    ReplacementText: "(auto & elem : C)"
> -  - FilePath:       "$(path)/common.h"
> -    Offset:          506
> -    Length:          2
> -    ReplacementText: "elem"
> -...
> 
> Added: clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/common_expected.yaml
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/common_expected.yaml?rev=189689&view=auto
> ==============================================================================
> --- clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/common_expected.yaml (added)
> +++ clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/common_expected.yaml Fri Aug 30 14:28:59 2013
> @@ -0,0 +1,20 @@
> +---
> +MainSourceFile:  "$(path)/common.cpp"
> +Replacements:    
> +  - FilePath:        "$(path)/common.h"
> +    Offset:          506
> +    Length:          2
> +    ReplacementText: "elem"
> +  - FilePath:        "$(path)/common.h"
> +    Offset:          432
> +    Length:          61
> +    ReplacementText: "(auto & elem : C)"
> +  - FilePath:        "$(path)/common.cpp"
> +    Offset:          289
> +    Length:          2
> +    ReplacementText: "elem"
> +  - FilePath:        "$(path)/common.cpp"
> +    Offset:          206
> +    Length:          63
> +    ReplacementText: "(auto & elem : C1)"
> +...
> 
> Modified: clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/main.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/main.cpp?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/main.cpp (original)
> +++ clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/main.cpp Fri Aug 30 14:28:59 2013
> @@ -1,44 +1,30 @@
> // The following block tests the following:
> -//   - Only 1 file is generated per translation unit and header file
> +//   - Only 1 file is generated per translation unit
> //   - Replacements are written in YAML that matches the expected YAML file
> -// RUN: rm -rf %t/Test
> -// RUN: mkdir -p %t/Test
> -// RUN: cp %S/main.cpp %S/common.cpp %S/common.h %t/Test
> -// RUN: cpp11-migrate -loop-convert -headers -yaml-only -include=%t/Test %t/Test/main.cpp %t/Test/common.cpp --
> -// Check that only 1 file is generated per translation unit and header file.
> -// RUN: ls -1 %t/Test | FileCheck %s --check-prefix=MAIN_CPP
> -// RUN: ls -1 %t/Test | FileCheck %s --check-prefix=COMMON_CPP
> -// RUN: cp %S/common.h.yaml %t/Test/main.cpp_common.h.yaml
> -// We need to put the build path to the expected YAML file to diff against the generated one.
> -// RUN: sed -e 's#$(path)#%/t/Test#g' %S/common.h.yaml > %t/Test/main.cpp_common.h.yaml
> -// RUN: sed -i -e 's#\\#/#g' %t/Test/main.cpp_common.h_*.yaml
> -// RUN: diff -b %t/Test/main.cpp_common.h.yaml %t/Test/main.cpp_common.h_*.yaml
> -// RUN: sed -e 's#$(path)#%/t/Test#g' -e 's#main.cpp"#common.cpp"#g' %S/common.h.yaml > %t/Test/common.cpp_common.h.yaml
> -// RUN: sed -i -e 's#\\#/#g' %t/Test/common.cpp_common.h_*.yaml
> -// RUN: diff -b %t/Test/common.cpp_common.h.yaml %t/Test/common.cpp_common.h_*.yaml
> +// The test is run in %T/SerializeTest so it's easy to create a clean test
> +// directory.
> //
> -// The following block tests the following:
> -//   - YAML files are written only when -headers is used
> -// RUN: rm -rf %t/Test
> -// RUN: mkdir -p %t/Test
> -// RUN: cp %S/main.cpp %S/common.cpp %S/common.h %t/Test
> -// RUN: cpp11-migrate -loop-convert -headers -yaml-only -include=%t/Test %t/Test/main.cpp --
> -// RUN: cpp11-migrate -loop-convert %t/Test/common.cpp --
> -// Check that only one YAML file is generated from main.cpp and common.h and not from common.cpp and common.h since -header is not specified
> -// RUN: ls -1 %t/Test | FileCheck %s --check-prefix=MAIN_CPP
> -// RUN: ls -1 %t/Test | FileCheck %s --check-prefix=NO_COMMON
> +// RUN: rm -rf %T/SerializeTest
> +// RUN: mkdir -p %T/SerializeTest
> +// RUN: cp %S/main.cpp %S/common.cpp %S/common.h %T/SerializeTest
> +// RUN: cpp11-migrate -loop-convert -headers -serialize-replacements -include=%T/SerializeTest %T/SerializeTest/main.cpp %T/SerializeTest/common.cpp --
> +// Check that only 1 file is generated per translation unit
> +// RUN: ls -1 %T/SerializeTest | FileCheck %s --check-prefix=MAIN_CPP
> +// RUN: ls -1 %T/SerializeTest | FileCheck %s --check-prefix=COMMON_CPP
> // We need to put the build path to the expected YAML file to diff against the generated one.
> -// RUN: sed -e 's#$(path)#%/t/Test#g' %S/common.h.yaml > %t/Test/main.cpp_common.h.yaml
> -// RUN: sed -i -e 's#\\#/#g' %t/Test/main.cpp_common.h_*.yaml
> -// RUN: diff -b %t/Test/main.cpp_common.h.yaml %t/Test/main.cpp_common.h_*.yaml
> -//
> -// MAIN_CPP: {{^main.cpp_common.h_.*.yaml$}}
> -// MAIN_CPP-NOT: {{main.cpp_common.h_.*.yaml}}
> +// RUN: sed -e 's#$(path)#%/T/SerializeTest#g' %S/main_expected.yaml > %T/SerializeTest/main_expected.yaml
> +// RUN: sed -i -e 's#\\#/#g' %T/SerializeTest/main.cpp_*.yaml
> +// RUN: diff -b %T/SerializeTest/main_expected.yaml %T/SerializeTest/main.cpp_*.yaml
> +// RUN: sed -e 's#$(path)#%/T/SerializeTest#g' %S/common_expected.yaml > %T/SerializeTest/common_expected.yaml
> +// RUN: sed -i -e 's#\\#/#g' %T/SerializeTest/common.cpp_*.yaml
> +// RUN: diff -b %T/SerializeTest/common_expected.yaml %T/SerializeTest/common.cpp_*.yaml
> //
> -// COMMON_CPP:     {{^common.cpp_common.h_.*.yaml$}}
> -// COMMON_CPP-NOT: {{common.cpp_common.h_.*.yaml}}
> +// The following are for FileCheck when used on output of 'ls'. See above.
> +// MAIN_CPP: {{^main.cpp_.*.yaml$}}
> +// MAIN_CPP-NOT: {{main.cpp_.*.yaml}}
> //
> -// NO_COMMON-NOT: {{common.cpp_common.h_.*.yaml}}
> +// COMMON_CPP:     {{^common.cpp_.*.yaml$}}
> +// COMMON_CPP-NOT: {{common.cpp_.*.yaml}}
> 
> #include "common.h"
> 
> 
> Added: clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/main_expected.yaml
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/main_expected.yaml?rev=189689&view=auto
> ==============================================================================
> --- clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/main_expected.yaml (added)
> +++ clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/main_expected.yaml Fri Aug 30 14:28:59 2013
> @@ -0,0 +1,12 @@
> +---
> +MainSourceFile:      "$(path)/main.cpp"
> +Replacements:
> +  - FilePath:        "$(path)/common.h"
> +    Offset:          506
> +    Length:          2
> +    ReplacementText: "elem"
> +  - FilePath:        "$(path)/common.h"
> +    Offset:          432
> +    Length:          61
> +    ReplacementText: "(auto & elem : C)"
> +...
> 
> Added: clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/no_yaml.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/no_yaml.cpp?rev=189689&view=auto
> ==============================================================================
> --- clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/no_yaml.cpp (added)
> +++ clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/no_yaml.cpp Fri Aug 30 14:28:59 2013
> @@ -0,0 +1,24 @@
> +// Ensure that if -serialize-replacements is not provided, no serialized
> +// replacement files should be generated and the changes are made directly.
> +//
> +// RUN: mkdir -p %T/Inputs
> +// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
> +// RUN: grep -Ev "// *[A-Z-]+:" %S/Inputs/no_yaml.h > %T/Inputs/no_yaml.h
> +// RUN: cpp11-migrate -loop-convert %t.cpp -headers -include=%T/Inputs -- -I %T/Inputs/no_yaml.h
> +// RUN: FileCheck --input-file=%t.cpp %s
> +// RUN: FileCheck --input-file=%T/Inputs/no_yaml.h %S/Inputs/no_yaml.h
> +// RUN: ls -1 %T | FileCheck %s --check-prefix=NO_YAML
> +//
> +// NO_YAML-NOT: {{no_yaml.cpp_.*.yaml}}
> +#include "Inputs/no_yaml.h"
> +
> +void func() {
> +  int arr[10];
> +  for (unsigned i = 0; i < sizeof(arr)/sizeof(int); ++i) {
> +    arr[i] = 0;
> +    // CHECK: for (auto & elem : arr) {
> +    // CHECK-NEXT: elem = 0;
> +  }
> +
> +  update(arr);
> +}
> 
> Modified: clang-tools-extra/trunk/unittests/cpp11-migrate/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/cpp11-migrate/CMakeLists.txt?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/unittests/cpp11-migrate/CMakeLists.txt (original)
> +++ clang-tools-extra/trunk/unittests/cpp11-migrate/CMakeLists.txt Fri Aug 30 14:28:59 2013
> @@ -1,26 +1,31 @@
> -set(LLVM_LINK_COMPONENTS
> -  support
> -  )
> -
> -get_filename_component(CPP11_MIGRATE_SOURCE_DIR
> -  ${CMAKE_CURRENT_SOURCE_DIR}/../../cpp11-migrate REALPATH)
> -include_directories(${CPP11_MIGRATE_SOURCE_DIR})
> -
> -add_extra_unittest(Cpp11MigrateTests
> -  FileOverridesTest.cpp
> -  ReformattingTest.cpp
> -  IncludeExcludeTest.cpp
> -  PerfSupportTest.cpp
> -  TransformTest.cpp
> -  UniqueHeaderNameTest.cpp
> -  IncludeDirectivesTest.cpp
> -  )
> -
> -target_link_libraries(Cpp11MigrateTests
> -  migrateCore
> -  clangFormat
> -  clangTooling
> -  clangBasic
> -  clangASTMatchers
> -  clangRewriteFrontend
> -  )
> +set(LLVM_LINK_COMPONENTS
> +  support
> +  )
> +
> +get_filename_component(CPP11_MIGRATE_SOURCE_DIR
> +  ${CMAKE_CURRENT_SOURCE_DIR}/../../cpp11-migrate REALPATH)
> +get_filename_component(ClangReplaceLocation
> +  "${CMAKE_CURRENT_SOURCE_DIR}/../../clang-replace/include" REALPATH)
> +include_directories(
> +  ${CPP11_MIGRATE_SOURCE_DIR}
> +  ${ClangReplaceLocation}
> +  )
> +
> +add_extra_unittest(Cpp11MigrateTests
> +  FileOverridesTest.cpp
> +  ReformattingTest.cpp
> +  IncludeExcludeTest.cpp
> +  PerfSupportTest.cpp
> +  TransformTest.cpp
> +  UniqueHeaderNameTest.cpp
> +  IncludeDirectivesTest.cpp
> +  )
> +
> +target_link_libraries(Cpp11MigrateTests
> +  migrateCore
> +  clangFormat
> +  clangTooling
> +  clangBasic
> +  clangASTMatchers
> +  clangRewriteFrontend
> +  )
> 
> Modified: clang-tools-extra/trunk/unittests/cpp11-migrate/FileOverridesTest.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/cpp11-migrate/FileOverridesTest.cpp?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/unittests/cpp11-migrate/FileOverridesTest.cpp (original)
> +++ clang-tools-extra/trunk/unittests/cpp11-migrate/FileOverridesTest.cpp Fri Aug 30 14:28:59 2013
> @@ -8,56 +8,34 @@
> //===----------------------------------------------------------------------===//
> 
> #include "Core/FileOverrides.h"
> +#include "Core/Refactoring.h"
> #include "gtest/gtest.h"
> #include "VirtualFileHelper.h"
> +#include "clang/Rewrite/Core/Rewriter.h"
> 
> using namespace clang;
> using namespace clang::tooling;
> 
> -TEST(SourceOverridesTest, Interface) {
> -  llvm::StringRef FileName = "<test-file>";
> -  VirtualFileHelper VFHelper;
> -  VFHelper.mapFile(
> -      FileName,
> -      "std::vector<such_a_long_name_for_a_type>::const_iterator long_type =\n"
> -      "    vec.begin();\n");
> -  SourceOverrides Overrides(FileName, /*TrackFileChanges=*/false);
> -
> -  EXPECT_EQ(FileName, Overrides.getMainFileName());
> -  EXPECT_FALSE(Overrides.isSourceOverriden());
> -  EXPECT_FALSE(Overrides.isTrackingFileChanges());
> -
> -  Replacements Replaces;
> -  unsigned ReplacementLength =
> -      strlen("std::vector<such_a_long_name_for_a_type>::const_iterator");
> -  Replaces.insert(
> -      Replacement(FileName, 0, ReplacementLength, "auto"));
> -  Overrides.applyReplacements(Replaces, VFHelper.getNewSourceManager());
> -  EXPECT_TRUE(Overrides.isSourceOverriden());
> -
> -  std::string ExpectedContent = "auto long_type =\n"
> -                                "    vec.begin();\n";
> -  EXPECT_EQ(ExpectedContent, Overrides.getMainFileContent());
> -}
> -
> -namespace {
> -Replacement makeReplacement(unsigned Offset, unsigned Length,
> -                            unsigned ReplacementLength) {
> -  return Replacement("", Offset, Length, std::string(ReplacementLength, '~'));
> +static Replacement makeReplacement(unsigned Offset, unsigned Length,
> +                                   unsigned ReplacementLength,
> +                                   llvm::StringRef FilePath) {
> +  return Replacement(FilePath, Offset, Length,
> +                     std::string(ReplacementLength, '~'));
> }
> 
> // generate a set of replacements containing one element
> -Replacements makeReplacements(unsigned Offset, unsigned Length,
> -                              unsigned ReplacementLength) {
> -  Replacements Replaces;
> -  Replaces.insert(makeReplacement(Offset, Length, ReplacementLength));
> +static ReplacementsVec makeReplacements(unsigned Offset, unsigned Length,
> +                                        unsigned ReplacementLength,
> +                                        llvm::StringRef FilePath = "~") {
> +  ReplacementsVec Replaces;
> +  Replaces.push_back(
> +      makeReplacement(Offset, Length, ReplacementLength, FilePath));
>   return Replaces;
> }
> 
> -bool equalRanges(Range A, Range B) {
> +static bool equalRanges(Range A, Range B) {
>   return A.getOffset() == B.getOffset() && A.getLength() == B.getLength();
> }
> -} // end anonymous namespace
> 
> TEST(ChangedRangesTest, adjustChangedRangesShrink) {
>   ChangedRanges Changes;
> @@ -139,3 +117,71 @@ TEST(ChangedRangesTest, adjustChangedRan
>   EXPECT_TRUE(
>       std::equal(Changes.begin(), Changes.end(), ExpectedChanges, equalRanges));
> }
> +
> +TEST(FileOverridesTest, applyOverrides) {
> +
> +  // Set up initial state
> +  VirtualFileHelper VFHelper;
> +
> +  SmallString<128> fileAPath("fileA.cpp");
> +  ASSERT_FALSE(llvm::sys::fs::make_absolute(fileAPath));
> +  SmallString<128> fileBPath("fileB.cpp");
> +  ASSERT_FALSE(llvm::sys::fs::make_absolute(fileBPath));
> +  VFHelper.mapFile(fileAPath, "Content A");
> +  VFHelper.mapFile(fileBPath, "Content B");
> +  SourceManager &SM = VFHelper.getNewSourceManager();
> +
> +  // Fill a Rewriter with changes
> +  Rewriter Rewrites(SM, LangOptions());
> +  ReplacementsVec R(1, Replacement(fileAPath, 0, 7, "Stuff"));
> +  ASSERT_TRUE(applyAllReplacements(R, Rewrites));
> +
> +  FileOverrides Overrides;
> +  Overrides.updateState(Rewrites);
> +  
> +  const FileOverrides::FileStateMap &State = Overrides.getState();
> +  
> +  // Ensure state updated
> +  ASSERT_TRUE(State.end() == State.find(fileBPath));
> +  ASSERT_TRUE(State.begin() == State.find(fileAPath));
> +  ASSERT_EQ("Stuff A", State.begin()->getValue());
> +
> +  Overrides.applyOverrides(SM);
> +
> +  const FileEntry *EntryA = SM.getFileManager().getFile(fileAPath);
> +  FileID IdA = SM.translateFile(EntryA);
> +  ASSERT_FALSE(IdA.isInvalid());
> +
> +  // Ensure the contents of the buffer matches what we'd expect.
> +  const llvm::MemoryBuffer *BufferA = SM.getBuffer(IdA);
> +  ASSERT_FALSE(0 == BufferA);
> +  ASSERT_EQ("Stuff A", BufferA->getBuffer());
> +}
> +
> +TEST(FileOverridesTest, adjustChangedRanges) {
> +  SmallString<128> fileAPath("fileA.cpp");
> +  ASSERT_FALSE(llvm::sys::fs::make_absolute(fileAPath));
> +  SmallString<128> fileBPath("fileB.cpp");
> +  ASSERT_FALSE(llvm::sys::fs::make_absolute(fileBPath));
> +
> +  replace::FileToReplacementsMap GroupedReplacements;
> +  GroupedReplacements[fileAPath] = makeReplacements(0, 5, 4, fileAPath);
> +  GroupedReplacements[fileBPath] = makeReplacements(10, 0, 6, fileBPath);
> +
> +  FileOverrides Overrides;
> +
> +  const FileOverrides::ChangeMap &Map = Overrides.getChangedRanges();
> +
> +  ASSERT_TRUE(Map.empty());
> +
> +  Overrides.adjustChangedRanges(GroupedReplacements);
> +
> +  ASSERT_TRUE(Map.end() != Map.find(fileAPath));
> +  ASSERT_TRUE(Map.end() != Map.find(fileBPath));
> +  const Range &RA = *Map.find(fileAPath)->second.begin();
> +  EXPECT_EQ(0u, RA.getOffset());
> +  EXPECT_EQ(4u, RA.getLength());
> +  const Range &RB = *Map.find(fileBPath)->second.begin();
> +  EXPECT_EQ(10u, RB.getOffset());
> +  EXPECT_EQ(6u, RB.getLength());
> +}
> 
> Modified: clang-tools-extra/trunk/unittests/cpp11-migrate/PerfSupportTest.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/cpp11-migrate/PerfSupportTest.cpp?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/unittests/cpp11-migrate/PerfSupportTest.cpp (original)
> +++ clang-tools-extra/trunk/unittests/cpp11-migrate/PerfSupportTest.cpp Fri Aug 30 14:28:59 2013
> @@ -18,7 +18,7 @@ public:
>   TransformA(const TransformOptions &Options)
>       : Transform("TransformA", Options) {}
> 
> -  virtual int apply(FileOverrides &,
> +  virtual int apply(const FileOverrides &,
>                     const tooling::CompilationDatabase &,
>                     const std::vector<std::string> &) {
>     return 0;
> @@ -34,7 +34,7 @@ public:
>   TransformB(const TransformOptions &Options)
>       : Transform("TransformB", Options) {}
> 
> -  virtual int apply(FileOverrides &,
> +  virtual int apply(const FileOverrides &,
>                     const tooling::CompilationDatabase &,
>                     const std::vector<std::string> &) {
>     return 0;
> 
> Modified: clang-tools-extra/trunk/unittests/cpp11-migrate/ReformattingTest.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/cpp11-migrate/ReformattingTest.cpp?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/unittests/cpp11-migrate/ReformattingTest.cpp (original)
> +++ clang-tools-extra/trunk/unittests/cpp11-migrate/ReformattingTest.cpp Fri Aug 30 14:28:59 2013
> @@ -9,6 +9,7 @@
> 
> #include "Core/Reformatting.h"
> #include "Core/FileOverrides.h"
> +#include "Core/Refactoring.h"
> #include "gtest/gtest.h"
> #include "VirtualFileHelper.h"
> 
> @@ -19,9 +20,9 @@ namespace {
> // convenience function to create a ChangedRanges containing one Range
> ChangedRanges makeChangedRanges(unsigned Offset, unsigned Length) {
>   ChangedRanges Changes;
> -  Replacements Replaces;
> +  ReplacementsVec Replaces;
> 
> -  Replaces.insert(Replacement("", Offset, 0, std::string(Length, '~')));
> +  Replaces.push_back(Replacement("", Offset, 0, std::string(Length, '~')));
>   Changes.adjustChangedRanges(Replaces);
>   return Changes;
> }
> @@ -35,16 +36,20 @@ TEST(Reformatter, SingleReformat) {
> 
>   Reformatter ChangesReformatter(format::getLLVMStyle());
>   ChangedRanges Changes = makeChangedRanges(0, 6);
> -  tooling::Replacements Replaces = ChangesReformatter.reformatSingleFile(
> -      FileName, Changes, VFHelper.getNewSourceManager());
> -
> -  SourceOverrides Overrides(FileName, /*TrackChanges=*/false);
> -  Overrides.applyReplacements(Replaces, VFHelper.getNewSourceManager());
> -
> -  std::string Expected, Result;
> -
> -  Expected = "int a;\n"
> -             "int  b;\n";
> -  Result = Overrides.getMainFileContent();
> -  EXPECT_EQ(Expected, Result);
> +  tooling::ReplacementsVec Replaces;
> +  ChangesReformatter.reformatSingleFile(
> +      FileName, Changes, VFHelper.getNewSourceManager(), Replaces);
> +
> +  // We expect the code above to reformatted like so:
> +  //
> +  // int a;
> +  // int  b;
> +  //
> +  // This test is slightly fragile since there's more than one Replacement that
> +  // results in the above change. However, testing the result of applying the
> +  // replacement is more trouble than it's worth in this context.
> +  ASSERT_EQ(1u, Replaces.size());
> +  EXPECT_EQ(3u, Replaces[0].getOffset());
> +  EXPECT_EQ(2u, Replaces[0].getLength());
> +  EXPECT_EQ(" ", Replaces[0].getReplacementText());
> }
> 
> Modified: clang-tools-extra/trunk/unittests/cpp11-migrate/TransformTest.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/cpp11-migrate/TransformTest.cpp?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/unittests/cpp11-migrate/TransformTest.cpp (original)
> +++ clang-tools-extra/trunk/unittests/cpp11-migrate/TransformTest.cpp Fri Aug 30 14:28:59 2013
> @@ -26,7 +26,7 @@ public:
>   DummyTransform(llvm::StringRef Name, const TransformOptions &Options)
>       : Transform(Name, Options) {}
> 
> -  virtual int apply(FileOverrides &,
> +  virtual int apply(const FileOverrides &,
>                     const tooling::CompilationDatabase &,
>                     const std::vector<std::string> &) { return 0; }
> 
> @@ -161,7 +161,7 @@ TEST(Transform, Timings) {
> 
>   // Transform's handle* functions require FileOverrides to be set, even if
>   // there aren't any.
> -  FileOverrides Overrides(/*TrackFileChanges=*/false);
> +  FileOverrides Overrides;
>   T.setOverrides(Overrides);
> 
>   Tool.run(clang::tooling::newFrontendActionFactory(&Factory, &Callbacks));
> 
> Modified: clang-tools-extra/trunk/unittests/cpp11-migrate/UniqueHeaderNameTest.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/cpp11-migrate/UniqueHeaderNameTest.cpp?rev=189689&r1=189688&r2=189689&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/unittests/cpp11-migrate/UniqueHeaderNameTest.cpp (original)
> +++ clang-tools-extra/trunk/unittests/cpp11-migrate/UniqueHeaderNameTest.cpp Fri Aug 30 14:28:59 2013
> @@ -28,34 +28,31 @@ TEST(UniqueHeaderName, testUniqueHeaderN
>   append(SourceFile, "project/lib/feature.cpp");
>   native(SourceFile.str().str(), SourceFile);
> 
> -  llvm::SmallString<128> HeaderFile(TmpDir);
> -  append(HeaderFile, "project/include/feature.h");
> -  native(HeaderFile.str().str(), HeaderFile);
> -
> -  llvm::SmallString<128> ExpectedName("^feature.cpp_feature.h_[0-9a-f]{2}_[0-9a-f]{2}_[0-9a-f]{2}_[0-9a-f]{2}_[0-9a-f]{2}_[0-9a-f]{2}.yaml$");
> -
> -  llvm::SmallString<128> ActualName;
> +  llvm::SmallString<128> FullActualPath;
>   llvm::SmallString<128> Error;
>   bool Result =
> -      generateReplacementsFileName(SourceFile, HeaderFile, ActualName, Error);
> +      generateReplacementsFileName(SourceFile, FullActualPath, Error);
> 
>   ASSERT_TRUE(Result);
>   EXPECT_TRUE(Error.empty());
> 
>   // We need to check the directory name and filename separately since on
>   // Windows, the path separator is '\' which is a regex escape character.
> -  llvm::SmallString<128> ExpectedHeaderPath =
> -      llvm::sys::path::parent_path(HeaderFile);
> -  llvm::SmallString<128> ActualHeaderPath =
> -      llvm::sys::path::parent_path(ActualName);
> -  llvm::SmallString<128> ActualHeaderName =
> -      llvm::sys::path::filename(ActualName);
> -
> -  EXPECT_STREQ(ExpectedHeaderPath.c_str(), ActualHeaderPath.c_str());
> -
> +  llvm::SmallString<128> ExpectedPath =
> +      llvm::sys::path::parent_path(SourceFile);
> +  llvm::SmallString<128> ActualPath =
> +      llvm::sys::path::parent_path(FullActualPath);
> +  llvm::SmallString<128> ActualName =
> +      llvm::sys::path::filename(FullActualPath);
> +
> +  EXPECT_STREQ(ExpectedPath.c_str(), ActualPath.c_str());
> +
> +  llvm::StringRef ExpectedName =
> +      "^feature.cpp_[0-9a-f]{2}_[0-9a-f]{2}_[0-9a-f]{2}_[0-9a-f]{2}_["
> +      "0-9a-f]{2}_[0-9a-f]{2}.yaml$";
>   llvm::Regex R(ExpectedName);
> -  ASSERT_TRUE(R.match(ActualHeaderName))
> -      << "ExpectedName: " << ExpectedName.c_str()
> +  ASSERT_TRUE(R.match(ActualName))
> +      << "ExpectedName: " << ExpectedName.data()
>       << "\nActualName: " << ActualName.c_str();
>   ASSERT_TRUE(Error.empty()) << "Error: " << Error.c_str();
> }
> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits




More information about the cfe-commits mailing list