[PATCH] clang-replace: Afford applying replacements in memory

Edwin Vane edwin.vane at intel.com
Mon Aug 26 12:34:50 PDT 2013


    - Switching back to two-function apply-and-write logic

Hi klimek,

http://llvm-reviews.chandlerc.com/D1519

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D1519?vs=3761&id=3765#toc

Files:
  clang-replace/ApplyReplacements.cpp
  clang-replace/ApplyReplacements.h
  clang-replace/tool/ClangReplaceMain.cpp

Index: clang-replace/ApplyReplacements.cpp
===================================================================
--- clang-replace/ApplyReplacements.cpp
+++ clang-replace/ApplyReplacements.cpp
@@ -189,7 +189,8 @@
 }
 
 bool applyReplacements(const FileToReplacementsMap &GroupedReplacements,
-                       clang::SourceManager &SM) {
+                       clang::SourceManager &SM,
+                       llvm::StringMap<std::string> &NewContents) {
   Rewriter Rewrites(SM, LangOptions());
 
   // Apply all changes
@@ -200,19 +201,33 @@
       return false;
   }
 
-  // Write all changes to disk
+  // Write all changes to preferred destination
   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);
+
+    llvm::raw_string_ostream StringStream(NewContents[FileName]);
+    BufferI->second.write(StringStream);
+    StringStream.flush();
+  }
+
+  return true;
+}
+
+bool writeFiles(const llvm::StringMap<std::string> &FileContents,
+                DiagnosticsEngine &Diagnostics) {
+
+  for (llvm::StringMap<std::string>::const_iterator I = FileContents.begin(),
+       E = FileContents.end(); I != E; ++I) {
+    std::string ErrorInfo;
+
+    llvm::raw_fd_ostream FileStream(I->getKey().data(), ErrorInfo);
     if (!ErrorInfo.empty()) {
-      errs() << "Unable to open " << FileName << " for writing\n";
-      return false;
+      errs() << "Warning: Could not write to " << I->getKey() << "\n";
+      continue;
     }
-    BufferI->second.write(FileStream);
+    FileStream << I->getValue();
   }
 
   return true;
Index: clang-replace/ApplyReplacements.h
===================================================================
--- clang-replace/ApplyReplacements.h
+++ clang-replace/ApplyReplacements.h
@@ -76,11 +76,23 @@
 /// \param[in] GroupedReplacements Deduplicated and conflict free Replacements
 /// to apply.
 /// \param[in] SM SourceManager required to construct clang::Rewriter.
+/// \param[out] FileContents The results of applying replacements will be
+/// written into this map. The map keys are filenames and the map values are
+/// file contents.
 ///
 /// \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);
+                       clang::SourceManager &SM,
+                       llvm::StringMap<std::string> &OutputState);
+
+/// \brief Write the contents of \c FileContents to disk. Keys of the map are
+/// filenames and values are the new contents for those files.
+///
+/// \param[in] FileContents Map of file name -> file content to write.
+/// \param[in] Diagnostics DiagnosticsEngine used for error output.
+bool writeFiles(const llvm::StringMap<std::string> &FileContents,
+                clang::DiagnosticsEngine &Diagnostics);
 
 } // end namespace replace
 } // end namespace clang
Index: clang-replace/tool/ClangReplaceMain.cpp
===================================================================
--- clang-replace/tool/ClangReplaceMain.cpp
+++ clang-replace/tool/ClangReplaceMain.cpp
@@ -51,6 +51,14 @@
   if (!mergeAndDeduplicate(TUs, GroupedReplacements, SM))
     return 1;
 
-  if (!applyReplacements(GroupedReplacements, SM))
+  llvm::StringMap<std::string> FileContents;
+  if (!applyReplacements(GroupedReplacements, SM, FileContents)) {
+    errs() << "Failed to apply all replacements. No changes made.\n";
     return 1;
+  }
+
+  if (!writeFiles(FileContents, Diagnostics))
+    return 1;
+
+  return 0;
 }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1519.2.patch
Type: text/x-patch
Size: 3910 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130826/0a37d07c/attachment.bin>


More information about the cfe-commits mailing list