summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/cpp11-migrate
diff options
context:
space:
mode:
authorEdwin Vane <edwin.vane@intel.com>2013-09-03 13:16:02 +0000
committerEdwin Vane <edwin.vane@intel.com>2013-09-03 13:16:02 +0000
commit147984a8adf15183de3f3a25f74b7b3620e2a1a6 (patch)
treebf419f9698f16461fb7d4160a9a6175c5d5d6383 /clang-tools-extra/cpp11-migrate
parent249c7fb10eb837cc78a6e6d26aef9ad802111440 (diff)
downloadbcm5719-llvm-147984a8adf15183de3f3a25f74b7b3620e2a1a6.tar.gz
bcm5719-llvm-147984a8adf15183de3f3a25f74b7b3620e2a1a6.zip
cpp11-migrate: Refactor for driver model of operation
Re-commit of r189691 and r189689 now with a proper autoconf fix. Massive simplification of how replacements and file overrides are handled by the migrator: * Sources and headers are all treated the same. * All replacements for a given translation unit are stored in the same TranslationUnitReplacements structure. * Change tracking is updated only from main file; no need for propagating "is tracking" flag around. * Transform base class no longer responsible for applying replacements. They are simply stored and main() looks after deduplication and application. * Renamed -yaml-only to -serialize-replacements. Same restrictions apply: Can only request one transform. New restriction: formatting cannot also be turned on since it's basically a transform. * If -serialize-replacements is requested, changes to files will not be applied on disk. * Changed behaviour of function generating names for serialized replacements: Only the main source file goes into the name of the file since a file may contain changes for multiple different files. * Updated HeaderReplacements LIT test for new serialization behaviour. * Replaced old test that ensures replacements are not serialized if -serialize-replacements is not provided. New version ensures changes are made directly to all files in the translation unit. * Updated unit tests. * Due to major simplification of structures in FileOverrides.h, the FileOverridesTest is quite a bit simpler now. llvm-svn: 189798
Diffstat (limited to 'clang-tools-extra/cpp11-migrate')
-rw-r--r--clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.cpp4
-rw-r--r--clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.h2
-rw-r--r--clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.cpp3
-rw-r--r--clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.h12
-rw-r--r--clang-tools-extra/cpp11-migrate/CMakeLists.txt8
-rw-r--r--clang-tools-extra/cpp11-migrate/Core/FileOverrides.cpp227
-rw-r--r--clang-tools-extra/cpp11-migrate/Core/FileOverrides.h202
-rw-r--r--clang-tools-extra/cpp11-migrate/Core/Makefile2
-rw-r--r--clang-tools-extra/cpp11-migrate/Core/Refactoring.h31
-rw-r--r--clang-tools-extra/cpp11-migrate/Core/Reformatting.cpp46
-rw-r--r--clang-tools-extra/cpp11-migrate/Core/Reformatting.h40
-rw-r--r--clang-tools-extra/cpp11-migrate/Core/SyntaxCheck.cpp4
-rw-r--r--clang-tools-extra/cpp11-migrate/Core/Transform.cpp28
-rw-r--r--clang-tools-extra/cpp11-migrate/Core/Transform.h31
-rw-r--r--clang-tools-extra/cpp11-migrate/LoopConvert/LoopActions.cpp17
-rw-r--r--clang-tools-extra/cpp11-migrate/LoopConvert/LoopActions.h8
-rw-r--r--clang-tools-extra/cpp11-migrate/LoopConvert/LoopConvert.cpp24
-rw-r--r--clang-tools-extra/cpp11-migrate/LoopConvert/LoopConvert.h2
-rw-r--r--clang-tools-extra/cpp11-migrate/PassByValue/PassByValue.cpp9
-rw-r--r--clang-tools-extra/cpp11-migrate/PassByValue/PassByValue.h2
-rw-r--r--clang-tools-extra/cpp11-migrate/PassByValue/PassByValueActions.cpp12
-rw-r--r--clang-tools-extra/cpp11-migrate/PassByValue/PassByValueActions.h12
-rw-r--r--clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.cpp8
-rw-r--r--clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.h2
-rw-r--r--clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.cpp7
-rw-r--r--clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.h16
-rw-r--r--clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.cpp11
-rw-r--r--clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.h2
-rw-r--r--clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.cpp7
-rw-r--r--clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.h16
-rw-r--r--clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.cpp33
-rw-r--r--clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.h6
-rw-r--r--clang-tools-extra/cpp11-migrate/UseNullptr/UseNullptr.cpp5
-rw-r--r--clang-tools-extra/cpp11-migrate/UseNullptr/UseNullptr.h2
-rw-r--r--clang-tools-extra/cpp11-migrate/tool/CMakeLists.txt1
-rw-r--r--clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp227
-rw-r--r--clang-tools-extra/cpp11-migrate/tool/Makefile4
37 files changed, 475 insertions, 598 deletions
diff --git a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.cpp b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.cpp
index db38fa64b56..9a13c044e5d 100644
--- a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.cpp
+++ b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.cpp
@@ -29,13 +29,13 @@ static cl::opt<bool> DetectMacros(
cl::desc("Detect and use macros that expand to the 'override' keyword."),
cl::cat(TransformsOptionsCategory));
-int AddOverrideTransform::apply(FileOverrides &InputStates,
+int AddOverrideTransform::apply(const FileOverrides &InputStates,
const CompilationDatabase &Database,
const std::vector<std::string> &SourcePaths) {
ClangTool AddOverrideTool(Database, SourcePaths);
unsigned AcceptedChanges = 0;
MatchFinder Finder;
- AddOverrideFixer Fixer(getReplacements(), AcceptedChanges, DetectMacros,
+ AddOverrideFixer Fixer(AcceptedChanges, DetectMacros,
/*Owner=*/ *this);
Finder.addMatcher(makeCandidateForOverrideAttrMatcher(), &Fixer);
diff --git a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.h b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.h
index 81ceaed859c..8c39775e48d 100644
--- a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.h
+++ b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.h
@@ -31,7 +31,7 @@ public:
: Transform("AddOverride", Options) {}
/// \see Transform::run().
- virtual int apply(FileOverrides &InputStates,
+ virtual int apply(const FileOverrides &InputStates,
const clang::tooling::CompilationDatabase &Database,
const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE;
diff --git a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.cpp b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.cpp
index 47c070e55ae..134318ed386 100644
--- a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.cpp
+++ b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.cpp
@@ -95,6 +95,7 @@ void AddOverrideFixer::run(const MatchFinder::MatchResult &Result) {
if (!MacroName.empty())
ReplacementText = (" " + MacroName).str();
}
- Replace.insert(tooling::Replacement(SM, StartLoc, 0, ReplacementText));
+ Owner.addReplacementForCurrentTU(
+ tooling::Replacement(SM, StartLoc, 0, ReplacementText));
++AcceptedChanges;
}
diff --git a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.h b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.h
index 54877d538a4..afcebeffd4b 100644
--- a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.h
+++ b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.h
@@ -25,11 +25,10 @@ class Transform;
///
class AddOverrideFixer : public clang::ast_matchers::MatchFinder::MatchCallback {
public:
- AddOverrideFixer(clang::tooling::Replacements &Replace,
- unsigned &AcceptedChanges, bool DetectMacros,
- const Transform &Owner)
- : Replace(Replace), AcceptedChanges(AcceptedChanges),
- DetectMacros(DetectMacros), Owner(Owner) {}
+ AddOverrideFixer(unsigned &AcceptedChanges, bool DetectMacros,
+ Transform &Owner)
+ : AcceptedChanges(AcceptedChanges), DetectMacros(DetectMacros),
+ Owner(Owner) {}
/// \brief Entry point to the callback called when matches are made.
virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result);
@@ -38,10 +37,9 @@ public:
private:
clang::Preprocessor *PP;
- clang::tooling::Replacements &Replace;
unsigned &AcceptedChanges;
bool DetectMacros;
- const Transform &Owner;
+ Transform &Owner;
};
#endif // CPP11_MIGRATE_ADD_OVERRIDE_ACTIONS_H
diff --git a/clang-tools-extra/cpp11-migrate/CMakeLists.txt b/clang-tools-extra/cpp11-migrate/CMakeLists.txt
index 13ec7ac2e73..41bb68ef82d 100644
--- a/clang-tools-extra/cpp11-migrate/CMakeLists.txt
+++ b/clang-tools-extra/cpp11-migrate/CMakeLists.txt
@@ -1,4 +1,10 @@
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+get_filename_component(ClangReplaceLocation
+ "${CMAKE_CURRENT_SOURCE_DIR}/../clang-replace/include" ABSOLUTE)
+
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${ClangReplaceLocation}
+ )
add_subdirectory(tool)
add_subdirectory(Core)
diff --git a/clang-tools-extra/cpp11-migrate/Core/FileOverrides.cpp b/clang-tools-extra/cpp11-migrate/Core/FileOverrides.cpp
index d8d4b3f27e1..7ab7e91c30c 100644
--- a/clang-tools-extra/cpp11-migrate/Core/FileOverrides.cpp
+++ b/clang-tools-extra/cpp11-migrate/Core/FileOverrides.cpp
@@ -29,157 +29,14 @@
using namespace clang;
using namespace clang::tooling;
-void HeaderOverride::recordReplacements(
- const clang::tooling::Replacements &Replaces) {
- Replacements.Replacements.resize(Replaces.size());
- std::copy(Replaces.begin(), Replaces.end(),
- Replacements.Replacements.begin());
-}
-
-SourceOverrides::SourceOverrides(llvm::StringRef MainFileName,
- bool TrackChanges)
- : MainFileName(MainFileName), TrackChanges(TrackChanges) {}
-
-void
-SourceOverrides::applyReplacements(clang::tooling::Replacements &Replaces) {
- llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts(
- new DiagnosticOptions());
- DiagnosticsEngine Diagnostics(
- llvm::IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
- DiagOpts.getPtr());
- FileManager Files((FileSystemOptions()));
- SourceManager SM(Diagnostics, Files);
- applyReplacements(Replaces, SM);
-}
-
-void SourceOverrides::applyReplacements(clang::tooling::Replacements &Replaces,
- clang::SourceManager &SM) {
- applyOverrides(SM);
-
- Rewriter Rewrites(SM, LangOptions());
-
- // FIXME: applyAllReplacements will indicate if it couldn't apply all
- // replacements. Handle that case.
- bool Success = tooling::applyAllReplacements(Replaces, Rewrites);
-
- if (!Success)
- llvm::errs() << "error: failed to apply some replacements.";
-
- std::string ResultBuf;
-
- for (Rewriter::buffer_iterator I = Rewrites.buffer_begin(),
- E = Rewrites.buffer_end();
- I != E; ++I) {
- const FileEntry *Entry =
- Rewrites.getSourceMgr().getFileEntryForID(I->first);
- assert(Entry != NULL && "unexpected null FileEntry");
- assert(Entry->getName() != NULL &&
- "unexpected null return from FileEntry::getName()");
- llvm::StringRef FileName = Entry->getName();
-
- // Get a copy of the rewritten buffer from the Rewriter.
- ResultBuf.clear();
- llvm::raw_string_ostream StringStream(ResultBuf);
- I->second.write(StringStream);
- StringStream.flush();
-
- if (MainFileName == FileName) {
- MainFileOverride.swap(ResultBuf);
- continue;
- }
-
- // Header overrides are treated differently. Eventually, raw replacements
- // 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];
- // "Create" HeaderOverride if not already existing
- if (HeaderOv.getHeaderPath().empty())
- HeaderOv = HeaderOverride(FileName, MainFileName);
-
- HeaderOv.swapContentOverride(ResultBuf);
- }
-
- // Separate replacements to header files
- Replacements MainFileReplaces;
- ReplacementsMap HeadersReplaces;
- for (Replacements::const_iterator I = Replaces.begin(), E = Replaces.end();
- I != E; ++I) {
- llvm::StringRef ReplacementFileName = I->getFilePath();
-
- if (ReplacementFileName == MainFileName) {
- MainFileReplaces.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(I->getValue());
- }
-
- 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()].adjustChangedRanges(I->getValue());
- }
-}
-
-void SourceOverrides::applyOverrides(SourceManager &SM) const {
- FileManager &FM = SM.getFileManager();
-
- if (isSourceOverriden())
- SM.overrideFileContents(FM.getFile(MainFileName),
- llvm::MemoryBuffer::getMemBuffer(MainFileOverride));
-
- for (HeaderOverrides::const_iterator I = Headers.begin(), E = Headers.end();
- I != E; ++I) {
- assert(!I->second.getContentOverride().empty() &&
- "Header override should not be empty!");
- SM.overrideFileContents(
- FM.getFile(I->second.getHeaderPath()),
- llvm::MemoryBuffer::getMemBuffer(I->second.getContentOverride()));
- }
-}
-
-bool generateReplacementsFileName(llvm::StringRef SourceFile,
- llvm::StringRef HeaderFile,
- llvm::SmallVectorImpl<char> &Result,
- llvm::SmallVectorImpl<char> &Error) {
+bool generateReplacementsFileName(const llvm::StringRef MainSourceFile,
+ llvm::SmallVectorImpl<char> &Result,
+ llvm::SmallVectorImpl<char> &Error) {
using namespace llvm::sys;
- std::string UniqueHeaderNameModel;
-
- // Get the filename portion of the path.
- llvm::StringRef SourceFileRef(path::filename(SourceFile));
- llvm::StringRef HeaderFileRef(path::filename(HeaderFile));
-
- // Get the actual path for the header file.
- llvm::SmallString<128> HeaderPath(HeaderFile);
- path::remove_filename(HeaderPath);
-
- // Build the model of the filename.
- llvm::raw_string_ostream UniqueHeaderNameStream(UniqueHeaderNameModel);
- UniqueHeaderNameStream << SourceFileRef << "_" << HeaderFileRef
- << "_%%_%%_%%_%%_%%_%%" << ".yaml";
- path::append(HeaderPath, UniqueHeaderNameStream.str());
Error.clear();
- if (llvm::error_code EC =
- fs::createUniqueFile(HeaderPath.c_str(), Result)) {
+ if (llvm::error_code EC = fs::createUniqueFile(
+ MainSourceFile + "_%%_%%_%%_%%_%%_%%.yaml", Result)) {
Error.append(EC.message().begin(), EC.message().end());
return false;
}
@@ -187,20 +44,6 @@ bool generateReplacementsFileName(llvm::StringRef SourceFile,
return true;
}
-FileOverrides::~FileOverrides() {
- for (SourceOverridesMap::iterator I = Overrides.begin(), E = Overrides.end();
- I != E; ++I)
- delete I->getValue();
-}
-
-SourceOverrides &FileOverrides::getOrCreate(llvm::StringRef Filename) {
- SourceOverrides *&Override = Overrides[Filename];
-
- if (Override == NULL)
- Override = new SourceOverrides(Filename, TrackChanges);
- return *Override;
-}
-
namespace {
/// \brief Comparator to be able to order tooling::Range based on their offset.
@@ -247,10 +90,11 @@ struct RangeReplacedAdjuster {
} // end anonymous namespace
-void ChangedRanges::adjustChangedRanges(const tooling::Replacements &Replaces) {
+void
+ChangedRanges::adjustChangedRanges(const tooling::ReplacementsVec &Replaces) {
// first adjust existing ranges in case they overlap with the replacements
- for (Replacements::iterator I = Replaces.begin(), E = Replaces.end(); I != E;
- ++I) {
+ for (ReplacementsVec::const_iterator I = Replaces.begin(), E = Replaces.end();
+ I != E; ++I) {
const tooling::Replacement &Replace = *I;
std::transform(Ranges.begin(), Ranges.end(), Ranges.begin(),
@@ -265,8 +109,8 @@ void ChangedRanges::adjustChangedRanges(const tooling::Replacements &Replaces) {
}
// then generate the new ranges from the replacements
- for (Replacements::iterator I = Replaces.begin(), E = Replaces.end(); I != E;
- ++I) {
+ for (ReplacementsVec::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();
@@ -303,3 +147,52 @@ void ChangedRanges::coalesceRanges() {
std::mem_fun_ref(&Range::contains)),
Ranges.end());
}
+
+void FileOverrides::applyOverrides(clang::SourceManager &SM) const {
+ FileManager &FM = SM.getFileManager();
+
+ for (FileStateMap::const_iterator I = FileStates.begin(),
+ E = FileStates.end();
+ I != E; ++I) {
+ SM.overrideFileContents(FM.getFile(I->getKey()),
+ llvm::MemoryBuffer::getMemBuffer(I->getValue()));
+ }
+}
+
+void FileOverrides::adjustChangedRanges(
+ const clang::replace::FileToReplacementsMap &Replaces) {
+
+ for (replace::FileToReplacementsMap::const_iterator I = Replaces.begin(),
+ E = Replaces.end(); I != E; ++I) {
+ ChangeTracking[I->getKey()].adjustChangedRanges(I->getValue());
+ }
+}
+
+void FileOverrides::updateState(const clang::Rewriter &Rewrites) {
+ for (Rewriter::const_buffer_iterator BufferI = Rewrites.buffer_begin(),
+ BufferE = Rewrites.buffer_end();
+ BufferI != BufferE; ++BufferI) {
+ const char *FileName =
+ Rewrites.getSourceMgr().getFileEntryForID(BufferI->first)->getName();
+ const RewriteBuffer &RewriteBuf = BufferI->second;
+ FileStates[FileName].assign(RewriteBuf.begin(), RewriteBuf.end());
+ }
+}
+
+bool FileOverrides::writeToDisk(DiagnosticsEngine &Diagnostics) const {
+ bool Errors = false;
+ for (FileStateMap::const_iterator I = FileStates.begin(),
+ E = FileStates.end();
+ I != E; ++I) {
+ std::string ErrorInfo;
+ // The extra transform through std::string is to ensure null-termination
+ // of the filename stored as the key of the StringMap.
+ llvm::raw_fd_ostream FileStream(I->getKey().str().c_str(), ErrorInfo);
+ if (!ErrorInfo.empty()) {
+ llvm::errs() << "Failed to write new state for " << I->getKey() << ".\n";
+ Errors = true;
+ }
+ FileStream << I->getValue();
+ }
+ return !Errors;
+}
diff --git a/clang-tools-extra/cpp11-migrate/Core/FileOverrides.h b/clang-tools-extra/cpp11-migrate/Core/FileOverrides.h
index 3e81abc6d34..8cde7591303 100644
--- a/clang-tools-extra/cpp11-migrate/Core/FileOverrides.h
+++ b/clang-tools-extra/cpp11-migrate/Core/FileOverrides.h
@@ -16,7 +16,8 @@
#ifndef CPP11_MIGRATE_FILE_OVERRIDES_H
#define CPP11_MIGRATE_FILE_OVERRIDES_H
-#include "clang/Tooling/Refactoring.h"
+#include "Core/Refactoring.h"
+#include "clang-replace/Tooling/ApplyReplacements.h"
#include "clang/Tooling/ReplacementsYaml.h"
#include "llvm/ADT/StringMap.h"
@@ -44,13 +45,13 @@ public:
/// to remove replaced parts.
///
/// Note that all replacements should come from the same file.
- void adjustChangedRanges(const clang::tooling::Replacements &Replaces);
+ void adjustChangedRanges(const clang::tooling::ReplacementsVec &Replaces);
/// \brief Iterators.
- /// @{
+ /// \{
const_iterator begin() const { return Ranges.begin(); }
const_iterator end() const { return Ranges.end(); }
- /// @}
+ /// \}
private:
void coalesceRanges();
@@ -58,178 +59,71 @@ private:
RangeVec Ranges;
};
-/// \brief Container for storing override information for a single headers.
-class HeaderOverride {
+/// \brief Maintains current state of transformed files and tracks source ranges
+/// where changes have been made.
+class FileOverrides {
public:
- /// \brief Constructors.
- /// @{
- HeaderOverride() {}
- HeaderOverride(llvm::StringRef HeaderPath,
- llvm::StringRef MainSourceFile) : HeaderPath(HeaderPath) {
- Replacements.MainSourceFile = MainSourceFile;
- }
- /// @}
-
- /// \brief Getter for HeaderPath.
- llvm::StringRef getHeaderPath() const {
- return HeaderPath;
- }
+ /// \brief Maps file names to file contents.
+ typedef llvm::StringMap<std::string> FileStateMap;
- /// \brief Accessor for ContentOverride.
- /// @{
- llvm::StringRef getContentOverride() const { return ContentOverride; }
- void setContentOverride(const llvm::StringRef S) { ContentOverride = S; }
- /// @}
+ /// \brief Maps file names to change tracking info for a file.
+ typedef llvm::StringMap<ChangedRanges> ChangeMap;
- /// \brief Getter for Changes.
- const ChangedRanges &getChanges() const { return Changes; }
- /// \brief Swaps the content of ContentOverride with \p S.
- void swapContentOverride(std::string &S) { ContentOverride.swap(S); }
-
- /// \brief Getter for Replacements.
- const clang::tooling::TranslationUnitReplacements &getReplacements() const {
- return Replacements;
- }
+ /// \brief Override file contents seen by \c SM for all files stored by this
+ /// object.
+ void applyOverrides(clang::SourceManager &SM) const;
- /// \brief Stores the replacements made by a transform to the header this
- /// object represents.
- void recordReplacements(const clang::tooling::Replacements &Replaces);
+ /// \brief Update change tracking information based on replacements stored in
+ /// \c Replaces.
+ void
+ adjustChangedRanges(const clang::replace::FileToReplacementsMap &Replaces);
- /// \brief Helper function to adjust the changed ranges.
- void adjustChangedRanges(const clang::tooling::Replacements &Replaces) {
- Changes.adjustChangedRanges(Replaces);
+ /// \brief Accessor for change tracking information.
+ const ChangeMap &getChangedRanges() const {
+ return ChangeTracking;
}
-private:
- std::string ContentOverride;
- ChangedRanges Changes;
- std::string HeaderPath;
- clang::tooling::TranslationUnitReplacements Replacements;
-};
-
-/// \brief Container mapping header file names to override information.
-typedef llvm::StringMap<HeaderOverride> HeaderOverrides;
-
-/// \brief Container storing the file content overrides for a source file and
-/// any headers included by the source file either directly or indirectly to
-/// which changes have been made.
-class SourceOverrides {
-public:
- SourceOverrides(llvm::StringRef MainFileName, bool TrackChanges);
-
- /// \brief Accessors.
- /// @{
- llvm::StringRef getMainFileName() const { return MainFileName; }
- llvm::StringRef getMainFileContent() const { return MainFileOverride; }
- const ChangedRanges &getChangedRanges() const { return MainFileChanges; }
-
- /// \brief Is file change tracking enabled?
+ /// \brief Coalesce changes stored in \c Rewrites and replace file contents
+ /// overrides stored in this object.
///
- /// Tracking file changes can be useful to reformat the code for example.
- bool isTrackingFileChanges() const { return TrackChanges; }
- /// @}
+ /// \param Rewrites Rewriter containing changes to files.
+ void updateState(const clang::Rewriter &Rewrites);
- /// \brief Indicates if the source file has been overridden.
- ///
- /// It's possible for a source to remain unchanged while only headers are
- /// changed.
- bool isSourceOverriden() const { return !MainFileOverride.empty(); }
+ /// \brief Accessor for current file state.
+ const FileStateMap &getState() const { return FileStates; }
- /// \brief Override the file contents by applying all the replacements.
+ /// \brief Write all file contents overrides to disk.
///
- /// \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);
-
- /// \brief Convenience function for applying this source's overrides to
- /// the given SourceManager.
- void applyOverrides(clang::SourceManager &SM) const;
-
- /// \brief Iterators.
- /// @{
- HeaderOverrides::iterator headers_begin() { return Headers.begin(); }
- HeaderOverrides::iterator headers_end() { return Headers.end(); }
- HeaderOverrides::const_iterator headers_begin() const {
- return Headers.begin();
- }
- HeaderOverrides::const_iterator headers_end() const { return Headers.end(); }
- /// @}
-
-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,
- const ReplacementsMap &HeadersReplaces);
-
- const std::string MainFileName;
- std::string MainFileOverride;
- const bool TrackChanges;
- ChangedRanges MainFileChanges;
- HeaderOverrides Headers;
-};
-
-/// \brief Maps source file names to content override information.
-class FileOverrides {
-public:
- typedef llvm::StringMap<SourceOverrides *> SourceOverridesMap;
- typedef SourceOverridesMap::const_iterator const_iterator;
-
- /// \brief Construct the SourceOverrides manager.
+ /// \param Diagnostics DiagnosticsEngine for error output.
///
- /// \param TrackChanges Wether or not the \c SourceOverrides should keep track
- /// of changes. See \c SourceOverrides::isTrackingFileChanges().
- FileOverrides(bool TrackChanges) : TrackChanges(TrackChanges) {}
- ~FileOverrides();
-
- const_iterator find(llvm::StringRef Filename) const {
- return Overrides.find(Filename);
- }
-
- /// \brief Get the \c SourceOverrides for \p Filename, creating it if
- /// necessary.
- SourceOverrides &getOrCreate(llvm::StringRef Filename);
-
- /// \brief Iterators.
- /// @{
- const_iterator begin() const { return Overrides.begin(); }
- const_iterator end() const { return Overrides.end(); }
- /// @}
+ /// \returns \li true if all files with overridden file contents were written
+ /// to disk successfully.
+ /// \li false if any failure occurred.
+ bool writeToDisk(clang::DiagnosticsEngine &Diagnostics) const;
private:
- FileOverrides(const FileOverrides &) LLVM_DELETED_FUNCTION;
- FileOverrides &operator=(const FileOverrides &) LLVM_DELETED_FUNCTION;
-
- SourceOverridesMap Overrides;
- const bool TrackChanges;
+ FileStateMap FileStates;
+ ChangeMap ChangeTracking;
};
/// \brief Generate a unique filename to store the replacements.
///
-/// Generates a unique filename in the same directory as the header file. The
-/// filename is based on the following model:
+/// Generates a unique filename in the same directory as \c MainSourceFile. The
+/// filename is generated following this pattern:
///
-/// source.cpp_header.h_%%_%%_%%_%%_%%_%%.yaml
+/// MainSourceFile_%%_%%_%%_%%_%%_%%.yaml
///
/// where all '%' will be replaced by a randomly chosen hex number.
///
-/// @param SourceFile Full path to the source file.
-/// @param HeaderFile Full path to the header file.
-/// @param Result The resulting unique filename in the same directory as the
-/// header file.
-/// @param Error Description of the error if there is any.
-/// @returns true if succeeded, false otherwise.
-bool generateReplacementsFileName(llvm::StringRef SourceFile,
- llvm::StringRef HeaderFile,
- llvm::SmallVectorImpl<char> &Result,
- llvm::SmallVectorImpl<char> &Error);
+/// \param[in] MainSourceFile Full path to the source file.
+/// \param[out] Result The resulting unique filename in the same directory as
+/// the \c MainSourceFile.
+/// \param[out] Error If an error occurs a description of that error is
+/// placed in this string.
+/// \returns true on success, false if a unique file name could not be created.
+bool generateReplacementsFileName(const llvm::StringRef MainSourceFile,
+ llvm::SmallVectorImpl<char> &Result,
+ llvm::SmallVectorImpl<char> &Error);
#endif // CPP11_MIGRATE_FILE_OVERRIDES_H
diff --git a/clang-tools-extra/cpp11-migrate/Core/Makefile b/clang-tools-extra/cpp11-migrate/Core/Makefile
index 5da4cec8481..51bc98defee 100644
--- a/clang-tools-extra/cpp11-migrate/Core/Makefile
+++ b/clang-tools-extra/cpp11-migrate/Core/Makefile
@@ -11,4 +11,4 @@ LIBRARYNAME := migrateCore
include $(CLANG_LEVEL)/Makefile
-CPP.Flags += -I$(PROJ_SRC_DIR)/..
+CPP.Flags += -I$(PROJ_SRC_DIR)/.. -I$(PROJ_SRC_DIR)/../../clang-replace/include
diff --git a/clang-tools-extra/cpp11-migrate/Core/Refactoring.h b/clang-tools-extra/cpp11-migrate/Core/Refactoring.h
new file mode 100644
index 00000000000..a15634a3704
--- /dev/null
+++ b/clang-tools-extra/cpp11-migrate/Core/Refactoring.h
@@ -0,0 +1,31 @@
+//===-- Core/Refactoring.h - Stand-in for Tooling/Refactoring.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 is meant to be used instead of clang/Tooling/Refactoring.h
+/// until such time as clang::tooling::Replacements is re-implemented as a
+/// vector instead of a set.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef CPP11_MIGRATE_REPLACEMENTS_VEC_H
+#define CPP11_MIGRATE_REPLACEMENTS_VEC_H
+
+#include "clang/Tooling/Refactoring.h"
+
+// FIXME: Remove this file when clang::tooling::Replacements becomes a vector
+// instead of a set.
+
+namespace clang {
+namespace tooling {
+typedef std::vector<clang::tooling::Replacement> ReplacementsVec;
+}
+}
+
+#endif // CPP11_MIGRATE_REPLACEMENTS_VEC_H
diff --git a/clang-tools-extra/cpp11-migrate/Core/Reformatting.cpp b/clang-tools-extra/cpp11-migrate/Core/Reformatting.cpp
index 4e14ea5784e..50ba1f19f7a 100644
--- a/clang-tools-extra/cpp11-migrate/Core/Reformatting.cpp
+++ b/clang-tools-extra/cpp11-migrate/Core/Reformatting.cpp
@@ -22,39 +22,23 @@
using namespace clang;
-void Reformatter::reformatChanges(SourceOverrides &Overrides) {
- llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts(
- new DiagnosticOptions());
- DiagnosticsEngine Diagnostics(
- llvm::IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
- DiagOpts.getPtr());
- FileManager Files((FileSystemOptions()));
- SourceManager SM(Diagnostics, Files);
-
- reformatChanges(Overrides, SM);
-}
-
-void Reformatter::reformatChanges(SourceOverrides &Overrides,
- clang::SourceManager &SM) {
- tooling::Replacements Replaces;
- Overrides.applyOverrides(SM);
- if (Overrides.isSourceOverriden())
- Replaces = reformatSingleFile(Overrides.getMainFileName(),
- Overrides.getChangedRanges(), SM);
-
- for (HeaderOverrides::const_iterator I = Overrides.headers_begin(),
- E = Overrides.headers_end();
+void Reformatter::reformatChanges(const FileOverrides &FileStates,
+ clang::SourceManager &SM,
+ clang::tooling::ReplacementsVec &Replaces) {
+ FileStates.applyOverrides(SM);
+
+ for (FileOverrides::ChangeMap::const_iterator
+ I = FileStates.getChangedRanges().begin(),
+ E = FileStates.getChangedRanges().end();
I != E; ++I) {
- const HeaderOverride &Header = I->getValue();
- const tooling::Replacements &HeaderReplaces =
- reformatSingleFile(Header.getHeaderPath(), Header.getChanges(), SM);
- Replaces.insert(HeaderReplaces.begin(), HeaderReplaces.end());
+ reformatSingleFile(I->getKey(), I->getValue(), SM, Replaces);
}
- Overrides.applyReplacements(Replaces, SM);
}
-tooling::Replacements Reformatter::reformatSingleFile(
- llvm::StringRef FileName, const ChangedRanges &Changes, SourceManager &SM) {
+void Reformatter::reformatSingleFile(
+ const llvm::StringRef FileName, const ChangedRanges &Changes,
+ SourceManager &SM, clang::tooling::ReplacementsVec &FormatReplacements) {
+
const clang::FileEntry *Entry = SM.getFileManager().getFile(FileName);
assert(Entry && "expected an existing file");
@@ -72,5 +56,7 @@ tooling::Replacements Reformatter::reformatSingleFile(
}
Lexer Lex(ID, SM.getBuffer(ID), SM, getFormattingLangOpts(Style.Standard));
- return format::reformat(Style, Lex, SM, ReformatRanges);
+ const tooling::Replacements &R =
+ format::reformat(Style, Lex, SM, ReformatRanges);
+ std::copy(R.begin(), R.end(), std::back_inserter(FormatReplacements));
}
diff --git a/clang-tools-extra/cpp11-migrate/Core/Reformatting.h b/clang-tools-extra/cpp11-migrate/Core/Reformatting.h
index e63e51d2160..9a10171a742 100644
--- a/clang-tools-extra/cpp11-migrate/Core/Reformatting.h
+++ b/clang-tools-extra/cpp11-migrate/Core/Reformatting.h
@@ -16,9 +16,10 @@
#ifndef CPP11_MIGRATE_REFORMATTING_H
#define CPP11_MIGRATE_REFORMATTING_H
+#include "Core/Refactoring.h"
#include "clang/Format/Format.h"
-class SourceOverrides;
+class FileOverrides;
class ChangedRanges;
class Reformatter {
@@ -27,31 +28,30 @@ public:
/// \brief Reformat the changes made to the file overrides.
///
- /// \param Overrides Overriden source files to reformat. Note that since only
- /// the changes are reformatted, file change tracking has to be enabled.
- /// \param SM A SourceManager where the overridens files can be found.
+ /// This function will apply the state of files stored in \c FileState to \c
+ /// SM.
///
- /// \sa \c SourceOverrides::isTrackingFileChanges()
- void reformatChanges(SourceOverrides &Overrides, clang::SourceManager &SM);
-
- /// \brief Overload of \c reformatChanges() providing it's own
- /// \c SourceManager.
- void reformatChanges(SourceOverrides &Overrides);
+ /// \param[in] FileState Files to reformat.
+ /// \param[in] SM SourceManager for access to source files.
+ /// \param[out] Replaces Container to store all reformatting replacements.
+ void reformatChanges(const FileOverrides &FileState, clang::SourceManager &SM,
+ clang::tooling::ReplacementsVec &Replaces);
/// \brief Produce a list of replacements to apply on \p FileName, only the
/// ranges in \p Changes are replaced.
///
- /// Since this routine use \c clang::format::reformat() the rules that applies
- /// on the ranges are identical:
+ /// Since this routine use \c clang::format::reformat() the rules that
+ /// function applies to ranges also apply here.
///
- /// \par
- /// Each range is extended on either end to its next bigger logic
- /// unit, i.e. everything that might influence its formatting or might be
- /// influenced by its formatting.
- /// -- \c clang::format::reformat()
- clang::tooling::Replacements reformatSingleFile(llvm::StringRef FileName,
- const ChangedRanges &Changes,
- clang::SourceManager &SM);
+ /// \param[in] FileName Name of file to reformat.
+ /// \param[in] Changes Description of where changes were made to the file.
+ /// \param[in] SM SourceManager required to create replacements.
+ /// \param[out] FormatReplacements New reformatting replacements are appended
+ /// to this container.
+ void reformatSingleFile(const llvm::StringRef FileName,
+ const ChangedRanges &Changes,
+ clang::SourceManager &SM,
+ clang::tooling::ReplacementsVec &FormatReplacements);
private:
clang::format::FormatStyle Style;
diff --git a/clang-tools-extra/cpp11-migrate/Core/SyntaxCheck.cpp b/clang-tools-extra/cpp11-migrate/Core/SyntaxCheck.cpp
index 7315768f360..bd2eb63044f 100644
--- a/clang-tools-extra/cpp11-migrate/Core/SyntaxCheck.cpp
+++ b/clang-tools-extra/cpp11-migrate/Core/SyntaxCheck.cpp
@@ -30,9 +30,7 @@ public:
if (!SyntaxOnlyAction::BeginSourceFileAction(CI, Filename))
return false;
- FileOverrides::const_iterator I = Overrides.find(Filename);
- if (I != Overrides.end())
- I->second->applyOverrides(CI.getSourceManager());
+ Overrides.applyOverrides(CI.getSourceManager());
return true;
}
diff --git a/clang-tools-extra/cpp11-migrate/Core/Transform.cpp b/clang-tools-extra/cpp11-migrate/Core/Transform.cpp
index 4354df2987e..cd76723d316 100644
--- a/clang-tools-extra/cpp11-migrate/Core/Transform.cpp
+++ b/clang-tools-extra/cpp11-migrate/Core/Transform.cpp
@@ -100,13 +100,8 @@ bool Transform::isFileModifiable(const SourceManager &SM,
bool Transform::handleBeginSource(CompilerInstance &CI, StringRef Filename) {
assert(Overrides != 0 && "Subclass transform didn't provide InputState");
- CurrentSource = Filename.str();
-
- FileOverrides::const_iterator I = Overrides->find(CurrentSource);
- if (I != Overrides->end())
- I->second->applyOverrides(CI.getSourceManager());
-
- Replace.clear();
+ Overrides->applyOverrides(CI.getSourceManager());
+ CurrentSource = Filename;
if (Options().EnableTiming) {
Timings.push_back(std::make_pair(Filename.str(), llvm::TimeRecord()));
@@ -116,11 +111,7 @@ bool Transform::handleBeginSource(CompilerInstance &CI, StringRef Filename) {
}
void Transform::handleEndSource() {
- if (!getReplacements().empty()) {
- SourceOverrides &SO = Overrides->getOrCreate(CurrentSource);
- SO.applyReplacements(getReplacements());
- }
-
+ CurrentSource.clear();
if (Options().EnableTiming)
Timings.back().second += llvm::TimeRecord::getCurrentTime(false);
}
@@ -129,6 +120,19 @@ void Transform::addTiming(llvm::StringRef Label, llvm::TimeRecord Duration) {
Timings.push_back(std::make_pair(Label.str(), Duration));
}
+bool
+Transform::addReplacementForCurrentTU(const clang::tooling::Replacement &R) {
+ if (CurrentSource.empty())
+ return false;
+
+ TranslationUnitReplacements &TU = Replacements[CurrentSource];
+ if (TU.MainSourceFile.empty())
+ TU.MainSourceFile = CurrentSource;
+ TU.Replacements.push_back(R);
+
+ return true;
+}
+
FrontendActionFactory *Transform::createActionFactory(MatchFinder &Finder) {
return new ActionFactory(Finder, /*Owner=*/ *this);
}
diff --git a/clang-tools-extra/cpp11-migrate/Core/Transform.h b/clang-tools-extra/cpp11-migrate/Core/Transform.h
index 43082111d54..45e470d64e4 100644
--- a/clang-tools-extra/cpp11-migrate/Core/Transform.h
+++ b/clang-tools-extra/cpp11-migrate/Core/Transform.h
@@ -17,7 +17,7 @@
#define CPP11_MIGRATE_TRANSFORM_H
#include "Core/IncludeExcludeInfo.h"
-#include "clang/Tooling/Refactoring.h"
+#include "Core/Refactoring.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Registry.h"
@@ -52,6 +52,12 @@ class MatchFinder;
class FileOverrides;
+
+// \brief Maps main source file names to a TranslationUnitReplacements
+// structure storing replacements for that translation unit.
+typedef llvm::StringMap<clang::tooling::TranslationUnitReplacements>
+TUReplacementsMap;
+
/// \brief To group transforms' options together when printing the help.
extern llvm::cl::OptionCategory TransformsOptionsCategory;
@@ -99,7 +105,7 @@ public:
/// SourcePaths and should take precedence over content of files on disk.
/// Upon return, \p ResultStates shall contain the result of performing this
/// transform on the files listed in \p SourcePaths.
- virtual int apply(FileOverrides &InputStates,
+ virtual int apply(const FileOverrides &InputStates,
const clang::tooling::CompilationDatabase &Database,
const std::vector<std::string> &SourcePaths) = 0;
@@ -172,6 +178,17 @@ public:
/// \brief Return an iterator to the start of collected timing data.
TimingVec::const_iterator timing_end() const { return Timings.end(); }
+ /// \brief Add a Replacement to the list for the current translation unit.
+ ///
+ /// \returns \li true on success
+ /// \li false if there is no current translation unit
+ bool addReplacementForCurrentTU(const clang::tooling::Replacement &R);
+
+ /// \brief Accessor to Replacements across all transformed translation units.
+ const TUReplacementsMap &getAllReplacements() const {
+ return Replacements;
+ }
+
protected:
void setAcceptedChanges(unsigned Changes) {
@@ -195,16 +212,12 @@ protected:
/// created with.
const TransformOptions &Options() { return GlobalOptions; }
- /// \brief Provide access for subclasses for the container to store
- /// translation unit replacements.
- clang::tooling::Replacements &getReplacements() { return Replace; }
-
/// \brief Affords a subclass to provide file contents overrides before
/// applying frontend actions.
///
/// It is an error not to call this function before calling ClangTool::run()
/// with the factory provided by createActionFactory().
- void setOverrides(FileOverrides &Overrides) {
+ void setOverrides(const FileOverrides &Overrides) {
this->Overrides = &Overrides;
}
@@ -219,8 +232,8 @@ protected:
private:
const std::string Name;
const TransformOptions &GlobalOptions;
- FileOverrides *Overrides;
- clang::tooling::Replacements Replace;
+ const FileOverrides *Overrides;
+ TUReplacementsMap Replacements;
std::string CurrentSource;
TimingVec Timings;
unsigned AcceptedChanges;
diff --git a/clang-tools-extra/cpp11-migrate/LoopConvert/LoopActions.cpp b/clang-tools-extra/cpp11-migrate/LoopConvert/LoopActions.cpp
index da9d7b56557..0ba49d8ad4f 100644
--- a/clang-tools-extra/cpp11-migrate/LoopConvert/LoopActions.cpp
+++ b/clang-tools-extra/cpp11-migrate/LoopConvert/LoopActions.cpp
@@ -815,9 +815,9 @@ void LoopFixer::doConversion(ASTContext *Context,
// the declaration of the alias variable. This is probably a bug.
ReplacementText = ";";
- Replace->insert(Replacement(Context->getSourceManager(),
- CharSourceRange::getTokenRange(ReplaceRange),
- ReplacementText));
+ Owner.addReplacementForCurrentTU(Replacement(
+ Context->getSourceManager(),
+ CharSourceRange::getTokenRange(ReplaceRange), ReplacementText));
// No further replacements are made to the loop, since the iterator or index
// was used exactly once - in the initialization of AliasVar.
} else {
@@ -830,10 +830,9 @@ void LoopFixer::doConversion(ASTContext *Context,
I != E; ++I) {
std::string ReplaceText = I->IsArrow ? VarName + "." : VarName;
ReplacedVarRanges->insert(std::make_pair(TheLoop, IndexVar));
- Replace->insert(
+ Owner.addReplacementForCurrentTU(
Replacement(Context->getSourceManager(),
- CharSourceRange::getTokenRange(I->Range),
- ReplaceText));
+ CharSourceRange::getTokenRange(I->Range), ReplaceText));
}
}
@@ -862,9 +861,9 @@ void LoopFixer::doConversion(ASTContext *Context,
std::string TypeString = AutoRefType.getAsString();
std::string Range = ("(" + TypeString + " " + VarName + " : "
+ MaybeDereference + ContainerString + ")").str();
- Replace->insert(Replacement(Context->getSourceManager(),
- CharSourceRange::getTokenRange(ParenRange),
- Range));
+ Owner.addReplacementForCurrentTU(
+ Replacement(Context->getSourceManager(),
+ CharSourceRange::getTokenRange(ParenRange), Range));
GeneratedDecls->insert(make_pair(TheLoop, VarName));
}
diff --git a/clang-tools-extra/cpp11-migrate/LoopConvert/LoopActions.h b/clang-tools-extra/cpp11-migrate/LoopConvert/LoopActions.h
index 95c1b021576..b72576bde82 100644
--- a/clang-tools-extra/cpp11-migrate/LoopConvert/LoopActions.h
+++ b/clang-tools-extra/cpp11-migrate/LoopConvert/LoopActions.h
@@ -41,12 +41,11 @@ enum LoopFixerKind {
class LoopFixer : public clang::ast_matchers::MatchFinder::MatchCallback {
public:
LoopFixer(StmtAncestorASTVisitor *ParentFinder,
- clang::tooling::Replacements *Replace,
StmtGeneratedVarNameMap *GeneratedDecls,
ReplacedVarsMap *ReplacedVarRanges, unsigned *AcceptedChanges,
unsigned *DeferredChanges, unsigned *RejectedChanges,
- RiskLevel MaxRisk, LoopFixerKind FixerKind, const Transform &Owner)
- : ParentFinder(ParentFinder), Replace(Replace),
+ RiskLevel MaxRisk, LoopFixerKind FixerKind, Transform &Owner)
+ : ParentFinder(ParentFinder),
GeneratedDecls(GeneratedDecls), ReplacedVarRanges(ReplacedVarRanges),
AcceptedChanges(AcceptedChanges), DeferredChanges(DeferredChanges),
RejectedChanges(RejectedChanges), MaxRisk(MaxRisk),
@@ -57,7 +56,6 @@ class LoopFixer : public clang::ast_matchers::MatchFinder::MatchCallback {
private:
StmtAncestorASTVisitor *ParentFinder;
- clang::tooling::Replacements *Replace;
StmtGeneratedVarNameMap *GeneratedDecls;
ReplacedVarsMap *ReplacedVarRanges;
unsigned *AcceptedChanges;
@@ -65,7 +63,7 @@ class LoopFixer : public clang::ast_matchers::MatchFinder::MatchCallback {
unsigned *RejectedChanges;
RiskLevel MaxRisk;
LoopFixerKind FixerKind;
- const Transform &Owner;
+ Transform &Owner;
/// \brief Computes the changes needed to convert a given for loop, and
/// applies it.
diff --git a/clang-tools-extra/cpp11-migrate/LoopConvert/LoopConvert.cpp b/clang-tools-extra/cpp11-migrate/LoopConvert/LoopConvert.cpp
index 73c2560e796..2dfa4562929 100644
--- a/clang-tools-extra/cpp11-migrate/LoopConvert/LoopConvert.cpp
+++ b/clang-tools-extra/cpp11-migrate/LoopConvert/LoopConvert.cpp
@@ -24,7 +24,7 @@ using clang::ast_matchers::MatchFinder;
using namespace clang::tooling;
using namespace clang;
-int LoopConvertTransform::apply(FileOverrides &InputStates,
+int LoopConvertTransform::apply(const FileOverrides &InputStates,
const CompilationDatabase &Database,
const std::vector<std::string> &SourcePaths) {
ClangTool LoopTool(Database, SourcePaths);
@@ -37,20 +37,20 @@ int LoopConvertTransform::apply(FileOverrides &InputStates,
unsigned RejectedChanges = 0;
MatchFinder Finder;
- LoopFixer ArrayLoopFixer(&ParentFinder, &getReplacements(), &GeneratedDecls,
- &ReplacedVars, &AcceptedChanges, &DeferredChanges,
- &RejectedChanges, Options().MaxRiskLevel, LFK_Array,
+ LoopFixer ArrayLoopFixer(&ParentFinder, &GeneratedDecls, &ReplacedVars,
+ &AcceptedChanges, &DeferredChanges, &RejectedChanges,
+ Options().MaxRiskLevel, LFK_Array,
/*Owner=*/ *this);
Finder.addMatcher(makeArrayLoopMatcher(), &ArrayLoopFixer);
- LoopFixer IteratorLoopFixer(
- &ParentFinder, &getReplacements(), &GeneratedDecls, &ReplacedVars,
- &AcceptedChanges, &DeferredChanges, &RejectedChanges,
- Options().MaxRiskLevel, LFK_Iterator, /*Owner=*/ *this);
+ LoopFixer IteratorLoopFixer(&ParentFinder, &GeneratedDecls, &ReplacedVars,
+ &AcceptedChanges, &DeferredChanges,
+ &RejectedChanges, Options().MaxRiskLevel,
+ LFK_Iterator, /*Owner=*/ *this);
Finder.addMatcher(makeIteratorLoopMatcher(), &IteratorLoopFixer);
- LoopFixer PseudoarrrayLoopFixer(
- &ParentFinder, &getReplacements(), &GeneratedDecls, &ReplacedVars,
- &AcceptedChanges, &DeferredChanges, &RejectedChanges,
- Options().MaxRiskLevel, LFK_PseudoArray, /*Owner=*/ *this);
+ LoopFixer PseudoarrrayLoopFixer(&ParentFinder, &GeneratedDecls, &ReplacedVars,
+ &AcceptedChanges, &DeferredChanges,
+ &RejectedChanges, Options().MaxRiskLevel,
+ LFK_PseudoArray, /*Owner=*/ *this);
Finder.addMatcher(makePseudoArrayLoopMatcher(), &PseudoarrrayLoopFixer);
setOverrides(InputStates);
diff --git a/clang-tools-extra/cpp11-migrate/LoopConvert/LoopConvert.h b/clang-tools-extra/cpp11-migrate/LoopConvert/LoopConvert.h
index af287652485..b45d9555b3d 100644
--- a/clang-tools-extra/cpp11-migrate/LoopConvert/LoopConvert.h
+++ b/clang-tools-extra/cpp11-migrate/LoopConvert/LoopConvert.h
@@ -28,7 +28,7 @@ public:
: Transform("LoopConvert", Options) {}
/// \see Transform::run().
- virtual int apply(FileOverrides &InputStates,
+ virtual int apply(const FileOverrides &InputStates,
const clang::tooling::CompilationDatabase &Database,
const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE;
};
diff --git a/clang-tools-extra/cpp11-migrate/PassByValue/PassByValue.cpp b/clang-tools-extra/cpp11-migrate/PassByValue/PassByValue.cpp
index 968fb5c8fff..fbd641233af 100644
--- a/clang-tools-extra/cpp11-migrate/PassByValue/PassByValue.cpp
+++ b/clang-tools-extra/cpp11-migrate/PassByValue/PassByValue.cpp
@@ -21,15 +21,14 @@ using namespace clang;
using namespace clang::tooling;
using namespace clang::ast_matchers;
-int PassByValueTransform::apply(
- FileOverrides &InputStates, const tooling::CompilationDatabase &Database,
- const std::vector<std::string> &SourcePaths) {
+int PassByValueTransform::apply(const FileOverrides &InputStates,
+ const tooling::CompilationDatabase &Database,
+ const std::vector<std::string> &SourcePaths) {
ClangTool Tool(Database, SourcePaths);
unsigned AcceptedChanges = 0;
unsigned RejectedChanges = 0;
MatchFinder Finder;
- ConstructorParamReplacer Replacer(getReplacements(), AcceptedChanges,
- RejectedChanges,
+ ConstructorParamReplacer Replacer(AcceptedChanges, RejectedChanges,
/*Owner=*/ *this);
Finder.addMatcher(makePassByValueCtorParamMatcher(), &Replacer);
diff --git a/clang-tools-extra/cpp11-migrate/PassByValue/PassByValue.h b/clang-tools-extra/cpp11-migrate/PassByValue/PassByValue.h
index 00949526254..6dad5497c99 100644
--- a/clang-tools-extra/cpp11-migrate/PassByValue/PassByValue.h
+++ b/clang-tools-extra/cpp11-migrate/PassByValue/PassByValue.h
@@ -58,7 +58,7 @@ public:
: Transform("PassByValue", Options), Replacer(0) {}
/// \see Transform::apply().
- virtual int apply(FileOverrides &InputStates,
+ virtual int apply(const FileOverrides &InputStates,
const clang::tooling::CompilationDatabase &Database,
const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE;
diff --git a/clang-tools-extra/cpp11-migrate/PassByValue/PassByValueActions.cpp b/clang-tools-extra/cpp11-migrate/PassByValue/PassByValueActions.cpp
index 612850a70db..63189219294 100644
--- a/clang-tools-extra/cpp11-migrate/PassByValue/PassByValueActions.cpp
+++ b/clang-tools-extra/cpp11-migrate/PassByValue/PassByValueActions.cpp
@@ -151,17 +151,21 @@ void ConstructorParamReplacer::run(const MatchFinder::MatchResult &Result) {
const tooling::Replacement &IncludeReplace =
IncludeManager->addAngledInclude(STDMoveFile, "utility");
if (IncludeReplace.isApplicable()) {
- Replaces.insert(IncludeReplace);
+ Owner.addReplacementForCurrentTU(IncludeReplace);
AcceptedChanges++;
}
// const-ref params becomes values (const Foo & -> Foo)
- Replaces.insert(ParamReplaces.begin(), ParamReplaces.end());
+ for (const Replacement *I = ParamReplaces.begin(), *E = ParamReplaces.end();
+ I != E; ++I) {
+ Owner.addReplacementForCurrentTU(*I);
+ }
AcceptedChanges += ParamReplaces.size();
// move the value in the init-list
- Replaces.insert(Replacement(
+ Owner.addReplacementForCurrentTU(Replacement(
SM, Initializer->getLParenLoc().getLocWithOffset(1), 0, "std::move("));
- Replaces.insert(Replacement(SM, Initializer->getRParenLoc(), 0, ")"));
+ Owner.addReplacementForCurrentTU(
+ Replacement(SM, Initializer->getRParenLoc(), 0, ")"));
AcceptedChanges += 2;
}
diff --git a/clang-tools-extra/cpp11-migrate/PassByValue/PassByValueActions.h b/clang-tools-extra/cpp11-migrate/PassByValue/PassByValueActions.h
index 5564fc54caf..5aeaae4f9fb 100644
--- a/clang-tools-extra/cpp11-migrate/PassByValue/PassByValueActions.h
+++ b/clang-tools-extra/cpp11-migrate/PassByValue/PassByValueActions.h
@@ -51,11 +51,10 @@ class IncludeDirectives;
class ConstructorParamReplacer
: public clang::ast_matchers::MatchFinder::MatchCallback {
public:
- ConstructorParamReplacer(clang::tooling::Replacements &Replaces,
- unsigned &AcceptedChanges, unsigned &RejectedChanges,
- const Transform &Owner)
- : Replaces(Replaces), AcceptedChanges(AcceptedChanges),
- RejectedChanges(RejectedChanges), Owner(Owner), IncludeManager(0) {}
+ ConstructorParamReplacer(unsigned &AcceptedChanges, unsigned &RejectedChanges,
+ Transform &Owner)
+ : AcceptedChanges(AcceptedChanges), RejectedChanges(RejectedChanges),
+ Owner(Owner), IncludeManager(0) {}
void setIncludeDirectives(IncludeDirectives *Includes) {
IncludeManager = Includes;
@@ -66,10 +65,9 @@ private:
virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result)
LLVM_OVERRIDE;
- clang::tooling::Replacements &Replaces;
unsigned &AcceptedChanges;
unsigned &RejectedChanges;
- const Transform &Owner;
+ Transform &Owner;
IncludeDirectives *IncludeManager;
};
diff --git a/clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.cpp b/clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.cpp
index 47dce8e7c89..fae7970b416 100644
--- a/clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.cpp
+++ b/clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.cpp
@@ -22,16 +22,14 @@ using namespace clang::tooling;
using namespace clang::ast_matchers;
int
-ReplaceAutoPtrTransform::apply(FileOverrides &InputStates,
+ReplaceAutoPtrTransform::apply(const FileOverrides &InputStates,
const CompilationDatabase &Database,
const std::vector<std::string> &SourcePaths) {
ClangTool Tool(Database, SourcePaths);
unsigned AcceptedChanges = 0;
MatchFinder Finder;
- AutoPtrReplacer Replacer(getReplacements(), AcceptedChanges,
- /*Owner=*/*this);
- OwnershipTransferFixer Fixer(getReplacements(), AcceptedChanges,
- /*Owner=*/*this);
+ AutoPtrReplacer Replacer(AcceptedChanges, /*Owner=*/ *this);
+ OwnershipTransferFixer Fixer(AcceptedChanges, /*Owner=*/ *this);
Finder.addMatcher(makeAutoPtrTypeLocMatcher(), &Replacer);
Finder.addMatcher(makeAutoPtrUsingDeclMatcher(), &Replacer);
diff --git a/clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.h b/clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.h
index 2bc711480a3..c236c99b6c8 100644
--- a/clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.h
+++ b/clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.h
@@ -47,7 +47,7 @@ public:
: Transform("ReplaceAutoPtr", Options) {}
/// \see Transform::run().
- virtual int apply(FileOverrides &InputStates,
+ virtual int apply(const FileOverrides &InputStates,
const clang::tooling::CompilationDatabase &Database,
const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE;
};
diff --git a/clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.cpp b/clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.cpp
index f538d94d53a..2074e3764bb 100644
--- a/clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.cpp
+++ b/clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.cpp
@@ -66,7 +66,7 @@ void AutoPtrReplacer::run(const MatchFinder::MatchResult &Result) {
if (!checkTokenIsAutoPtr(IdentifierLoc, SM, LangOptions()))
return;
- Replace.insert(
+ Owner.addReplacementForCurrentTU(
Replacement(SM, IdentifierLoc, strlen("auto_ptr"), "unique_ptr"));
++AcceptedChanges;
}
@@ -101,7 +101,8 @@ void OwnershipTransferFixer::run(const MatchFinder::MatchResult &Result) {
if (!Owner.isFileModifiable(SM, Range.getBegin()))
return;
- Replace.insert(Replacement(SM, Range.getBegin(), 0, "std::move("));
- Replace.insert(Replacement(SM, Range.getEnd(), 0, ")"));
+ Owner.addReplacementForCurrentTU(
+ Replacement(SM, Range.getBegin(), 0, "std::move("));
+ Owner.addReplacementForCurrentTU(Replacement(SM, Range.getEnd(), 0, ")"));
AcceptedChanges += 2;
}
diff --git a/clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.h b/clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.h
index 2cf55a09742..fb805965b01 100644
--- a/clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.h
+++ b/clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.h
@@ -25,9 +25,8 @@ class Transform;
/// using declarations.
class AutoPtrReplacer : public clang::ast_matchers::MatchFinder::MatchCallback {
public:
- AutoPtrReplacer(clang::tooling::Replacements &Replace,
- unsigned &AcceptedChanges, const Transform &Owner)
- : Replace(Replace), AcceptedChanges(AcceptedChanges), Owner(Owner) {}
+ AutoPtrReplacer(unsigned &AcceptedChanges, Transform &Owner)
+ : AcceptedChanges(AcceptedChanges), Owner(Owner) {}
/// \brief Entry point to the callback called when matches are made.
virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result)
@@ -63,9 +62,8 @@ private:
const clang::SourceManager &SM);
private:
- clang::tooling::Replacements &Replace;
unsigned &AcceptedChanges;
- const Transform &Owner;
+ Transform &Owner;
};
/// \brief The callback to be used to fix the ownership transfers of
@@ -86,18 +84,16 @@ private:
class OwnershipTransferFixer
: public clang::ast_matchers::MatchFinder::MatchCallback {
public:
- OwnershipTransferFixer(clang::tooling::Replacements &Replace,
- unsigned &AcceptedChanges, const Transform &Owner)
- : Replace(Replace), AcceptedChanges(AcceptedChanges), Owner(Owner) {}
+ OwnershipTransferFixer(unsigned &AcceptedChanges, Transform &Owner)
+ : AcceptedChanges(AcceptedChanges), Owner(Owner) {}
/// \brief Entry point to the callback called when matches are made.
virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result)
LLVM_OVERRIDE;
private:
- clang::tooling::Replacements &Replace;
unsigned &AcceptedChanges;
- const Transform &Owner;
+ Transform &Owner;
};
#endif // CPP11_MIGRATE_REPLACE_AUTO_PTR_ACTIONS_H
diff --git a/clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.cpp b/clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.cpp
index ccf49d88c92..72f5ae077f2 100644
--- a/clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.cpp
+++ b/clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.cpp
@@ -20,7 +20,7 @@ using clang::ast_matchers::MatchFinder;
using namespace clang;
using namespace clang::tooling;
-int UseAutoTransform::apply(FileOverrides &InputStates,
+int UseAutoTransform::apply(const FileOverrides &InputStates,
const clang::tooling::CompilationDatabase &Database,
const std::vector<std::string> &SourcePaths) {
ClangTool UseAutoTool(Database, SourcePaths);
@@ -28,10 +28,11 @@ int UseAutoTransform::apply(FileOverrides &InputStates,
unsigned AcceptedChanges = 0;
MatchFinder Finder;
- IteratorReplacer ReplaceIterators(getReplacements(), AcceptedChanges,
- Options().MaxRiskLevel, /*Owner=*/ *this);
- NewReplacer ReplaceNew(getReplacements(), AcceptedChanges,
- Options().MaxRiskLevel, /*Owner=*/ *this);
+ ReplacementsVec Replaces;
+ IteratorReplacer ReplaceIterators(AcceptedChanges, Options().MaxRiskLevel,
+ /*Owner=*/ *this);
+ NewReplacer ReplaceNew(AcceptedChanges, Options().MaxRiskLevel,
+ /*Owner=*/ *this);
Finder.addMatcher(makeIteratorDeclMatcher(), &ReplaceIterators);
Finder.addMatcher(makeDeclWithNewMatcher(), &ReplaceNew);
diff --git a/clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.h b/clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.h
index 71b8dd7dc95..26b5e4496f6 100644
--- a/clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.h
+++ b/clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.h
@@ -34,7 +34,7 @@ public:
: Transform("UseAuto", Options) {}
/// \see Transform::run().
- virtual int apply(FileOverrides &InputStates,
+ virtual int apply(const FileOverrides &InputStates,
const clang::tooling::CompilationDatabase &Database,
const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE;
};
diff --git a/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.cpp b/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.cpp
index 643de63069e..2a8d5c5935d 100644
--- a/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.cpp
+++ b/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.cpp
@@ -73,7 +73,7 @@ void IteratorReplacer::run(const MatchFinder::MatchResult &Result) {
// iterators but something to keep in mind in the future.
CharSourceRange Range(TL.getSourceRange(), true);
- Replace.insert(tooling::Replacement(SM, Range, "auto"));
+ Owner.addReplacementForCurrentTU(tooling::Replacement(SM, Range, "auto"));
++AcceptedChanges;
}
@@ -131,8 +131,9 @@ void NewReplacer::run(const MatchFinder::MatchResult &Result) {
for (std::vector<SourceLocation>::iterator I = StarLocations.begin(),
E = StarLocations.end();
I != E; ++I) {
- Replace.insert(tooling::Replacement(SM, *I, 1, ""));
+ Owner.addReplacementForCurrentTU(tooling::Replacement(SM, *I, 1, ""));
}
+
// FIXME: There is, however, one case we can address: when the VarDecl
// pointee is the same as the initializer, just more CV-qualified. However,
// TypeLoc information is not reliable where CV qualifiers are concerned so
@@ -141,6 +142,6 @@ void NewReplacer::run(const MatchFinder::MatchResult &Result) {
FirstDecl->getTypeSourceInfo()->getTypeLoc().getSourceRange(), true);
// Space after 'auto' to handle cases where the '*' in the pointer type
// is next to the identifier. This avoids changing 'int *p' into 'autop'.
- Replace.insert(tooling::Replacement(SM, Range, "auto "));
+ Owner.addReplacementForCurrentTU(tooling::Replacement(SM, Range, "auto "));
++AcceptedChanges;
}
diff --git a/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.h b/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.h
index 403621803c3..0ddb0e0c5af 100644
--- a/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.h
+++ b/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.h
@@ -25,36 +25,32 @@
class IteratorReplacer
: public clang::ast_matchers::MatchFinder::MatchCallback {
public:
- IteratorReplacer(clang::tooling::Replacements &Replace,
- unsigned &AcceptedChanges, RiskLevel, const Transform &Owner)
- : Replace(Replace), AcceptedChanges(AcceptedChanges), Owner(Owner) {}
+ IteratorReplacer(unsigned &AcceptedChanges, RiskLevel, Transform &Owner)
+ : AcceptedChanges(AcceptedChanges), Owner(Owner) {}
/// \brief Entry point to the callback called when matches are made.
virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result)
LLVM_OVERRIDE;
private:
- clang::tooling::Replacements &Replace;
unsigned &AcceptedChanges;
- const Transform &Owner;
+ Transform &Owner;
};
/// \brief The callback used when replacing type specifiers of variable
/// declarations initialized by a C++ new expression.
class NewReplacer : public clang::ast_matchers::MatchFinder::MatchCallback {
public:
- NewReplacer(clang::tooling::Replacements &Replace, unsigned &AcceptedChanges,
- RiskLevel, const Transform &Owner)
- : Replace(Replace), AcceptedChanges(AcceptedChanges), Owner(Owner) {}
+ NewReplacer(unsigned &AcceptedChanges, RiskLevel, Transform &Owner)
+ : AcceptedChanges(AcceptedChanges), Owner(Owner) {}
/// \brief Entry point to the callback called when matches are made.
virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result)
LLVM_OVERRIDE;
private:
- clang::tooling::Replacements &Replace;
unsigned &AcceptedChanges;
- const Transform &Owner;
+ Transform &Owner;
};
#endif // CPP11_MIGRATE_USE_AUTO_ACTIONS_H
diff --git a/clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.cpp b/clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.cpp
index e170801a034..23a8fd3a476 100644
--- a/clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.cpp
+++ b/clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.cpp
@@ -47,7 +47,7 @@ bool isReplaceableRange(SourceLocation StartLoc, SourceLocation EndLoc,
/// \brief Replaces the provided range with the text "nullptr", but only if
/// the start and end location are both in main file.
/// Returns true if and only if a replacement was made.
-void ReplaceWithNullptr(tooling::Replacements &Replace, SourceManager &SM,
+void ReplaceWithNullptr(Transform &Owner, SourceManager &SM,
SourceLocation StartLoc, SourceLocation EndLoc) {
CharSourceRange Range(SourceRange(StartLoc, EndLoc), true);
// Add a space if nullptr follows an alphanumeric character. This happens
@@ -55,9 +55,11 @@ void ReplaceWithNullptr(tooling::Replacements &Replace, SourceManager &SM,
// parentheses and right beside a return statement.
SourceLocation PreviousLocation = StartLoc.getLocWithOffset(-1);
if (isAlphanumeric(*FullSourceLoc(PreviousLocation, SM).getCharacterData()))
- Replace.insert(tooling::Replacement(SM, Range, " nullptr"));
+ Owner.addReplacementForCurrentTU(
+ tooling::Replacement(SM, Range, " nullptr"));
else
- Replace.insert(tooling::Replacement(SM, Range, "nullptr"));
+ Owner.addReplacementForCurrentTU(
+ tooling::Replacement(SM, Range, "nullptr"));
}
/// \brief Returns the name of the outermost macro.
@@ -153,10 +155,9 @@ private:
/// ambiguities.
class CastSequenceVisitor : public RecursiveASTVisitor<CastSequenceVisitor> {
public:
- CastSequenceVisitor(tooling::Replacements &R, ASTContext &Context,
- const UserMacroNames &UserNullMacros,
- unsigned &AcceptedChanges, const Transform &Owner)
- : Replace(R), SM(Context.getSourceManager()), Context(Context),
+ CastSequenceVisitor(ASTContext &Context, const UserMacroNames &UserNullMacros,
+ unsigned &AcceptedChanges, Transform &Owner)
+ : SM(Context.getSourceManager()), Context(Context),
UserNullMacros(UserNullMacros), AcceptedChanges(AcceptedChanges),
Owner(Owner), FirstSubExpr(0), PruneSubtree(false) {}
@@ -196,7 +197,7 @@ public:
FileLocEnd = SM.getFileLoc(EndLoc);
if (isReplaceableRange(FileLocStart, FileLocEnd, SM, Owner) &&
allArgUsesValid(C)) {
- ReplaceWithNullptr(Replace, SM, FileLocStart, FileLocEnd);
+ ReplaceWithNullptr(Owner, SM, FileLocStart, FileLocEnd);
++AcceptedChanges;
}
return skipSubTree();
@@ -220,7 +221,7 @@ public:
if (!isReplaceableRange(StartLoc, EndLoc, SM, Owner)) {
return skipSubTree();
}
- ReplaceWithNullptr(Replace, SM, StartLoc, EndLoc);
+ ReplaceWithNullptr(Owner, SM, StartLoc, EndLoc);
++AcceptedChanges;
return skipSubTree();
@@ -417,21 +418,19 @@ private:
}
private:
- tooling::Replacements &Replace;
SourceManager &SM;
ASTContext &Context;
const UserMacroNames &UserNullMacros;
unsigned &AcceptedChanges;
- const Transform &Owner;
+ Transform &Owner;
Expr *FirstSubExpr;
bool PruneSubtree;
};
} // namespace
-NullptrFixer::NullptrFixer(clang::tooling::Replacements &Replace,
- unsigned &AcceptedChanges, RiskLevel,
- const Transform &Owner)
- : Replace(Replace), AcceptedChanges(AcceptedChanges), Owner(Owner) {
+NullptrFixer::NullptrFixer(unsigned &AcceptedChanges, RiskLevel,
+ Transform &Owner)
+ : AcceptedChanges(AcceptedChanges), Owner(Owner) {
if (!UserNullMacroNames.empty()) {
llvm::StringRef S = UserNullMacroNames;
S.split(UserNullMacros, ",");
@@ -445,7 +444,7 @@ void NullptrFixer::run(const ast_matchers::MatchFinder::MatchResult &Result) {
// Given an implicit null-ptr cast or an explicit cast with an implicit
// null-to-pointer cast within use CastSequenceVisitor to identify sequences
// of explicit casts that can be converted into 'nullptr'.
- CastSequenceVisitor Visitor(Replace, *Result.Context, UserNullMacros,
- AcceptedChanges, Owner);
+ CastSequenceVisitor Visitor(*Result.Context, UserNullMacros, AcceptedChanges,
+ Owner);
Visitor.TraverseStmt(const_cast<CastExpr *>(NullCast));
}
diff --git a/clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.h b/clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.h
index f647d8e4d65..02da6b76db0 100644
--- a/clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.h
+++ b/clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.h
@@ -27,17 +27,15 @@ typedef llvm::SmallVector<llvm::StringRef, 1> UserMacroNames;
///
class NullptrFixer : public clang::ast_matchers::MatchFinder::MatchCallback {
public:
- NullptrFixer(clang::tooling::Replacements &Replace, unsigned &AcceptedChanges,
- RiskLevel, const Transform &Owner);
+ NullptrFixer(unsigned &AcceptedChanges, RiskLevel, Transform &Owner);
/// \brief Entry point to the callback called when matches are made.
virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result);
private:
- clang::tooling::Replacements &Replace;
unsigned &AcceptedChanges;
UserMacroNames UserNullMacros;
- const Transform &Owner;
+ Transform &Owner;
};
#endif // CPP11_MIGRATE_NULLPTR_ACTIONS_H
diff --git a/clang-tools-extra/cpp11-migrate/UseNullptr/UseNullptr.cpp b/clang-tools-extra/cpp11-migrate/UseNullptr/UseNullptr.cpp
index afeec4a10af..e07ee6682ee 100644
--- a/clang-tools-extra/cpp11-migrate/UseNullptr/UseNullptr.cpp
+++ b/clang-tools-extra/cpp11-migrate/UseNullptr/UseNullptr.cpp
@@ -24,7 +24,7 @@ using clang::ast_matchers::MatchFinder;
using namespace clang::tooling;
using namespace clang;
-int UseNullptrTransform::apply(FileOverrides &InputStates,
+int UseNullptrTransform::apply(const FileOverrides &InputStates,
const CompilationDatabase &Database,
const std::vector<std::string> &SourcePaths) {
ClangTool UseNullptrTool(Database, SourcePaths);
@@ -32,8 +32,7 @@ int UseNullptrTransform::apply(FileOverrides &InputStates,
unsigned AcceptedChanges = 0;
MatchFinder Finder;
- NullptrFixer Fixer(getReplacements(), AcceptedChanges, Options().MaxRiskLevel,
- /*Owner=*/ *this);
+ NullptrFixer Fixer(AcceptedChanges, Options().MaxRiskLevel, /*Owner=*/ *this);
Finder.addMatcher(makeCastSequenceMatcher(), &Fixer);
diff --git a/clang-tools-extra/cpp11-migrate/UseNullptr/UseNullptr.h b/clang-tools-extra/cpp11-migrate/UseNullptr/UseNullptr.h
index 873ffab0702..ed90f9a5bbc 100644
--- a/clang-tools-extra/cpp11-migrate/UseNullptr/UseNullptr.h
+++ b/clang-tools-extra/cpp11-migrate/UseNullptr/UseNullptr.h
@@ -28,7 +28,7 @@ public:
: Transform("UseNullptr", Options) {}
/// \see Transform::run().
- virtual int apply(FileOverrides &InputStates,
+ virtual int apply(const FileOverrides &InputStates,
const clang::tooling::CompilationDatabase &Database,
const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE;
};
diff --git a/clang-tools-extra/cpp11-migrate/tool/CMakeLists.txt b/clang-tools-extra/cpp11-migrate/tool/CMakeLists.txt
index a40e0f3e31a..8721b5e5c25 100644
--- a/clang-tools-extra/cpp11-migrate/tool/CMakeLists.txt
+++ b/clang-tools-extra/cpp11-migrate/tool/CMakeLists.txt
@@ -34,6 +34,7 @@ add_dependencies(cpp11-migrate
)
target_link_libraries(cpp11-migrate
+ clangReplace
migrateCore
)
diff --git a/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp b/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp
index eaaec3c91de..e75a4754881 100644
--- a/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp
+++ b/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp
@@ -21,9 +21,14 @@
#include "Core/Transform.h"
#include "Core/Transforms.h"
#include "Core/Reformatting.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/FrontendActions.h"
+#include "clang/Rewrite/Core/Rewriter.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
+#include "clang-replace/Tooling/ApplyReplacements.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -122,12 +127,12 @@ static cl::opt<bool, /*ExternalStorage=*/true> EnableHeaderModifications(
cl::location(GlobalOptions.EnableHeaderModifications),
cl::init(false));
-static cl::opt<bool> YAMLOnly("yaml-only",
- cl::Hidden, // Associated with -headers
- cl::desc("Don't change headers on disk. Write "
- "changes to change description files "
- "only."),
- cl::init(false));
+static cl::opt<bool>
+SerializeReplacements("serialize-replacements",
+ cl::Hidden, // Associated with -headers
+ cl::desc("Serialize translation unit replacements to "
+ "disk instead of changing files."),
+ cl::init(false));
cl::opt<std::string> SupportedCompilers(
"for-compilers", cl::value_desc("string"),
@@ -225,6 +230,68 @@ static Reformatter *handleFormatStyle(const char *ProgName, bool &Error) {
return 0;
}
+/// \brief Use \c ChangesReformatter to reformat all changed regions of all
+/// files stored in \c Overrides and write the result to disk.
+///
+/// \returns \li true if reformatting replacements were successfully applied
+/// without conflicts and all files were successfully written to
+/// disk.
+/// \li false if reformatting could not be successfully applied or
+/// if at least one file failed to write to disk.
+bool reformat(Reformatter &ChangesReformatter, const FileOverrides &Overrides,
+ DiagnosticsEngine &Diagnostics) {
+ FileManager Files((FileSystemOptions()));
+ SourceManager SM(Diagnostics, Files);
+
+ replace::TUReplacements AllReplacements(1);
+ ChangesReformatter.reformatChanges(Overrides, SM,
+ AllReplacements.front().Replacements);
+
+ replace::FileToReplacementsMap GroupedReplacements;
+ if (!replace::mergeAndDeduplicate(AllReplacements, GroupedReplacements, SM)) {
+ llvm::errs() << "Warning: Reformatting produced conflicts.\n";
+ return false;
+ }
+
+ Rewriter DestRewriter(SM, LangOptions());
+ if (!replace::applyReplacements(GroupedReplacements, DestRewriter)) {
+ llvm::errs() << "Warning: Failed to apply reformatting conflicts!\n";
+ return false;
+ }
+
+ return replace::writeFiles(DestRewriter);
+}
+
+bool serializeReplacements(const replace::TUReplacements &Replacements) {
+ bool Errors = false;
+ for (replace::TUReplacements::const_iterator I = Replacements.begin(),
+ E = Replacements.end();
+ I != E; ++I) {
+ llvm::SmallString<128> ReplacementsFileName;
+ llvm::SmallString<64> Error;
+ bool Result = generateReplacementsFileName(I->MainSourceFile,
+ ReplacementsFileName, Error);
+ if (!Result) {
+ llvm::errs() << "Failed to generate replacements filename:" << Error
+ << "\n";
+ Errors = true;
+ continue;
+ }
+
+ std::string ErrorInfo;
+ llvm::raw_fd_ostream ReplacementsFile(ReplacementsFileName.c_str(),
+ ErrorInfo, llvm::sys::fs::F_Binary);
+ if (!ErrorInfo.empty()) {
+ llvm::errs() << "Error opening file: " << ErrorInfo << "\n";
+ Errors = true;
+ continue;
+ }
+ llvm::yaml::Output YAML(ReplacementsFile);
+ YAML << const_cast<TranslationUnitReplacements &>(*I);
+ }
+ return !Errors;
+}
+
int main(int argc, const char **argv) {
llvm::sys::PrintStackTraceOnErrorSignal();
Transforms TransformManager;
@@ -280,6 +347,15 @@ int main(int argc, const char **argv) {
TransformManager.createSelectedTransforms(GlobalOptions, RequiredVersions);
+ llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts(
+ new DiagnosticOptions());
+ DiagnosticsEngine Diagnostics(
+ llvm::IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
+ DiagOpts.getPtr());
+
+ // FIXME: Make this DiagnosticsEngine available to all Transforms probably via
+ // GlobalOptions.
+
if (TransformManager.begin() == TransformManager.end()) {
if (SupportedCompilers.empty())
llvm::errs() << argv[0] << ": no selected transforms\n";
@@ -289,21 +365,22 @@ int main(int argc, const char **argv) {
return 1;
}
- if (std::distance(TransformManager.begin(), TransformManager.end()) > 1 &&
- YAMLOnly) {
- llvm::errs() << "Header change description files requested for multiple "
+ // If SerializeReplacements is requested, then change reformatting must be
+ // turned off and only one transform should be requested. Reformatting is
+ // basically another transform so even if there's only one other transform,
+ // the reformatting pass would make two.
+ if (SerializeReplacements &&
+ (std::distance(TransformManager.begin(), TransformManager.end()) > 1 ||
+ ChangesReformatter)) {
+ llvm::errs() << "Serialization of replacements requested for multiple "
"transforms.\nChanges from only one transform can be "
- "recorded in a change description file.\n";
+ "serialized.\n";
return 1;
}
- // if reformatting is enabled we wants to track file changes so that it's
- // possible to reformat them.
- bool TrackReplacements = static_cast<bool>(ChangesReformatter);
- FileOverrides FileStates(TrackReplacements);
SourcePerfData PerfData;
+ FileOverrides FileStates;
- // Apply transforms.
for (Transforms::const_iterator I = TransformManager.begin(),
E = TransformManager.end();
I != E; ++I) {
@@ -326,79 +403,67 @@ int main(int argc, const char **argv) {
}
llvm::outs() << "\n";
}
- }
- // Reformat changes if a reformatter is provided.
- if (ChangesReformatter)
- for (FileOverrides::const_iterator I = FileStates.begin(),
- E = FileStates.end();
- I != E; ++I) {
- SourceOverrides &Overrides = *I->second;
- ChangesReformatter->reformatChanges(Overrides);
+ // Collect all TranslationUnitReplacements generated from the translation
+ // units the transform worked on and store them in AllReplacements.
+ replace::TUReplacements AllReplacements;
+ const TUReplacementsMap &ReplacementsMap = T->getAllReplacements();
+ const TranslationUnitReplacements &(
+ TUReplacementsMap::value_type::*getValue)() const =
+ &TUReplacementsMap::value_type::getValue;
+ std::transform(ReplacementsMap.begin(), ReplacementsMap.end(),
+ std::back_inserter(AllReplacements),
+ std::mem_fun_ref(getValue));
+
+ if (SerializeReplacements)
+ serializeReplacements(AllReplacements);
+
+ FileManager Files((FileSystemOptions()));
+ SourceManager SM(Diagnostics, Files);
+
+ // Make sure SourceManager is updated to have the same initial state as the
+ // transforms.
+ FileStates.applyOverrides(SM);
+
+ replace::FileToReplacementsMap GroupedReplacements;
+ if (!replace::mergeAndDeduplicate(AllReplacements, GroupedReplacements,
+ SM)) {
+ llvm::outs() << "Transform " << T->getName()
+ << " resulted in conflicts. Discarding all "
+ << "replacements.\n";
+ continue;
}
- if (FinalSyntaxCheck)
- if (!doSyntaxCheck(*Compilations, SourcePaths, FileStates))
- return 1;
-
- // Write results to file.
- for (FileOverrides::const_iterator I = FileStates.begin(),
- E = FileStates.end();
- I != E; ++I) {
- const SourceOverrides &Overrides = *I->second;
- if (Overrides.isSourceOverriden()) {
- std::string ErrorInfo;
- std::string MainFileName = I->getKey();
- llvm::raw_fd_ostream FileStream(MainFileName.c_str(), ErrorInfo,
- llvm::sys::fs::F_Binary);
- FileStream << Overrides.getMainFileContent();
+ // Apply replacements and update FileStates with new state.
+ Rewriter DestRewriter(SM, LangOptions());
+ if (!replace::applyReplacements(GroupedReplacements, DestRewriter)) {
+ llvm::outs() << "Some replacements failed to apply. Discarding "
+ "all replacements.\n";
+ continue;
}
- for (HeaderOverrides::const_iterator HeaderI = Overrides.headers_begin(),
- HeaderE = Overrides.headers_end();
- HeaderI != HeaderE; ++HeaderI) {
- std::string ErrorInfo;
- if (YAMLOnly) {
- // 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(), HeaderI->getKey().data(),
- 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<TranslationUnitReplacements &>(
- HeaderI->getValue().getReplacements());
- } else {
- // If -yaml-only was not specified, then change headers on disk.
- // FIXME: This is transitional behaviour. Remove this functionality
- // when header change description tool is ready.
- assert(!HeaderI->second.getContentOverride().empty() &&
- "A header override should not be empty");
- std::string HeaderFileName = HeaderI->getKey();
- llvm::raw_fd_ostream HeaderStream(HeaderFileName.c_str(), ErrorInfo,
- llvm::sys::fs::F_Binary);
- if (!ErrorInfo.empty()) {
- llvm::errs() << "Error opening file: " << ErrorInfo << "\n";
- continue;
- }
- HeaderStream << HeaderI->second.getContentOverride();
- }
- }
+ // Update contents of files in memory to serve as initial state for next
+ // transform.
+ FileStates.updateState(DestRewriter);
+
+ // Update changed ranges for reformatting
+ if (ChangesReformatter)
+ FileStates.adjustChangedRanges(GroupedReplacements);
}
+ // Skip writing final file states to disk if we were asked to serialize
+ // replacements. Otherwise reformat changes if reformatting is enabled. If
+ // not enabled or if reformatting fails write un-formated changes to disk
+ // instead. reformat() takes care of writing successfully formatted changes.
+ if (!SerializeReplacements &&
+ (!ChangesReformatter ||
+ !reformat(*ChangesReformatter, FileStates, Diagnostics)))
+ FileStates.writeToDisk(Diagnostics);
+
+ if (FinalSyntaxCheck)
+ if (!doSyntaxCheck(*Compilations, SourcePaths, FileStates))
+ return 1;
+
// Report execution times.
if (GlobalOptions.EnableTiming && !PerfData.empty()) {
std::string DirectoryName = TimingDirectoryName;
diff --git a/clang-tools-extra/cpp11-migrate/tool/Makefile b/clang-tools-extra/cpp11-migrate/tool/Makefile
index f1780265aa9..82abe8ab569 100644
--- a/clang-tools-extra/cpp11-migrate/tool/Makefile
+++ b/clang-tools-extra/cpp11-migrate/tool/Makefile
@@ -36,14 +36,14 @@ SOURCES += $(addprefix ../ReplaceAutoPtr/,$(notdir $(wildcard $(PROJ_SRC_DIR)/..
BUILT_SOURCES += $(ObjDir)/../ReplaceAutoPtr/.objdir
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc mcparser option
-USEDLIBS = migrateCore.a clangFormat.a clangTooling.a clangFrontend.a \
+USEDLIBS = migrateCore.a clangFormat.a clangReplace.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
-CPP.Flags += -I$(PROJ_SRC_DIR)/..
+CPP.Flags += -I$(PROJ_SRC_DIR)/.. -I$(PROJ_SRC_DIR)/../../clang-replace/include
# BUILT_SOURCES gets used as a prereq for many top-level targets. However, at
# the point those targets are defined, $(ObjDir) hasn't been defined and so the
OpenPOWER on IntegriCloud