[clang-tools-extra] r189014 - clang-replace: Write merged changes to disk

Edwin Vane edwin.vane at intel.com
Thu Aug 22 06:40:33 PDT 2013


Author: revane
Date: Thu Aug 22 08:40:32 2013
New Revision: 189014

URL: http://llvm.org/viewvc/llvm-project?rev=189014&view=rev
Log:
clang-replace: Write merged changes to disk

Functionality for clang-replace completed with the addition of the ability to
write merged replacements to disk.

Test added.

Differential Revision: http://llvm-reviews.chandlerc.com/D1460


Added:
    clang-tools-extra/trunk/test/clang-replace/basic/
    clang-tools-extra/trunk/test/clang-replace/basic.cpp
    clang-tools-extra/trunk/test/clang-replace/basic/basic.h
    clang-tools-extra/trunk/test/clang-replace/basic/file1.yaml
    clang-tools-extra/trunk/test/clang-replace/basic/file2.yaml
Modified:
    clang-tools-extra/trunk/clang-replace/ApplyReplacements.cpp
    clang-tools-extra/trunk/clang-replace/ApplyReplacements.h
    clang-tools-extra/trunk/clang-replace/tool/ClangReplaceMain.cpp

Modified: clang-tools-extra/trunk/clang-replace/ApplyReplacements.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-replace/ApplyReplacements.cpp?rev=189014&r1=189013&r2=189014&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-replace/ApplyReplacements.cpp (original)
+++ clang-tools-extra/trunk/clang-replace/ApplyReplacements.cpp Thu Aug 22 08:40:32 2013
@@ -15,6 +15,7 @@
 #include "ApplyReplacements.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/SourceManager.h"
+#include "clang/Rewrite/Core/Rewriter.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -122,7 +123,7 @@ static void reportConflict(
 ///
 /// \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
+/// \param[in] SM SourceManager required for conflict reporting.
 ///
 /// \returns \li true if conflicts were detected
 ///          \li false if no conflicts were detected
@@ -166,7 +167,7 @@ static bool deduplicateAndDetectConflict
 
 bool mergeAndDeduplicate(const TUReplacements &TUs,
                          FileToReplacementsMap &GroupedReplacements,
-                         clang::DiagnosticsEngine &Diagnostics) {
+                         clang::SourceManager &SM) {
 
   // FIXME: Use Diagnostics for output
 
@@ -179,8 +180,6 @@ bool mergeAndDeduplicate(const TUReplace
          RI != RE; ++RI)
       GroupedReplacements[RI->getFilePath()].push_back(*RI);
 
-  FileManager Files((FileSystemOptions()));
-  SourceManager SM(Diagnostics, Files);
 
   // Ask clang to deduplicate and report conflicts.
   if (deduplicateAndDetectConflicts(GroupedReplacements, SM))
@@ -188,6 +187,36 @@ bool mergeAndDeduplicate(const TUReplace
 
   return true;
 }
+
+bool applyReplacements(const FileToReplacementsMap &GroupedReplacements,
+                       clang::SourceManager &SM) {
+  Rewriter Rewrites(SM, LangOptions());
+
+  // Apply all changes
+  for (FileToReplacementsMap::const_iterator I = GroupedReplacements.begin(),
+                                             E = GroupedReplacements.end();
+       I != E; ++I) {
+    if (!tooling::applyAllReplacements(I->getValue(), Rewrites))
+      return false;
+  }
+
+  // Write all changes to disk
+  for (Rewriter::buffer_iterator BufferI = Rewrites.buffer_begin(),
+                                 BufferE = Rewrites.buffer_end();
+       BufferI != BufferE; ++BufferI) {
+    std::string ErrorInfo;
+    const char *FileName = SM.getFileEntryForID(BufferI->first)->getName();
+    llvm::raw_fd_ostream FileStream(FileName, ErrorInfo,
+                                    llvm::sys::fs::F_Binary);
+    if (!ErrorInfo.empty()) {
+      errs() << "Unable to open " << FileName << " for writing\n";
+      return false;
+    }
+    BufferI->second.write(FileStream);
+  }
+
+  return true;
+}
 
 } // end namespace replace
 } // end namespace clang

Modified: clang-tools-extra/trunk/clang-replace/ApplyReplacements.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-replace/ApplyReplacements.h?rev=189014&r1=189013&r2=189014&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-replace/ApplyReplacements.h (original)
+++ clang-tools-extra/trunk/clang-replace/ApplyReplacements.h Thu Aug 22 08:40:32 2013
@@ -63,13 +63,24 @@ collectReplacementsFromDirectory(const l
 /// deduplicate, and test for conflicts.
 /// \param[out] GroupedReplacements Container grouping all Replacements by the
 /// file they target.
-/// \param[in] Diagnostics DiagnosticsEngine used for error/warning output.
+/// \param[in] SM SourceManager required for conflict reporting.
 ///
 /// \returns \li true If all changes were applied successfully.
 ///          \li false If there were conflicts.
 bool mergeAndDeduplicate(const TUReplacements &TUs,
                          FileToReplacementsMap &GroupedReplacements,
-                         clang::DiagnosticsEngine &Diagnostics);
+                         clang::SourceManager &SM);
+
+/// \brief Apply all replacements in \c GroupedReplacements.
+///
+/// \param[in] GroupedReplacements Deduplicated and conflict free Replacements
+/// to apply.
+/// \param[in] SM SourceManager required to construct clang::Rewriter.
+///
+/// \returns \li true If all changes were applied successfully.
+///          \li false If a replacement failed to apply.
+bool applyReplacements(const FileToReplacementsMap &GroupedReplacements,
+                       clang::SourceManager &SM);
 
 } // end namespace replace
 } // end namespace clang

