[clang-tools-extra] r191667 - clang-apply-replacements: Add code formatting functionality

Edwin Vane edwin.vane at intel.com
Mon Sep 30 06:59:22 PDT 2013


Author: revane
Date: Mon Sep 30 08:59:21 2013
New Revision: 191667

URL: http://llvm.org/viewvc/llvm-project?rev=191667&view=rev
Log:
clang-apply-replacements: Add code formatting functionality

The tool now supports a collection of arguments to turn on and provide settings
for the formatting of code affected by applying replacements:
* --format turns on formatting (default style is LLVM)
* --style controls code style settings
* --style-config allows one to explicitly indicate where a style config file
  lives.

The libclangApplyReplacements interface has a new function to turn Replacements
into Ranges to be used with tooling::reformat().


Added:
    clang-tools-extra/trunk/test/clang-apply-replacements/Inputs/format/
    clang-tools-extra/trunk/test/clang-apply-replacements/Inputs/format/no.cpp
    clang-tools-extra/trunk/test/clang-apply-replacements/Inputs/format/no.yaml
    clang-tools-extra/trunk/test/clang-apply-replacements/Inputs/format/yes.cpp
    clang-tools-extra/trunk/test/clang-apply-replacements/Inputs/format/yes.yaml
    clang-tools-extra/trunk/test/clang-apply-replacements/format.cpp
    clang-tools-extra/trunk/unittests/clang-apply-replacements/
    clang-tools-extra/trunk/unittests/clang-apply-replacements/CMakeLists.txt
    clang-tools-extra/trunk/unittests/clang-apply-replacements/Makefile
    clang-tools-extra/trunk/unittests/clang-apply-replacements/ReformattingTest.cpp
    clang-tools-extra/trunk/unittests/include/
    clang-tools-extra/trunk/unittests/include/common/
    clang-tools-extra/trunk/unittests/include/common/Utility.h
    clang-tools-extra/trunk/unittests/include/common/VirtualFileHelper.h
Removed:
    clang-tools-extra/trunk/unittests/clang-modernize/Utility.h
    clang-tools-extra/trunk/unittests/clang-modernize/VirtualFileHelper.h
Modified:
    clang-tools-extra/trunk/clang-apply-replacements/CMakeLists.txt
    clang-tools-extra/trunk/clang-apply-replacements/include/clang-apply-replacements/Tooling/ApplyReplacements.h
    clang-tools-extra/trunk/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp
    clang-tools-extra/trunk/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp
    clang-tools-extra/trunk/unittests/CMakeLists.txt
    clang-tools-extra/trunk/unittests/Makefile
    clang-tools-extra/trunk/unittests/clang-modernize/CMakeLists.txt
    clang-tools-extra/trunk/unittests/clang-modernize/FileOverridesTest.cpp
    clang-tools-extra/trunk/unittests/clang-modernize/IncludeDirectivesTest.cpp
    clang-tools-extra/trunk/unittests/clang-modernize/IncludeExcludeTest.cpp
    clang-tools-extra/trunk/unittests/clang-modernize/Makefile
    clang-tools-extra/trunk/unittests/clang-modernize/ReformattingTest.cpp

