[clang-tools-extra] r187428 - cpp11-migrate: Write header replacements to disk
Alex Rosenberg
alexr at leftfield.org
Tue Jul 30 12:48:14 PDT 2013
I missed the initial discussion here, but I'm wondering why YAML is being used here and not just outputting a diff.
Sent from my iPad
On Jul 30, 2013, at 11:18 AM, "Tareq A. Siraj" <tareq.a.sriaj at intel.com> wrote:
> 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
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list