Modified: clang-tools-extra/trunk/clang-replace/tool/ClangReplaceMain.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-replace/tool/ClangReplaceMain.cpp?rev=189014&r1=189013&r2=189014&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-replace/tool/ClangReplaceMain.cpp (original)
+++ clang-tools-extra/trunk/clang-replace/tool/ClangReplaceMain.cpp Thu Aug 22 08:40:32 2013
@@ -15,6 +15,7 @@
 #include "ApplyReplacements.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/SourceManager.h"
 #include "llvm/Support/CommandLine.h"
 
 using namespace llvm;
@@ -43,8 +44,13 @@ int main(int argc, char **argv) {
     return false;
   }
 
+  FileManager Files((FileSystemOptions()));
+  SourceManager SM(Diagnostics, Files);
+
   FileToReplacementsMap GroupedReplacements;
-  if (mergeAndDeduplicate(TUs, GroupedReplacements, Diagnostics))
-    return 0;
-  return 1;
+  if (!mergeAndDeduplicate(TUs, GroupedReplacements, SM))
+    return 1;
+
+  if (!applyReplacements(GroupedReplacements, SM))
+    return 1;
 }

Added: clang-tools-extra/trunk/test/clang-replace/basic.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-replace/basic.cpp?rev=189014&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-replace/basic.cpp (added)
+++ clang-tools-extra/trunk/test/clang-replace/basic.cpp Thu Aug 22 08:40:32 2013
@@ -0,0 +1,6 @@
+// RUN: mkdir -p %T/basic
+// RUN: grep -Ev "// *[A-Z-]+:" %S/basic/basic.h > %T/basic/basic.h
+// RUN: sed "s#\$(path)#%/T/basic#" %S/basic/file1.yaml > %T/basic/file1.yaml
+// RUN: sed "s#\$(path)#%/T/basic#" %S/basic/file2.yaml > %T/basic/file2.yaml
+// RUN: clang-replace %T/basic
+// RUN: FileCheck -input-file=%T/basic/basic.h %S/basic/basic.h

Added: clang-tools-extra/trunk/test/clang-replace/basic/basic.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-replace/basic/basic.h?rev=189014&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-replace/basic/basic.h (added)
+++ clang-tools-extra/trunk/test/clang-replace/basic/basic.h Thu Aug 22 08:40:32 2013
@@ -0,0 +1,32 @@
+#ifndef BASIC_H
+#define BASIC_H
+
+
+class Parent {
+public:
+  virtual void func() {}
+};
+
+class Derived : public Parent {
+public:
+  virtual void func() {}
+  // CHECK: virtual void func() override {}
+};
+
+extern void ext(int (&)[5], const Parent &);
+
+void func(int t) {
+  int ints[5];
+  for (unsigned i = 0; i < 5; ++i) {
+    int &e = ints[i];
+    e = t;
+    // CHECK: for (auto & elem : ints) {
+    // CHECK-NEXT: elem = t;
+  }
+
+  Derived d;
+
+  ext(ints, d);
+}
+
+#endif // BASIC_H

Added: clang-tools-extra/trunk/test/clang-replace/basic/file1.yaml
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-replace/basic/file1.yaml?rev=189014&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-replace/basic/file1.yaml (added)
+++ clang-tools-extra/trunk/test/clang-replace/basic/file1.yaml Thu Aug 22 08:40:32 2013
@@ -0,0 +1,16 @@
+---
+MainSourceFile:     "source1.cpp"
+Replacements:
+  - FilePath:        "$(path)/basic.h"
+    Offset:          242
+    Length:          26
+    ReplacementText: "auto & elem : ints"
+  - FilePath:        "$(path)/basic.h"
+    Offset:          276
+    Length:          22
+    ReplacementText: ""
+  - FilePath:        "$(path)/basic.h"
+    Offset:          298
+    Length:          1
+    ReplacementText: "elem"
+...

Added: clang-tools-extra/trunk/test/clang-replace/basic/file2.yaml
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-replace/basic/file2.yaml?rev=189014&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-replace/basic/file2.yaml (added)
+++ clang-tools-extra/trunk/test/clang-replace/basic/file2.yaml Thu Aug 22 08:40:32 2013
@@ -0,0 +1,8 @@
+---
+MainSourceFile:     "source2.cpp"
+Replacements:
+  - FilePath:        "$(path)/basic.h"
+    Offset:          148
+    Length:          0
+    ReplacementText: "override "
+...





More information about the cfe-commits mailing list