Modified: clang-tools-extra/trunk/clang-apply-replacements/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-apply-replacements/CMakeLists.txt?rev=191667&r1=191666&r2=191667&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-apply-replacements/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-apply-replacements/CMakeLists.txt Mon Sep 30 08:59:21 2013
@@ -13,6 +13,7 @@ target_link_libraries(clangApplyReplacem
   clangTooling
   clangBasic
   clangRewriteFrontend
+  clangFormat
   )
 
 include_directories(

Modified: clang-tools-extra/trunk/clang-apply-replacements/include/clang-apply-replacements/Tooling/ApplyReplacements.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-apply-replacements/include/clang-apply-replacements/Tooling/ApplyReplacements.h?rev=191667&r1=191666&r2=191667&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-apply-replacements/include/clang-apply-replacements/Tooling/ApplyReplacements.h (original)
+++ clang-tools-extra/trunk/clang-apply-replacements/include/clang-apply-replacements/Tooling/ApplyReplacements.h Mon Sep 30 08:59:21 2013
@@ -28,8 +28,15 @@ namespace clang {
 class DiagnosticsEngine;
 class Rewriter;
 
+namespace format {
+struct FormatStyle;
+} // end namespace format
+
 namespace replace {
 
+/// \brief Collection of source ranges.
+typedef std::vector<clang::tooling::Range> RangeVector;
+
 /// \brief Collection of TranslationUnitReplacements.
 typedef std::vector<clang::tooling::TranslationUnitReplacements>
 TUReplacements;
@@ -67,6 +74,9 @@ collectReplacementsFromDirectory(const l
 /// \brief Deduplicate, check for conflicts, and apply all Replacements stored
 /// in \c TUs. If conflicts occur, no Replacements are applied.
 ///
+/// \post For all (key,value) in GroupedReplacements, value[i].getOffset() <=
+/// value[i+1].getOffset().
+///
 /// \param[in] TUs Collection of TranslationUnitReplacements to merge,
 /// deduplicate, and test for conflicts.
 /// \param[out] GroupedReplacements Container grouping all Replacements by the
@@ -91,6 +101,18 @@ bool mergeAndDeduplicate(const TUReplace
 bool applyReplacements(const FileToReplacementsMap &GroupedReplacements,
                        clang::Rewriter &Rewrites);
 
+/// \brief Given a collection of Replacements for a single file, produces a list
+/// of source ranges that enclose those Replacements.
+///
+/// \pre Replacements[i].getOffset() <= Replacements[i+1].getOffset().
+///
+/// \param[in] Replacements Replacements from a single file.
+/// 
+/// \returns Collection of source ranges that enclose all given Replacements.
+/// One range is created for each replacement.
+RangeVector calculateChangedRanges(
+    const std::vector<clang::tooling::Replacement> &Replacements);
+
 /// \brief Write the contents of \c FileContents to disk. Keys of the map are
 /// filenames and values are the new contents for those files.
 ///

Modified: clang-tools-extra/trunk/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp?rev=191667&r1=191666&r2=191667&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp (original)
+++ clang-tools-extra/trunk/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp Mon Sep 30 08:59:21 2013
@@ -17,6 +17,8 @@
 #include "clang-apply-replacements/Tooling/ApplyReplacements.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/SourceManager.h"
+#include "clang/Format/Format.h"
+#include "clang/Lex/Lexer.h"
 #include "clang/Rewrite/Core/Rewriter.h"
 #include "clang/Tooling/ReplacementsYaml.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -34,7 +36,6 @@ static void eatDiagnostics(const SMDiagn
 namespace clang {
 namespace replace {
 
-
 llvm::error_code
 collectReplacementsFromDirectory(const llvm::StringRef Directory,
                                  TUReplacements &TUs,
@@ -128,6 +129,8 @@ static void reportConflict(
 /// \brief Deduplicates and tests for conflicts among the replacements for each
 /// file in \c Replacements. Any conflicts found are reported.
 ///
+/// \post Replacements[i].getOffset() <= Replacements[i+1].getOffset().
+///
 /// \param[in,out] Replacements Container of all replacements grouped by file
 /// to be deduplicated and checked for conflicts.
 /// \param[in] SM SourceManager required for conflict reporting.
@@ -212,6 +215,29 @@ bool applyReplacements(const FileToRepla
   return true;
 }
 
+RangeVector calculateChangedRanges(
+    const std::vector<clang::tooling::Replacement> &Replaces) {
+  RangeVector ChangedRanges;
+
+  // Generate the new ranges from the replacements.
+  //
+  // NOTE: This is O(n^2) in the number of replacements. If this starts to
+  // become a problem inline shiftedCodePosition() here and do shifts in a
+  // single run through this loop.
+  for (std::vector<clang::tooling::Replacement>::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();
+
+    ChangedRanges.push_back(tooling::Range(Offset, Length));
+  }
+
+  return ChangedRanges;
+}
+
 bool writeFiles(const clang::Rewriter &Rewrites) {
 
   for (Rewriter::const_buffer_iterator BufferI = Rewrites.buffer_begin(),

Modified: clang-tools-extra/trunk/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp?rev=191667&r1=191666&r2=191667&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp (original)
+++ clang-tools-extra/trunk/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp Mon Sep 30 08:59:21 2013
@@ -18,6 +18,7 @@
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Version.h"
+#include "clang/Format/Format.h"
 #include "clang/Rewrite/Core/Rewriter.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringSet.h"
@@ -30,6 +31,8 @@ using namespace clang::replace;
 static cl::opt<std::string> Directory(cl::Positional, cl::Required,
                                       cl::desc("<Search Root Directory>"));
 
+static cl::OptionCategory FormattingCategory("Formatting Options");
+
 static cl::opt<bool> RemoveTUReplacementFiles(
     "remove-change-desc-files",
     cl::desc("Remove the change description files regardless of successful\n"
@@ -39,7 +42,31 @@ static cl::opt<bool> RemoveTUReplacement
 // Update this list of options to show in -help as new options are added.
 // Should add even those options marked as 'Hidden'. Any option not listed
 // here will get marked 'ReallyHidden' so they don't appear in any -help text.
-const char *OptionsToShow[] = { "help", "version", "remove-change-desc-files" };
+const char *OptionsToShow[] = { "help",                     "version",
+                                "remove-change-desc-files", "format",
+                                "style-config",             "style" };
+
+static cl::opt<bool> DoFormat(
+    "format",
+    cl::desc("Enable formatting of code changed by applying replacements.\n"
+             "Use -style to choose formatting style.\n"),
+    cl::cat(FormattingCategory));
+
+// FIXME: Consider making the default behaviour for finding a style
+// configuration file to start the search anew for every file being changed to
+// handle situations where the style is different for different parts of a
+// project.
+
+static cl::opt<std::string> FormatStyleConfig(
+    "style-config",
+    cl::desc("Path to a directory containing a .clang-format file\n"
+             "describing a formatting style to use for formatting\n"
+             "code when -style=file.\n"),
+    cl::init(""), cl::cat(FormattingCategory));
+
+static cl::opt<std::string>
+FormatStyleOpt("style", cl::desc(format::StyleOptionHelpDescription),
+               cl::init("LLVM"), cl::cat(FormattingCategory));
 
 // Helper object to remove the TUReplacement files (triggered by
 // "remove-change-desc-files" command line option) when exiting current scope.
@@ -62,6 +89,111 @@ void printVersion() {
   outs() << "clang-apply-replacements version " CLANG_VERSION_STRING << "\n";
 }
 
+/// \brief Convenience function to get rewritten content for \c Filename from
+/// \c Rewrites.
+///
+/// \pre Replacements[i].getFilePath() == Replacements[i+1].getFilePath().
+/// \post Replacements.empty() -> Result.empty()
+///
+/// \param[in] Replacements Replacements to apply
+/// \param[in] Rewrites Rewriter to use to apply replacements.
+/// \param[out] Result Contents of the file after applying replacements if
+/// replacements were provided.
+///
+/// \returns \li true if all replacements were applied successfully.
+///          \li false if at least one replacement failed to apply.
+static bool
+getRewrittenData(const std::vector<tooling::Replacement> &Replacements,
+                 Rewriter &Rewrites, std::string &Result) {
+  if (Replacements.empty()) return true;
+
+  if (!tooling::applyAllReplacements(Replacements, Rewrites))
+    return false;
+
+  SourceManager &SM = Rewrites.getSourceMgr();
+  FileManager &Files = SM.getFileManager();
+
+  StringRef FileName = Replacements.begin()->getFilePath();
+  const clang::FileEntry *Entry = Files.getFile(FileName);
+  assert(Entry && "Expected an existing file");
+  FileID ID = SM.translateFile(Entry);
+  assert(!ID.isInvalid() && "Expected a valid FileID");
+  const RewriteBuffer *Buffer = Rewrites.getRewriteBufferFor(ID);
+  Result = std::string(Buffer->begin(), Buffer->end());
+
+  return true;
+}
+
+/// \brief Apply \c Replacements and return the new file contents.
+///
+/// \pre Replacements[i].getFilePath() == Replacements[i+1].getFilePath().
+/// \post Replacements.empty() -> Result.empty()
+///
+/// \param[in] Replacements Replacements to apply.
+/// \param[out] Result Contents of the file after applying replacements if
+/// replacements were provided.
+/// \param[in] Diagnostics For diagnostic output.
+///
+/// \returns \li true if all replacements applied successfully.
+///          \li false if at least one replacement failed to apply.
+bool applyReplacements(const std::vector<tooling::Replacement> &Replacements,
+                       std::string &Result,
+                       DiagnosticsEngine &Diagnostics) {
+  FileManager Files((FileSystemOptions()));
+  SourceManager SM(Diagnostics, Files);
+  Rewriter Rewrites(SM, LangOptions());
+
+  return getRewrittenData(Replacements, Rewrites, Result);
+}
+
+/// \brief Apply code formatting to all places where replacements were made.
+///
+/// \pre !Replacements.empty().
+/// \pre Replacements[i].getFilePath() == Replacements[i+1].getFilePath().
+/// \pre Replacements[i].getOffset() <= Replacements[i+1].getOffset().
+///
+/// \param[in] Replacements Replacements that were made to the file. Provided
+/// to indicate where changes were made.
+/// \param[in] FileData The contents of the file \b after \c Replacements have
+/// been applied.
+/// \param[out] FormattedFileData The contents of the file after reformatting.
+/// \param[in] Diagnostics For diagnostic output.
+///
+/// \returns \li true if reformatting replacements were all successfully
+///          applied.
+///          \li false if at least one reformatting replacement failed to apply.
+bool applyFormatting(const std::vector<tooling::Replacement> &Replacements,
+                     const StringRef FileData,
+                     std::string &FormattedFileData,
+                     const format::FormatStyle &FormatStyle,
+                     DiagnosticsEngine &Diagnostics) {
+  assert(!Replacements.empty() && "Need at least one replacement");
+
+  RangeVector Ranges = calculateChangedRanges(Replacements);
+
+  StringRef FileName = Replacements.begin()->getFilePath();
+  tooling::Replacements R =
+      format::reformat(FormatStyle, FileData, Ranges, FileName);
+
+  // FIXME: Remove this copy when tooling::Replacements is implemented as a
+  // vector instead of a set.
+  std::vector<tooling::Replacement> FormattingReplacements;
+  std::copy(R.begin(), R.end(), back_inserter(FormattingReplacements));
+
+  if (FormattingReplacements.empty()) {
+    FormattedFileData = FileData;
+    return true;
+  }
+
+  FileManager Files((FileSystemOptions()));
+  SourceManager SM(Diagnostics, Files);
+  SM.overrideFileContents(Files.getFile(FileName),
+                          llvm::MemoryBuffer::getMemBufferCopy(FileData));
+  Rewriter Rewrites(SM, LangOptions());
+
+  return getRewrittenData(FormattingReplacements, Rewrites, FormattedFileData);
+}
+
 int main(int argc, char **argv) {
   // Only include our options in -help output.
   StringMap<cl::Option*> OptMap;
@@ -81,6 +213,11 @@ int main(int argc, char **argv) {
       IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
       DiagOpts.getPtr());
 
+  // Determine a formatting style from options.
+  format::FormatStyle FormatStyle;
+  if (DoFormat)
+    FormatStyle = format::getStyle(FormatStyleOpt, FormatStyleConfig);
+
   TUReplacements TUs;
   TUReplacementFiles TURFiles;
 
@@ -106,14 +243,42 @@ int main(int argc, char **argv) {
   if (!mergeAndDeduplicate(TUs, GroupedReplacements, SM))
     return 1;
 
-  Rewriter DestRewriter(SM, LangOptions());
-  if (!applyReplacements(GroupedReplacements, DestRewriter)) {
-    errs() << "Failed to apply all replacements. No changes made.\n";
-    return 1;
-  }
+  Rewriter ReplacementsRewriter(SM, LangOptions());
 
-  if (!writeFiles(DestRewriter))
-    return 1;
+  for (FileToReplacementsMap::const_iterator I = GroupedReplacements.begin(),
+                                             E = GroupedReplacements.end();
+       I != E; ++I) {
+
+    std::string NewFileData;
+
+    // This shouldn't happen but if a file somehow has no replacements skip to
+    // next file.
+    if (I->getValue().empty())
+      continue;
+
+    if (!applyReplacements(I->getValue(), NewFileData, Diagnostics)) {
+      errs() << "Failed to apply replacements to " << I->getKey() << "\n";
+      continue;
+    }
+
+    // Apply formatting if requested.
+    if (DoFormat && !applyFormatting(I->getValue(), NewFileData, NewFileData,
+                                     FormatStyle, Diagnostics)) {
+      errs() << "Failed to apply reformatting replacements for " << I->getKey()
+             << "\n";
+      continue;
+    }
+
+    // Write new file to disk
+    std::string ErrorInfo;
+    llvm::raw_fd_ostream FileStream(I->getKey().str().c_str(), ErrorInfo);
+    if (!ErrorInfo.empty()) {
+      llvm::errs() << "Could not open " << I->getKey() << " for writing\n";
+      continue;
+    }
+
+    FileStream << NewFileData;
+  }
 
   return 0;
 }

Added: clang-tools-extra/trunk/test/clang-apply-replacements/Inputs/format/no.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-apply-replacements/Inputs/format/no.cpp?rev=191667&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-apply-replacements/Inputs/format/no.cpp (added)
+++ clang-tools-extra/trunk/test/clang-apply-replacements/Inputs/format/no.cpp Mon Sep 30 08:59:21 2013
@@ -0,0 +1,6 @@
+class C {};
+
+void f() { // This comment necessary to prevent formatting as void f() { ... }
+  C *a = new C();
+  // CHECK: {{^\ \ auto\ a\ \=\ new\ C\(\);}}
+}

Added: clang-tools-extra/trunk/test/clang-apply-replacements/Inputs/format/no.yaml
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-apply-replacements/Inputs/format/no.yaml?rev=191667&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-apply-replacements/Inputs/format/no.yaml (added)
+++ clang-tools-extra/trunk/test/clang-apply-replacements/Inputs/format/no.yaml Mon Sep 30 08:59:21 2013
@@ -0,0 +1,8 @@
+---
+MainSourceFile:  no.cpp
+Replacements:    
+  - FilePath:        $(path)/no.cpp
+    Offset:          94
+    Length:          3
+    ReplacementText: 'auto '
+...

Added: clang-tools-extra/trunk/test/clang-apply-replacements/Inputs/format/yes.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-apply-replacements/Inputs/format/yes.cpp?rev=191667&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-apply-replacements/Inputs/format/yes.cpp (added)
+++ clang-tools-extra/trunk/test/clang-apply-replacements/Inputs/format/yes.cpp Mon Sep 30 08:59:21 2013
@@ -0,0 +1,22 @@
+class MyType012345678901234567890123456789 {};
+
+void g(int, int*, int, int*, int, int*, int);
+
+void f() {
+  MyType012345678901234567890123456789 *a =
+      new MyType012345678901234567890123456789();
+  // CHECK: {{^\ \ auto\ a\ \=\ new\ MyType012345678901234567890123456789\(\);}}
+
+  int iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii;
+  int jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj;
+  int kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk;
+  int mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm;
+  g(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii, 0, jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj,
+    0, kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk, 0, mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm);
+  // CHECK: g(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii, nullptr,
+  // CHECK-NEXT: jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj, nullptr,
+  // CHECK-NEXT: kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk, nullptr,
+  // CHECK-NEXT: mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm);
+
+  delete a;
+}

Added: clang-tools-extra/trunk/test/clang-apply-replacements/Inputs/format/yes.yaml
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-apply-replacements/Inputs/format/yes.yaml?rev=191667&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-apply-replacements/Inputs/format/yes.yaml (added)
+++ clang-tools-extra/trunk/test/clang-apply-replacements/Inputs/format/yes.yaml Mon Sep 30 08:59:21 2013
@@ -0,0 +1,22 @@
+# These replacements are out of order on purpose to test that they get sorted
+# so that formatting happens correctly.
+---
+MainSourceFile:  yes.cpp
+Replacements:    
+  - FilePath:        $(path)/yes.cpp
+    Offset:          494
+    Length:          1
+    ReplacementText: nullptr
+  - FilePath:        $(path)/yes.cpp
+    Offset:          410
+    Length:          1
+    ReplacementText: nullptr
+  - FilePath:        $(path)/yes.cpp
+    Offset:          454
+    Length:          1
+    ReplacementText: nullptr
+  - FilePath:        $(path)/yes.cpp
+    Offset:          108
+    Length:          38
+    ReplacementText: 'auto '
+...

Added: clang-tools-extra/trunk/test/clang-apply-replacements/format.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-apply-replacements/format.cpp?rev=191667&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-apply-replacements/format.cpp (added)
+++ clang-tools-extra/trunk/test/clang-apply-replacements/format.cpp Mon Sep 30 08:59:21 2013
@@ -0,0 +1,15 @@
+// RUN: mkdir -p %T/Inputs/format
+//
+// yes.cpp requires formatting after replacements are applied. no.cpp does not.
+// The presence of no.cpp ensures that files that don't need formatting still
+// have their new state written to disk after applying replacements.
+//
+// RUN: grep -Ev "// *[A-Z-]+:" %S/Inputs/format/yes.cpp > %T/Inputs/format/yes.cpp
+// RUN: grep -Ev "// *[A-Z-]+:" %S/Inputs/format/no.cpp > %T/Inputs/format/no.cpp
+// RUN: sed "s#\$(path)#%/T/Inputs/format#" %S/Inputs/format/yes.yaml > %T/Inputs/format/yes.yaml
+// RUN: sed "s#\$(path)#%/T/Inputs/format#" %S/Inputs/format/no.yaml > %T/Inputs/format/no.yaml
+// RUN: clang-apply-replacements -format %T/Inputs/format
+// RUN: FileCheck --strict-whitespace -input-file=%T/Inputs/format/yes.cpp %S/Inputs/format/yes.cpp
+// RUN: FileCheck --strict-whitespace -input-file=%T/Inputs/format/no.cpp %S/Inputs/format/no.cpp
+//
+// RUN not clang-apply-replacements -format=blah %T/Inputs/format

Modified: clang-tools-extra/trunk/unittests/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/CMakeLists.txt?rev=191667&r1=191666&r2=191667&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/unittests/CMakeLists.txt Mon Sep 30 08:59:21 2013
@@ -5,5 +5,6 @@ function(add_extra_unittest test_dirname
   add_unittest(ExtraToolsUnitTests ${test_dirname} ${ARGN})
 endfunction()
 
+add_subdirectory(clang-apply-replacements)
 add_subdirectory(clang-modernize)
 add_subdirectory(clang-tidy)

Modified: clang-tools-extra/trunk/unittests/Makefile
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/Makefile?rev=191667&r1=191666&r2=191667&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/Makefile (original)
+++ clang-tools-extra/trunk/unittests/Makefile Mon Sep 30 08:59:21 2013
@@ -10,6 +10,6 @@
 CLANG_LEVEL := ../../..
 include $(CLANG_LEVEL)/../../Makefile.config
 
-PARALLEL_DIRS := clang-modernize clang-tidy
+PARALLEL_DIRS := clang-apply-replacements clang-modernize clang-tidy
 
 include $(CLANG_LEVEL)/Makefile

Added: clang-tools-extra/trunk/unittests/clang-apply-replacements/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-apply-replacements/CMakeLists.txt?rev=191667&view=auto
==============================================================================
--- clang-tools-extra/trunk/unittests/clang-apply-replacements/CMakeLists.txt (added)
+++ clang-tools-extra/trunk/unittests/clang-apply-replacements/CMakeLists.txt Mon Sep 30 08:59:21 2013
@@ -0,0 +1,23 @@
+set(LLVM_LINK_COMPONENTS
+  asmparser
+  bitreader
+  support
+  mc
+  )
+
+get_filename_component(ClangApplyReplacementsLocation
+  "${CMAKE_CURRENT_SOURCE_DIR}/../../clang-apply-replacements/include" REALPATH)
+get_filename_component(CommonIncLocation
+  "${CMAKE_CURRENT_SOURCE_DIR}/../include" REALPATH)
+include_directories(
+  ${ClangApplyReplacementsLocation}
+  ${CommonIncLocation}
+  )
+
+add_extra_unittest(ClangApplyReplacementsTests
+  ReformattingTest.cpp
+  )
+
+target_link_libraries(ClangApplyReplacementsTests
+  clangApplyReplacements
+  )

Added: clang-tools-extra/trunk/unittests/clang-apply-replacements/Makefile
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-apply-replacements/Makefile?rev=191667&view=auto
==============================================================================
--- clang-tools-extra/trunk/unittests/clang-apply-replacements/Makefile (added)
+++ clang-tools-extra/trunk/unittests/clang-apply-replacements/Makefile Mon Sep 30 08:59:21 2013
@@ -0,0 +1,23 @@
+##===- unittests/clang-apply-replacements/Makefile ---------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+CLANG_LEVEL = ../../../..
+include $(CLANG_LEVEL)/../../Makefile.config
+
+TESTNAME = ClangApplyReplacementsTests
+LINK_COMPONENTS := asmparser bitreader support mc mcparser option
+USEDLIBS = clangApplyReplacements.a clangFormat.a clangTooling.a clangFrontend.a \
+		clangSerialization.a clangDriver.a clangRewriteFrontend.a \
+		clangRewriteCore.a clangParse.a clangSema.a clangAnalysis.a \
+		clangAST.a clangASTMatchers.a clangEdit.a clangLex.a clangBasic.a
+
+include $(CLANG_LEVEL)/Makefile
+MAKEFILE_UNITTEST_NO_INCLUDE_COMMON := 1
+CPP.Flags += -I$(PROJ_SRC_DIR)/../../clang-apply-replacements/include -I$(PROJ_SRC_DIR)/../include
+include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest

Added: clang-tools-extra/trunk/unittests/clang-apply-replacements/ReformattingTest.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-apply-replacements/ReformattingTest.cpp?rev=191667&view=auto
==============================================================================
--- clang-tools-extra/trunk/unittests/clang-apply-replacements/ReformattingTest.cpp (added)
+++ clang-tools-extra/trunk/unittests/clang-apply-replacements/ReformattingTest.cpp Mon Sep 30 08:59:21 2013
@@ -0,0 +1,69 @@
+//===- clang-apply-replacements/ReformattingTest.cpp ----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang-apply-replacements/Tooling/ApplyReplacements.h"
+#include "clang/Format/Format.h"
+#include "clang/Tooling/Refactoring.h"
+#include "common/VirtualFileHelper.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+using namespace clang::tooling;
+using namespace clang::replace;
+
+typedef std::vector<clang::tooling::Replacement> ReplacementsVec;
+
+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
+static ReplacementsVec makeReplacements(unsigned Offset, unsigned Length,
+                                        unsigned ReplacementLength,
+                                        llvm::StringRef FilePath = "~") {
+  ReplacementsVec Replaces;
+  Replaces.push_back(
+      makeReplacement(Offset, Length, ReplacementLength, FilePath));
+  return Replaces;
+}
+
+// Put these functions in the clang::tooling namespace so arg-dependent name
+// lookup finds these functions for the EXPECT_EQ macros below.
+namespace clang {
+namespace tooling {
+bool operator==(const Range &A, const Range &B) {
+  return A.getOffset() == B.getOffset() && A.getLength() == B.getLength();
+}
+
+std::ostream &operator<<(std::ostream &os, const Range &R) {
+  return os << "Range(" << R.getOffset() << ", " << R.getLength() << ")";
+}
+} // namespace tooling
+} // namespace clang
+
+// Ensure zero-length ranges are produced. Even lines where things are deleted
+// need reformatting.
+TEST(CalculateChangedRangesTest, producesZeroLengthRange) {
+  RangeVector Changes = calculateChangedRanges(makeReplacements(0, 4, 0));
+  EXPECT_EQ(Range(0, 0), Changes.front());
+}
+
+// Basic test to ensure replacements turn into ranges properly.
+TEST(CalculateChangedRangesTest, calculatesRanges) {
+  ReplacementsVec R;
+  R.push_back(makeReplacement(2, 0, 3));
+  R.push_back(makeReplacement(5, 2, 4));
+  RangeVector Changes = calculateChangedRanges(R);
+
+  Range ExpectedRanges[] = { Range(2, 3), Range(8, 4) };
+  EXPECT_TRUE(std::equal(Changes.begin(), Changes.end(), ExpectedRanges));
+}

Modified: clang-tools-extra/trunk/unittests/clang-modernize/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-modernize/CMakeLists.txt?rev=191667&r1=191666&r2=191667&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clang-modernize/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/unittests/clang-modernize/CMakeLists.txt Mon Sep 30 08:59:21 2013
@@ -6,9 +6,12 @@ get_filename_component(CLANG_MODERNIZE_S
   ${CMAKE_CURRENT_SOURCE_DIR}/../../clang-modernize REALPATH)
 get_filename_component(ClangReplaceLocation
   "${CMAKE_CURRENT_SOURCE_DIR}/../../clang-apply-replacements/include" REALPATH)
+get_filename_component(CommonIncLocation
+  "${CMAKE_CURRENT_SOURCE_DIR}/../include" REALPATH)
 include_directories(
   ${CLANG_MODERNIZE_SOURCE_DIR}
   ${ClangReplaceLocation}
+  ${CommonIncLocation}
   )
 
 add_extra_unittest(ClangModernizeTests

Modified: clang-tools-extra/trunk/unittests/clang-modernize/FileOverridesTest.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-modernize/FileOverridesTest.cpp?rev=191667&r1=191666&r2=191667&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clang-modernize/FileOverridesTest.cpp (original)
+++ clang-tools-extra/trunk/unittests/clang-modernize/FileOverridesTest.cpp Mon Sep 30 08:59:21 2013
@@ -10,7 +10,7 @@
 #include "Core/FileOverrides.h"
 #include "Core/Refactoring.h"
 #include "gtest/gtest.h"
-#include "VirtualFileHelper.h"
+#include "common/VirtualFileHelper.h"
 #include "clang/Rewrite/Core/Rewriter.h"
 
 using namespace clang;

Modified: clang-tools-extra/trunk/unittests/clang-modernize/IncludeDirectivesTest.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-modernize/IncludeDirectivesTest.cpp?rev=191667&r1=191666&r2=191667&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clang-modernize/IncludeDirectivesTest.cpp (original)
+++ clang-tools-extra/trunk/unittests/clang-modernize/IncludeDirectivesTest.cpp Mon Sep 30 08:59:21 2013
@@ -9,7 +9,7 @@
 
 #include "Core/IncludeDirectives.h"
 #include "gtest/gtest.h"
-#include "VirtualFileHelper.h"
+#include "common/VirtualFileHelper.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/FrontendActions.h"
 #include "llvm/Support/Path.h"

Modified: clang-tools-extra/trunk/unittests/clang-modernize/IncludeExcludeTest.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-modernize/IncludeExcludeTest.cpp?rev=191667&r1=191666&r2=191667&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clang-modernize/IncludeExcludeTest.cpp (original)
+++ clang-tools-extra/trunk/unittests/clang-modernize/IncludeExcludeTest.cpp Mon Sep 30 08:59:21 2013
@@ -7,7 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Utility.h"
+#include "common/Utility.h"
 #include "Core/IncludeExcludeInfo.h"
 #include "gtest/gtest.h"
 #include "llvm/Support/FileSystem.h"

Modified: clang-tools-extra/trunk/unittests/clang-modernize/Makefile
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-modernize/Makefile?rev=191667&r1=191666&r2=191667&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clang-modernize/Makefile (original)
+++ clang-tools-extra/trunk/unittests/clang-modernize/Makefile Mon Sep 30 08:59:21 2013
@@ -21,5 +21,6 @@ USEDLIBS = modernizeCore.a clangFormat.a
 
 include $(CLANG_LEVEL)/Makefile
 MAKEFILE_UNITTEST_NO_INCLUDE_COMMON := 1
-CPP.Flags += -I$(PROJ_SRC_DIR)/../../clang-modernize -I$(PROJ_SRC_DIR)/../../clang-apply-replacements/include
+CPP.Flags += -I$(PROJ_SRC_DIR)/../../clang-modernize -I$(PROJ_SRC_DIR)/../../clang-apply-replacements/include \
+	           -I$(PROJ_SRC_DIR)/../include
 include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest

Modified: clang-tools-extra/trunk/unittests/clang-modernize/ReformattingTest.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-modernize/ReformattingTest.cpp?rev=191667&r1=191666&r2=191667&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clang-modernize/ReformattingTest.cpp (original)
+++ clang-tools-extra/trunk/unittests/clang-modernize/ReformattingTest.cpp Mon Sep 30 08:59:21 2013
@@ -11,7 +11,7 @@
 #include "Core/FileOverrides.h"
 #include "Core/Refactoring.h"
 #include "gtest/gtest.h"
-#include "VirtualFileHelper.h"
+#include "common/VirtualFileHelper.h"
 
 using namespace clang;
 using namespace clang::tooling;

Removed: clang-tools-extra/trunk/unittests/clang-modernize/Utility.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-modernize/Utility.h?rev=191666&view=auto
==============================================================================
--- clang-tools-extra/trunk/unittests/clang-modernize/Utility.h (original)
+++ clang-tools-extra/trunk/unittests/clang-modernize/Utility.h (removed)
@@ -1,25 +0,0 @@
-//=-- clang-modernize/Utility.h - Utility functions and macros---*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CLANG_MODERNIZE_UNITTESTS_UTILITY_H
-#define CLANG_MODERNIZE_UNITTESTS_UTILITY_H
-
-// FIXME: copied from unittests/Support/Path.cpp
-#define ASSERT_NO_ERROR(x)                                                     \
-  if (llvm::error_code ASSERT_NO_ERROR_ec = x) {                               \
-    llvm::SmallString<128> MessageStorage;                                     \
-    llvm::raw_svector_ostream Message(MessageStorage);                         \
-    Message << #x ": did not return errc::success.\n"                          \
-            << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n"          \
-            << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n";      \
-    GTEST_FATAL_FAILURE_(MessageStorage.c_str());                              \
-  } else {                                                                     \
-  }
-
-#endif // CLANG_MODERNIZE_UNITTESTS_UTILITY_H

Removed: clang-tools-extra/trunk/unittests/clang-modernize/VirtualFileHelper.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-modernize/VirtualFileHelper.h?rev=191666&view=auto
==============================================================================
--- clang-tools-extra/trunk/unittests/clang-modernize/VirtualFileHelper.h (original)
+++ clang-tools-extra/trunk/unittests/clang-modernize/VirtualFileHelper.h (removed)
@@ -1,81 +0,0 @@
-//===--- VirtualFileHelper.h ------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \brief This file defines an utility class for tests that needs a source
-/// manager for a virtual file with customizable content.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef CLANG_MODERNIZE_VIRTUAL_FILE_HELPER_H
-#define CLANG_MODERNIZE_VIRTUAL_FILE_HELPER_H
-
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/DiagnosticOptions.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Frontend/TextDiagnosticPrinter.h"
-
-namespace clang {
-
-/// \brief Class that provides easy access to a SourceManager and that allows to
-/// map virtual files conveniently.
-class VirtualFileHelper {
-  struct VirtualFile {
-    std::string FileName;
-    std::string Code;
-  };
-
-public:
-  VirtualFileHelper()
-      : DiagOpts(new DiagnosticOptions()),
-        Diagnostics(IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
-                    &*DiagOpts),
-        DiagnosticPrinter(llvm::outs(), &*DiagOpts),
-        Files((FileSystemOptions())) {}
-
-  /// \brief Create a virtual file \p FileName, with content \p Code.
-  void mapFile(llvm::StringRef FileName, llvm::StringRef Code) {
-    VirtualFile VF = { FileName, Code };
-    VirtualFiles.push_back(VF);
-  }
-
-  /// \brief Create a new \c SourceManager with the virtual files and contents
-  /// mapped to it.
-  SourceManager &getNewSourceManager() {
-    Sources.reset(new SourceManager(Diagnostics, Files));
-    mapVirtualFiles(*Sources);
-    return *Sources;
-  }
-
-  /// \brief Map the virtual file contents in the given \c SourceManager.
-  void mapVirtualFiles(SourceManager &SM) const {
-    for (llvm::SmallVectorImpl<VirtualFile>::const_iterator
-             I = VirtualFiles.begin(),
-             E = VirtualFiles.end();
-         I != E; ++I) {
-      llvm::MemoryBuffer *Buf = llvm::MemoryBuffer::getMemBuffer(I->Code);
-      const FileEntry *Entry = SM.getFileManager().getVirtualFile(
-          I->FileName, Buf->getBufferSize(), /*ModificationTime=*/0);
-      SM.overrideFileContents(Entry, Buf);
-    }
-  }
-
-private:
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
-  DiagnosticsEngine Diagnostics;
-  TextDiagnosticPrinter DiagnosticPrinter;
-  FileManager Files;
-  // most tests don't need more than one file
-  llvm::SmallVector<VirtualFile, 1> VirtualFiles;
-  llvm::OwningPtr<SourceManager> Sources;
-};
-
-} // end namespace clang
-
-#endif // CLANG_MODERNIZE_VIRTUAL_FILE_HELPER_H

Added: clang-tools-extra/trunk/unittests/include/common/Utility.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/include/common/Utility.h?rev=191667&view=auto
==============================================================================
--- clang-tools-extra/trunk/unittests/include/common/Utility.h (added)
+++ clang-tools-extra/trunk/unittests/include/common/Utility.h Mon Sep 30 08:59:21 2013
@@ -0,0 +1,25 @@
+//=-- clang-modernize/Utility.h - Utility functions and macros---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_MODERNIZE_UNITTESTS_UTILITY_H
+#define CLANG_MODERNIZE_UNITTESTS_UTILITY_H
+
+// FIXME: copied from unittests/Support/Path.cpp
+#define ASSERT_NO_ERROR(x)                                                     \
+  if (llvm::error_code ASSERT_NO_ERROR_ec = x) {                               \
+    llvm::SmallString<128> MessageStorage;                                     \
+    llvm::raw_svector_ostream Message(MessageStorage);                         \
+    Message << #x ": did not return errc::success.\n"                          \
+            << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n"          \
+            << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n";      \
+    GTEST_FATAL_FAILURE_(MessageStorage.c_str());                              \
+  } else {                                                                     \
+  }
+
+#endif // CLANG_MODERNIZE_UNITTESTS_UTILITY_H

Added: clang-tools-extra/trunk/unittests/include/common/VirtualFileHelper.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/include/common/VirtualFileHelper.h?rev=191667&view=auto
==============================================================================
--- clang-tools-extra/trunk/unittests/include/common/VirtualFileHelper.h (added)
+++ clang-tools-extra/trunk/unittests/include/common/VirtualFileHelper.h Mon Sep 30 08:59:21 2013
@@ -0,0 +1,81 @@
+//===--- VirtualFileHelper.h ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \brief This file defines an utility class for tests that needs a source
+/// manager for a virtual file with customizable content.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_MODERNIZE_VIRTUAL_FILE_HELPER_H
+#define CLANG_MODERNIZE_VIRTUAL_FILE_HELPER_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+
+namespace clang {
+
+/// \brief Class that provides easy access to a SourceManager and that allows to
+/// map virtual files conveniently.
+class VirtualFileHelper {
+  struct VirtualFile {
+    std::string FileName;
+    std::string Code;
+  };
+
+public:
+  VirtualFileHelper()
+      : DiagOpts(new DiagnosticOptions()),
+        Diagnostics(IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
+                    &*DiagOpts),
+        DiagnosticPrinter(llvm::outs(), &*DiagOpts),
+        Files((FileSystemOptions())) {}
+
+  /// \brief Create a virtual file \p FileName, with content \p Code.
+  void mapFile(llvm::StringRef FileName, llvm::StringRef Code) {
+    VirtualFile VF = { FileName, Code };
+    VirtualFiles.push_back(VF);
+  }
+
+  /// \brief Create a new \c SourceManager with the virtual files and contents
+  /// mapped to it.
+  SourceManager &getNewSourceManager() {
+    Sources.reset(new SourceManager(Diagnostics, Files));
+    mapVirtualFiles(*Sources);
+    return *Sources;
+  }
+
+  /// \brief Map the virtual file contents in the given \c SourceManager.
+  void mapVirtualFiles(SourceManager &SM) const {
+    for (llvm::SmallVectorImpl<VirtualFile>::const_iterator
+             I = VirtualFiles.begin(),
+             E = VirtualFiles.end();
+         I != E; ++I) {
+      llvm::MemoryBuffer *Buf = llvm::MemoryBuffer::getMemBuffer(I->Code);
+      const FileEntry *Entry = SM.getFileManager().getVirtualFile(
+          I->FileName, Buf->getBufferSize(), /*ModificationTime=*/0);
+      SM.overrideFileContents(Entry, Buf);
+    }
+  }
+
+private:
+  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
+  DiagnosticsEngine Diagnostics;
+  TextDiagnosticPrinter DiagnosticPrinter;
+  FileManager Files;
+  // most tests don't need more than one file
+  llvm::SmallVector<VirtualFile, 1> VirtualFiles;
+  llvm::OwningPtr<SourceManager> Sources;
+};
+
+} // end namespace clang
+
+#endif // CLANG_MODERNIZE_VIRTUAL_FILE_HELPER_H





More information about the cfe-commits mailing list