[clang-tools-extra] r187428 - cpp11-migrate: Write header replacements to disk

Tareq A. Siraj tareq.a.sriaj at intel.com
Tue Jul 30 11:18:02 PDT 2013


Author: tasiraj
Date: Tue Jul 30 13:18:02 2013
New Revision: 187428

URL: http://llvm.org/viewvc/llvm-project?rev=187428&view=rev
Log:
cpp11-migrate: Write header replacements to disk

Committing r187204 with fixes for darwin. Note that one of the lit tests are
disabled on windows due to a bug in writing header replacements to file.

Header replacements are now written to disk in YAML format for an external tool
to merge. A unique file will be created in the same directory as the header
with all replacements that came from a source file that included the header
file. The YAML file will have:
 - Name of the file
 - Transform ID that generated the replacement
 - Offset
 - Length
 - Replacement text

Any tool reading these replacements should read them using the
TransformDocument struct.


Added:
    clang-tools-extra/trunk/cpp11-migrate/Core/ReplacementsYaml.h
    clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/common.cpp
    clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/common.h
    clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/common.h.yaml
    clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/main.cpp
    clang-tools-extra/trunk/unittests/cpp11-migrate/ReplacementsYamlTest.cpp
    clang-tools-extra/trunk/unittests/cpp11-migrate/Utility.h
Modified:
    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/Transform.cpp
    clang-tools-extra/trunk/cpp11-migrate/tool/Cpp11Migrate.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/IncludeExcludeTest.cpp
    clang-tools-extra/trunk/unittests/cpp11-migrate/ReformattingTest.cpp

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=187428&r1=187427&r2=187428&view=diff
==============================================================================
--- clang-tools-extra/trunk/cpp11-migrate/Core/FileOverrides.cpp (original)
+++ clang-tools-extra/trunk/cpp11-migrate/Core/FileOverrides.cpp Tue Jul 30 13:18:02 2013
@@ -23,16 +23,26 @@
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/system_error.h"
+#include <algorithm>
 
 using namespace clang;
 using namespace clang::tooling;
 
+void HeaderOverride::recordReplacements(
+    llvm::StringRef TransformID, const clang::tooling::Replacements &Replaces) {
+  TransformReplacements TR;
+  TR.TransformID = TransformID;
+  TR.GeneratedReplacements.resize(Replaces.size());
+  std::copy(Replaces.begin(), Replaces.end(), TR.GeneratedReplacements.begin());
+  TransformReplacementsDoc.Replacements.push_back(TR);
+}
+
 SourceOverrides::SourceOverrides(llvm::StringRef MainFileName,
                                  bool TrackChanges)
     : MainFileName(MainFileName), TrackChanges(TrackChanges) {}
 
-void
-SourceOverrides::applyReplacements(clang::tooling::Replacements &Replaces) {
+void SourceOverrides::applyReplacements(tooling::Replacements &Replaces,
+                                        llvm::StringRef TransformName) {
   llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts(
       new DiagnosticOptions());
   DiagnosticsEngine Diagnostics(
@@ -40,11 +50,12 @@ SourceOverrides::applyReplacements(clang
       DiagOpts.getPtr());
   FileManager Files((FileSystemOptions()));
   SourceManager SM(Diagnostics, Files);
-  applyReplacements(Replaces, SM);
+  applyReplacements(Replaces, SM, TransformName);
 }
 
-void SourceOverrides::applyReplacements(clang::tooling::Replacements &Replaces,
-                                        clang::SourceManager &SM) {
+void SourceOverrides::applyReplacements(tooling::Replacements &Replaces,
+                                        SourceManager &SM,
+                                        llvm::StringRef TransformName) {
   applyOverrides(SM);
 
   Rewriter Rewrites(SM, LangOptions());
@@ -56,12 +67,6 @@ void SourceOverrides::applyReplacements(
   if (!Success)
     llvm::errs() << "error: failed to apply some replacements.";
 
-  applyRewrites(Rewrites);
-  if (TrackChanges)
-    adjustChangedRanges(Replaces);
-}
-
-void SourceOverrides::applyRewrites(Rewriter &Rewrites) {
   std::string ResultBuf;
 
   for (Rewriter::buffer_iterator I = Rewrites.buffer_begin(),
@@ -89,36 +94,50 @@ void SourceOverrides::applyRewrites(Rewr
     // 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];
-    HeaderOv.FileOverride.swap(ResultBuf);
     // "Create" HeaderOverride if not already existing
-    if (HeaderOv.FileName.empty())
-      HeaderOv.FileName = FileName;
+    if (HeaderOv.getFileName().empty())
+      HeaderOv = HeaderOverride(FileName);
+
+    HeaderOv.swapContentOverride(ResultBuf);
   }
-}
 
-void SourceOverrides::adjustChangedRanges(const Replacements &Replaces) {
-  // Start by grouping replacements by file name
+  // Separate replacements to header files
   Replacements MainFileReplaces;
-  llvm::StringMap<Replacements> HeadersReplaces;
-
-  for (Replacements::iterator I = Replaces.begin(), E = Replaces.end(); I != E;
-       ++I) {
+  ReplacementsMap HeadersReplaces;
+  for (Replacements::const_iterator I = Replaces.begin(), E = Replaces.end();
+      I != E; ++I) {
     llvm::StringRef ReplacementFileName = I->getFilePath();
 
-    if (ReplacementFileName == MainFileName)
+    if (ReplacementFileName == MainFileName) {
       MainFileReplaces.insert(*I);
-    else
-      HeadersReplaces[ReplacementFileName].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(TransformName, I->getValue());
   }
 
-  // Then adjust the changed ranges for each individual file
-  MainFileChanges.adjustChangedRanges(Replaces);
-  for (llvm::StringMap<Replacements>::iterator I = HeadersReplaces.begin(),
-                                               E = HeadersReplaces.end();
+  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()].Changes.adjustChangedRanges(I->getValue());
+    Headers[I->getKey()].adjustChangedRanges(I->getValue());
   }
 }
 
@@ -131,11 +150,11 @@ void SourceOverrides::applyOverrides(Sou
 
   for (HeaderOverrides::const_iterator I = Headers.begin(), E = Headers.end();
        I != E; ++I) {
-    assert(!I->second.FileOverride.empty() &&
+    assert(!I->second.getContentOverride().empty() &&
            "Header override should not be empty!");
     SM.overrideFileContents(
-        FM.getFile(I->second.FileName),
-        llvm::MemoryBuffer::getMemBuffer(I->second.FileOverride));
+        FM.getFile(I->second.getFileName()),
+        llvm::MemoryBuffer::getMemBuffer(I->second.getContentOverride()));
   }
 }
 

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=187428&r1=187427&r2=187428&view=diff
==============================================================================
--- clang-tools-extra/trunk/cpp11-migrate/Core/FileOverrides.h (original)
+++ clang-tools-extra/trunk/cpp11-migrate/Core/FileOverrides.h Tue Jul 30 13:18:02 2013
@@ -16,6 +16,7 @@
 #ifndef CPP11_MIGRATE_FILE_OVERRIDES_H
 #define CPP11_MIGRATE_FILE_OVERRIDES_H
 
+#include "Core/ReplacementsYaml.h"
 #include "clang/Tooling/Refactoring.h"
 #include "llvm/ADT/StringMap.h"
 
@@ -58,13 +59,52 @@ private:
 };
 
 /// \brief Container for storing override information for a single headers.
-struct HeaderOverride {
+class HeaderOverride {
+public:
+  /// \brief Constructors.
+  /// @{
   HeaderOverride() {}
-  HeaderOverride(llvm::StringRef FileName) : FileName(FileName) {}
+  HeaderOverride(llvm::StringRef FileName) {
+    TransformReplacementsDoc.FileName = FileName;
+  }
+  /// @}
+
+  /// \brief Getter for FileName.
+  llvm::StringRef getFileName() const {
+    return TransformReplacementsDoc.FileName;
+  }
+
+  /// \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; }
 
-  std::string FileName;
-  std::string FileOverride;
+  /// \brief Swaps the content of ContentOverride with \param S
+  void swapContentOverride(std::string &S) { ContentOverride.swap(S); }
+
+  /// \brief Getter for TransformReplacementsDoc.
+  const TransformDocument &getTransformReplacementsDoc() const {
+    return TransformReplacementsDoc;
+  }
+
+  /// \brief Stores the replacements made by a transform to the header this
+  /// object represents.
+  void recordReplacements(llvm::StringRef TransformID,
+                          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;
+  TransformDocument TransformReplacementsDoc;
 };
 
 /// \brief Container mapping header file names to override information.
@@ -100,8 +140,10 @@ public:
   /// \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);
+                         clang::SourceManager &SM,
+                         llvm::StringRef TransformName);
+  void applyReplacements(clang::tooling::Replacements &Replaces,
+                         llvm::StringRef TransformName);
 
   /// \brief Convenience function for applying this source's overrides to
   /// the given SourceManager.
@@ -118,13 +160,16 @@ public:
   /// @}
 
 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);
+  void adjustChangedRanges(const clang::tooling::Replacements &Replaces,
+                           const ReplacementsMap &HeadersReplaces);
 
   const std::string MainFileName;
   std::string MainFileOverride;

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=187428&r1=187427&r2=187428&view=diff
==============================================================================
--- clang-tools-extra/trunk/cpp11-migrate/Core/Reformatting.cpp (original)
+++ clang-tools-extra/trunk/cpp11-migrate/Core/Reformatting.cpp Tue Jul 30 13:18:02 2013
@@ -47,10 +47,10 @@ void Reformatter::reformatChanges(Source
        I != E; ++I) {
     const HeaderOverride &Header = I->getValue();
     const tooling::Replacements &HeaderReplaces =
-        reformatSingleFile(Header.FileName, Header.Changes, SM);
+        reformatSingleFile(Header.getFileName(), Header.getChanges(), SM);
     Replaces.insert(HeaderReplaces.begin(), HeaderReplaces.end());
   }
-  Overrides.applyReplacements(Replaces, SM);
+  Overrides.applyReplacements(Replaces, SM, "reformatter");
 }
 
 tooling::Replacements Reformatter::reformatSingleFile(

Added: clang-tools-extra/trunk/cpp11-migrate/Core/ReplacementsYaml.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/Core/ReplacementsYaml.h?rev=187428&view=auto
==============================================================================
--- clang-tools-extra/trunk/cpp11-migrate/Core/ReplacementsYaml.h (added)
+++ clang-tools-extra/trunk/cpp11-migrate/Core/ReplacementsYaml.h Tue Jul 30 13:18:02 2013
@@ -0,0 +1,115 @@
+//===-- Core/ReplacementsYaml.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 provides structs to store the migrator specific header
+/// replacements and the YAML traits for Replacements.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef CPP11_MIGRATE_REPLACEMENTS_YAML_H
+#define CPP11_MIGRATE_REPLACEMENTS_YAML_H
+
+#include "clang/Tooling/Refactoring.h"
+#include "llvm/Support/YAMLTraits.h"
+#include <vector>
+#include <string>
+
+/// \brief A replacement struct to store the transform ID and the replacement.
+struct TransformReplacements {
+  std::string TransformID;
+  std::vector<clang::tooling::Replacement> GeneratedReplacements;
+};
+
+/// \brief The top-level YAML document that contains the name of the file and
+/// the TransformReplacements.
+struct TransformDocument {
+  std::string FileName;
+  std::vector<TransformReplacements> Replacements;
+};
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::Replacement)
+LLVM_YAML_IS_SEQUENCE_VECTOR(TransformReplacements)
+
+namespace llvm {
+namespace yaml {
+
+/// \brief ScalarTraits to read/write std::string objects.
+template <>
+struct ScalarTraits<std::string> {
+  static void output(const std::string &Val, void *, llvm::raw_ostream &Out) {
+    // We need to put quotes around the string to make sure special characters
+    // in the string is not treated as YAML tokens.
+    std::string NormalizedVal = std::string("\"") + Val + std::string("\"");
+    Out << NormalizedVal;
+  }
+
+  static StringRef input(StringRef Scalar, void *, std::string &Val) {
+    Val = Scalar;
+    return StringRef();
+  }
+};
+
+/// \brief Specialized MappingTraits for Repleacements to be converted to/from
+/// a YAML File.
+template <>
+struct MappingTraits<clang::tooling::Replacement> {
+  /// \brief Normalize clang::tooling::Replacement to provide direct access to
+  /// its members.
+  struct NormalizedReplacement {
+    NormalizedReplacement(const IO &)
+        : FilePath(""), Offset(0), Length(0), ReplacementText("") {}
+
+    NormalizedReplacement(const IO &, const clang::tooling::Replacement &R)
+        : FilePath(R.getFilePath()), Offset(R.getOffset()),
+          Length(R.getLength()), ReplacementText(R.getReplacementText()) {}
+
+    clang::tooling::Replacement denormalize(const IO &) {
+      return clang::tooling::Replacement(FilePath, Offset, Length,
+                                         ReplacementText);
+    }
+
+    std::string FilePath;
+    unsigned int Offset;
+    unsigned int Length;
+    std::string ReplacementText;
+  };
+
+  static void mapping(IO &Io, clang::tooling::Replacement &R) {
+    MappingNormalization<NormalizedReplacement, clang::tooling::Replacement>
+        Keys(Io, R);
+    Io.mapRequired("Offset", Keys->Offset);
+    Io.mapRequired("Length", Keys->Length);
+    Io.mapRequired("ReplacementText", Keys->ReplacementText);
+  }
+};
+
+/// \brief Specialized MappingTraits for TransformRepleacements to be converted
+/// to/from a YAML File.
+template <>
+struct MappingTraits<TransformReplacements> {
+  static void mapping(IO &Io, TransformReplacements &R) {
+    Io.mapRequired("TransformID", R.TransformID);
+    Io.mapRequired("Replacements", R.GeneratedReplacements);
+  }
+};
+
+/// \brief Specialized MappingTraits for TransformDocument to be converted
+/// to/from a YAML File.
+template <>
+struct MappingTraits<TransformDocument> {
+  static void mapping(IO &Io, TransformDocument &TD) {
+    Io.mapRequired("FileName", TD.FileName);
+    Io.mapRequired("Transforms", TD.Replacements);
+  }
+};
+} // end namespace yaml
+} // end namespace llvm
+
+#endif // CPP11_MIGRATE_REPLACEMENTS_YAML_H

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=187428&r1=187427&r2=187428&view=diff
==============================================================================
--- clang-tools-extra/trunk/cpp11-migrate/Core/Transform.cpp (original)
+++ clang-tools-extra/trunk/cpp11-migrate/Core/Transform.cpp Tue Jul 30 13:18:02 2013
@@ -118,7 +118,7 @@ bool Transform::handleBeginSource(Compil
 void Transform::handleEndSource() {
   if (!getReplacements().empty()) {
     SourceOverrides &SO = Overrides->getOrCreate(CurrentSource);
-    SO.applyReplacements(getReplacements());
+    SO.applyReplacements(getReplacements(), getName());
   }
 
   if (Options().EnableTiming)

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=187428&r1=187427&r2=187428&view=diff
==============================================================================
--- clang-tools-extra/trunk/cpp11-migrate/tool/Cpp11Migrate.cpp (original)
+++ clang-tools-extra/trunk/cpp11-migrate/tool/Cpp11Migrate.cpp Tue Jul 30 13:18:02 2013
@@ -325,13 +325,40 @@ int main(int argc, const char **argv) {
     for (HeaderOverrides::const_iterator HeaderI = Overrides.headers_begin(),
                                          HeaderE = Overrides.headers_end();
          HeaderI != HeaderE; ++HeaderI) {
-      assert(!HeaderI->second.FileOverride.empty() &&
+      assert(!HeaderI->second.getContentOverride().empty() &&
              "A header override should not be empty");
       std::string ErrorInfo;
       std::string HeaderFileName = HeaderI->getKey();
       llvm::raw_fd_ostream HeaderStream(HeaderFileName.c_str(), ErrorInfo,
                                         llvm::sys::fs::F_Binary);
-      HeaderStream << HeaderI->second.FileOverride;
+      if (!ErrorInfo.empty()) {
+        llvm::errs() << "Error opening file: " << ErrorInfo << "\n";
+        continue;
+      }
+      HeaderStream << HeaderI->second.getContentOverride();
+
+      // 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(), HeaderFileName,
+                                                 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<TransformDocument &>(
+                  HeaderI->getValue().getTransformReplacementsDoc());
     }
   }
 

Added: clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/common.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/common.cpp?rev=187428&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/common.cpp (added)
+++ clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/common.cpp Tue Jul 30 13:18:02 2013
@@ -0,0 +1,16 @@
+// This is just a dummy run command to keep lit happy. Tests for this file are
+// in main.cpp
+// RUN: true
+
+#include "common.h"
+
+void func1(int &I) {
+}
+
+void func2() {
+  container C1;
+  container C2;
+  for (container::iterator I = C1.begin(), E = C1.end(); I != E; ++I) {
+    C2.push_back(*I);
+  }
+}

Added: clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/common.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/common.h?rev=187428&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/common.h (added)
+++ clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/common.h Tue Jul 30 13:18:02 2013
@@ -0,0 +1,27 @@
+#ifndef CPP11_MIGRATE_TEST_HEADER_REPLACEMENTS_COMMON_H
+#define CPP11_MIGRATE_TEST_HEADER_REPLACEMENTS_COMMON_H
+
+struct container {
+  struct iterator {
+    int &operator*();
+    const int &operator*() const;
+    iterator &operator++();
+    bool operator!=(const iterator &other);
+  };
+
+  iterator begin();
+  iterator end();
+  void push_back(const int &);
+};
+
+void func1(int &I);
+void func2();
+
+void dostuff() {
+  container C;
+  for (container::iterator I = C.begin(), E = C.end(); I != E; ++I) {
+    func1(*I);
+  }
+}
+
+#endif // CPP11_MIGRATE_TEST_HEADER_REPLACEMENTS_COMMON_H

Added: 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=187428&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/common.h.yaml (added)
+++ clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/common.h.yaml Tue Jul 30 13:18:02 2013
@@ -0,0 +1,12 @@
+---
+FileName: "common.h"
+Transforms:
+  - TransformID:     "LoopConvert"
+    Replacements:
+      - Offset:          432
+        Length:          61
+        ReplacementText: "(auto & elem : C)"
+      - Offset:          506
+        Length:          2
+        ReplacementText: "elem"
+...

Added: 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=187428&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/main.cpp (added)
+++ clang-tools-extra/trunk/test/cpp11-migrate/HeaderReplacements/main.cpp Tue Jul 30 13:18:02 2013
@@ -0,0 +1,39 @@
+// XFAIL: win32
+// This test fails on windows due to a bug in writing to header replacements.
+//
+// The following block tests the following:
+//   - Only 1 file is generated per translation unit and header file
+//   - 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 -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 | grep -c "main.cpp_common.h_.*.yaml" | grep "^1$"
+// RUN: ls -1 %t/Test | grep -c "common.cpp_common.h_.*.yaml" | grep "^1$"
+// We need to remove the path from FileName in the generated YAML file because it will have a path in the temp directory
+// RUN: sed -i -e 's/^\(FileName:\).*[\/\\]\(.*\)"$/\1 "\2"/g' %t/Test/main.cpp_common.h_*.yaml
+// RUN: sed -i -e 's/^\(FileName:\).*[\/\\]\(.*\)"$/\1 "\2"/g' %t/Test/common.cpp_common.h_*.yaml
+// RUN: diff -b %S/common.h.yaml %t/Test/main.cpp_common.h_*.yaml
+// RUN: diff -b %S/common.h.yaml %t/Test/common.cpp_common.h_*.yaml
+//
+// 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 -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 | grep -c "main.cpp_common.h_.*.yaml" | grep "^1$"
+// RUN: ls -1 %t/Test | not grep "common.cpp_common.h_.*.yaml"
+// We need to remove the path from FileName in the generated YAML file because it will have a path in the temp directory
+// RUN: sed -i -e 's/^\(FileName:\).*[\/\\]\(.*\)"$/\1 "\2"/g' %t/Test/main.cpp_common.h_*.yaml
+// RUN: diff -b %S/common.h.yaml %t/Test/main.cpp_common.h_*.yaml
+
+#include "common.h"
+
+void test_header_replacement() {
+  dostuff();
+  func2();
+}

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=187428&r1=187427&r2=187428&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/cpp11-migrate/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/unittests/cpp11-migrate/CMakeLists.txt Tue Jul 30 13:18:02 2013
@@ -11,6 +11,7 @@ add_extra_unittest(Cpp11MigrateTests
   ReformattingTest.cpp
   IncludeExcludeTest.cpp
   PerfSupportTest.cpp
+  ReplacementsYamlTest.cpp
   TransformTest.cpp
   UniqueHeaderNameTest.cpp
   )

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=187428&r1=187427&r2=187428&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/cpp11-migrate/FileOverridesTest.cpp (original)
+++ clang-tools-extra/trunk/unittests/cpp11-migrate/FileOverridesTest.cpp Tue Jul 30 13:18:02 2013
@@ -30,8 +30,10 @@ TEST(SourceOverridesTest, Interface) {
   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());
+  Replaces.insert(
+      Replacement(FileName, 0, ReplacementLength, "auto"));
+  Overrides.applyReplacements(Replaces, VFHelper.getNewSourceManager(),
+                              "use-auto");
   EXPECT_TRUE(Overrides.isSourceOverriden());
 
   std::string ExpectedContent = "auto long_type =\n"

Modified: clang-tools-extra/trunk/unittests/cpp11-migrate/IncludeExcludeTest.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/cpp11-migrate/IncludeExcludeTest.cpp?rev=187428&r1=187427&r2=187428&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/cpp11-migrate/IncludeExcludeTest.cpp (original)
+++ clang-tools-extra/trunk/unittests/cpp11-migrate/IncludeExcludeTest.cpp Tue Jul 30 13:18:02 2013
@@ -7,24 +7,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "Utility.h"
 #include "Core/IncludeExcludeInfo.h"
 #include "gtest/gtest.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 #include <fstream>
 
-// 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 {                                                                     \
-  }
-
 TEST(IncludeExcludeTest, ParseString) {
   IncludeExcludeInfo IEManager;
   llvm::error_code Err = IEManager.readListFromString(

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=187428&r1=187427&r2=187428&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/cpp11-migrate/ReformattingTest.cpp (original)
+++ clang-tools-extra/trunk/unittests/cpp11-migrate/ReformattingTest.cpp Tue Jul 30 13:18:02 2013
@@ -39,7 +39,8 @@ TEST(Reformatter, SingleReformat) {
       FileName, Changes, VFHelper.getNewSourceManager());
 
   SourceOverrides Overrides(FileName, /*TrackChanges=*/false);
-  Overrides.applyReplacements(Replaces, VFHelper.getNewSourceManager());
+  Overrides.applyReplacements(Replaces, VFHelper.getNewSourceManager(),
+                              "reformatter");
 
   std::string Expected, Result;
 

Added: clang-tools-extra/trunk/unittests/cpp11-migrate/ReplacementsYamlTest.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/cpp11-migrate/ReplacementsYamlTest.cpp?rev=187428&view=auto
==============================================================================
--- clang-tools-extra/trunk/unittests/cpp11-migrate/ReplacementsYamlTest.cpp (added)
+++ clang-tools-extra/trunk/unittests/cpp11-migrate/ReplacementsYamlTest.cpp Tue Jul 30 13:18:02 2013
@@ -0,0 +1,84 @@
+//===- unittests/cpp11-migrate/ReplacementsYamlTest.cpp -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Test for the Yaml files generated by transforms on header files.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Utility.h"
+#include "Core/FileOverrides.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+TEST(ReplacementsYamlTest, writeReadTest) {
+  using clang::tooling::Replacement;
+
+  const std::string HeaderFileName = "/path/to/common.h";
+  const std::string TransformID = "loop-convert";
+  const unsigned int ReplacementOffset1 = 232;
+  const unsigned int ReplacementLength1 = 56;
+  const std::string ReplacementText1 = "(auto & elem : V)";
+  const unsigned int ReplacementOffset2 = 301;
+  const unsigned int ReplacementLength2 = 2;
+  const std::string ReplacementText2 = "elem";
+
+  TransformReplacements TR;
+  TR.TransformID = TransformID;
+  TR.GeneratedReplacements
+      .push_back(Replacement(HeaderFileName, ReplacementOffset1,
+                             ReplacementLength1, ReplacementText1));
+  TR.GeneratedReplacements
+      .push_back(Replacement(HeaderFileName, ReplacementOffset2,
+                             ReplacementLength2, ReplacementText2));
+
+  TransformDocument TD;
+  TD.FileName = HeaderFileName.c_str();
+  TD.Replacements.push_back(TR);
+
+  std::string YamlContent;
+  llvm::raw_string_ostream YamlContentStream(YamlContent);
+
+  // Write to the YAML file.
+  {
+    yaml::Output YAML(YamlContentStream);
+    YAML << TD;
+    YamlContentStream.str();
+    ASSERT_NE(YamlContent.length(), 0u);
+  }
+
+  // Read from the YAML file and verify that what was written is exactly what
+  // we read back.
+  {
+    TransformDocument TDActual;
+    yaml::Input YAML(YamlContent);
+    YAML >> TDActual;
+    ASSERT_NO_ERROR(YAML.error());
+    EXPECT_EQ(HeaderFileName, TDActual.FileName);
+    ASSERT_EQ(1u, TDActual.Replacements.size());
+
+    TransformReplacements TRActual = TDActual.Replacements[0];
+    EXPECT_EQ(TransformID, TRActual.TransformID);
+    ASSERT_EQ(2u, TRActual.GeneratedReplacements.size());
+
+    EXPECT_EQ(ReplacementOffset1,
+              TRActual.GeneratedReplacements[0].getOffset());
+    EXPECT_EQ(ReplacementLength1,
+              TRActual.GeneratedReplacements[0].getLength());
+    EXPECT_EQ(ReplacementText1,
+              TRActual.GeneratedReplacements[0].getReplacementText().str());
+
+    EXPECT_EQ(ReplacementOffset2,
+              TRActual.GeneratedReplacements[1].getOffset());
+    EXPECT_EQ(ReplacementLength2,
+              TRActual.GeneratedReplacements[1].getLength());
+    EXPECT_EQ(ReplacementText2,
+              TRActual.GeneratedReplacements[1].getReplacementText().str());
+  }
+}

Added: clang-tools-extra/trunk/unittests/cpp11-migrate/Utility.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/cpp11-migrate/Utility.h?rev=187428&view=auto
==============================================================================
--- clang-tools-extra/trunk/unittests/cpp11-migrate/Utility.h (added)
+++ clang-tools-extra/trunk/unittests/cpp11-migrate/Utility.h Tue Jul 30 13:18:02 2013
@@ -0,0 +1,25 @@
+//=-- cpp11-migrate/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 CPP11_MIGRATE_UNITTESTS_UTILITY_H
+#define CPP11_MIGRATE_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 // CPP11_MIGRATE_UNITTESTS_UTILITY_H





More information about the cfe-commits mailing list