Hi arielbernal, tareqsiraj,
To make it possible for replacements made to headers as part of
transforming one translation unit to not be visible to the transform of
other translation units, Transform now handles replacement application
as part of its end-of-source handling. Several things were simplified as
a result:
- The duplicated code in every transform for applying replacements is
now gone and replaced with on location in Transform.
- RefactoringTool is no longer used since Transform houses the Replacements
structure.
- RewriterContainer is now a private implementation detail of Transform (also
renamed to RewriterManager since its behaviour is slightly different now with
respect to lifetime of objects).
- There's now no distinction between input and output file state.
Misc notes:
- Interface changes reflected in unit tests.
- Replacements for files other than the main file are assumed to be for headers
and stored as such.
http://llvm-reviews.chandlerc.com/D993
Files:
cpp11-migrate/AddOverride/AddOverride.cpp
cpp11-migrate/AddOverride/AddOverride.h
cpp11-migrate/Core/FileOverrides.cpp
cpp11-migrate/Core/FileOverrides.h
cpp11-migrate/Core/SyntaxCheck.cpp
cpp11-migrate/Core/Transform.cpp
cpp11-migrate/Core/Transform.h
cpp11-migrate/LoopConvert/LoopConvert.cpp
cpp11-migrate/LoopConvert/LoopConvert.h
cpp11-migrate/UseAuto/UseAuto.cpp
cpp11-migrate/UseAuto/UseAuto.h
cpp11-migrate/UseNullptr/UseNullptr.cpp
cpp11-migrate/UseNullptr/UseNullptr.h
cpp11-migrate/tool/Cpp11Migrate.cpp
unittests/cpp11-migrate/PerfSupportTest.cpp
unittests/cpp11-migrate/TransformTest.cpp
Index: cpp11-migrate/AddOverride/AddOverride.cpp
===================================================================
--- cpp11-migrate/AddOverride/AddOverride.cpp
+++ cpp11-migrate/AddOverride/AddOverride.cpp
@@ -32,17 +32,15 @@
llvm::cl::desc(
"Detect and use macros that expand to the 'override' keyword."));
-int AddOverrideTransform::apply(const FileOverrides &InputStates,
+int AddOverrideTransform::apply(FileOverrides &InputStates,
const CompilationDatabase &Database,
- const std::vector<std::string> &SourcePaths,
- FileOverrides &ResultStates) {
- RefactoringTool AddOverrideTool(Database, SourcePaths);
+ const std::vector<std::string> &SourcePaths) {
+ ClangTool AddOverrideTool(Database, SourcePaths);
unsigned AcceptedChanges = 0;
MatchFinder Finder;
- AddOverrideFixer Fixer(AddOverrideTool.getReplacements(), AcceptedChanges,
- DetectMacros);
+ AddOverrideFixer Fixer(getReplacements(), AcceptedChanges, DetectMacros);
Finder.addMatcher(makeCandidateForOverrideAttrMatcher(), &Fixer);
// Make Fixer available to handleBeginSource().
@@ -55,13 +53,6 @@
return result;
}
- RewriterContainer Rewrite(AddOverrideTool.getFiles(), InputStates);
-
- // FIXME: Do something if some replacements didn't get applied?
- AddOverrideTool.applyAllReplacements(Rewrite.getRewriter());
-
- collectResults(Rewrite.getRewriter(), InputStates, ResultStates);
-
setAcceptedChanges(AcceptedChanges);
return 0;
Index: cpp11-migrate/AddOverride/AddOverride.h
===================================================================
--- cpp11-migrate/AddOverride/AddOverride.h
+++ cpp11-migrate/AddOverride/AddOverride.h
@@ -30,10 +30,9 @@
: Transform("AddOverride", Options) {}
/// \see Transform::run().
- virtual int apply(const FileOverrides &InputStates,
+ virtual int apply(FileOverrides &InputStates,
const clang::tooling::CompilationDatabase &Database,
- const std::vector<std::string> &SourcePaths,
- FileOverrides &ResultStates) LLVM_OVERRIDE;
+ const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE;
virtual bool handleBeginSource(clang::CompilerInstance &CI,
llvm::StringRef Filename) LLVM_OVERRIDE;
Index: cpp11-migrate/Core/FileOverrides.cpp
===================================================================
--- cpp11-migrate/Core/FileOverrides.cpp
+++ cpp11-migrate/Core/FileOverrides.cpp
@@ -1,16 +1,18 @@
#include "Core/FileOverrides.h"
#include "clang/Basic/SourceManager.h"
-void SourceOverrides::applyOverrides(clang::SourceManager &SM,
- clang::FileManager &FM) const {
- assert(!MainFileOverride.empty() &&
- "Main source file override should exist!");
- SM.overrideFileContents(FM.getFile(MainFileName),
- llvm::MemoryBuffer::getMemBuffer(MainFileOverride));
+void SourceOverrides::applyOverrides(clang::SourceManager &SM) const {
+ clang::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)
+ E = Headers.end(); I != E; ++I) {
+ assert(!I->second.FileOverride.empty() && "Header override should not be empty!");
SM.overrideFileContents(
FM.getFile(I->second.FileName),
llvm::MemoryBuffer::getMemBuffer(I->second.FileOverride));
+ }
}
Index: cpp11-migrate/Core/FileOverrides.h
===================================================================
--- cpp11-migrate/Core/FileOverrides.h
+++ cpp11-migrate/Core/FileOverrides.h
@@ -26,6 +26,8 @@
/// \brief Container for storing override information for a single headers.
struct HeaderOverride {
+ HeaderOverride(const char *FileName) : FileName(FileName) {}
+
std::string FileName;
std::string FileOverride;
};
@@ -35,12 +37,18 @@
/// \brief Container storing the file content overrides for a source file.
struct SourceOverrides {
- SourceOverrides(const char *MainFileName)
+ SourceOverrides(const std::string &MainFileName)
: MainFileName(MainFileName) {}
/// \brief Convenience function for applying this source's overrides to
/// the given SourceManager.
- void applyOverrides(clang::SourceManager &SM, clang::FileManager &FM) const;
+ void applyOverrides(clang::SourceManager &SM) const;
+
+ /// \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(); }
std::string MainFileName;
std::string MainFileOverride;
Index: cpp11-migrate/Core/SyntaxCheck.cpp
===================================================================
--- cpp11-migrate/Core/SyntaxCheck.cpp
+++ cpp11-migrate/Core/SyntaxCheck.cpp
@@ -16,7 +16,7 @@
FileOverrides::const_iterator I = Overrides.find(Filename);
if (I != Overrides.end())
- I->second.applyOverrides(CI.getSourceManager(), CI.getFileManager());
+ I->second.applyOverrides(CI.getSourceManager());
return true;
}
Index: cpp11-migrate/Core/Transform.cpp
===================================================================
--- cpp11-migrate/Core/Transform.cpp
+++ cpp11-migrate/Core/Transform.cpp
@@ -1,6 +1,10 @@
#include "Core/Transform.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/raw_ostream.h"
@@ -54,43 +58,63 @@
MatchFinder &Finder;
Transform &Owner;
};
-
} // namespace
-RewriterContainer::RewriterContainer(clang::FileManager &Files,
- const FileOverrides &InputStates)
- : DiagOpts(new clang::DiagnosticOptions()),
- DiagnosticPrinter(llvm::errs(), DiagOpts.getPtr()),
- Diagnostics(llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs>(
- new clang::DiagnosticIDs()),
- DiagOpts.getPtr(), &DiagnosticPrinter, false),
- Sources(Diagnostics, Files), Rewrite(Sources, DefaultLangOptions) {
- for (FileOverrides::const_iterator I = InputStates.begin(),
- E = InputStates.end();
- I != E; ++I)
- I->second.applyOverrides(Sources, Files);
-}
+/// \brief Class for creating Rewriter objects and housing Rewriter
+/// dependencies.
+///
+/// A Rewriter depends on a SourceManager which in turn depends on a
+/// FileManager and a DiagnosticsEngine. Transform uses this class to create a
+/// new Rewriter and SourceManager for every translation unit it transforms. A
+/// DiagnosticsEngine doesn't need to be re-created so it's constructed once. A
+/// SourceManager and Rewriter and (re)created as required.
+///
+/// FIXME: The DiagnosticsEngine should really come from somewhere more global.
+/// It shouldn't be re-created once for every transform.
+///
+/// NOTE: SourceManagers cannot be shared. Therefore the one used to parse the
+/// translation unit cannot be used to create a Rewriter. This is why both a
+/// SourceManager and Rewriter need to be created for each translation unit.
+class RewriterManager {
+public:
+ RewriterManager()
+ : DiagOpts(new DiagnosticOptions()),
+ DiagnosticPrinter(llvm::errs(), DiagOpts.getPtr()),
+ Diagnostics(
+ llvm::IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
+ DiagOpts.getPtr(), &DiagnosticPrinter, false) {}
+
+ void prepare(FileManager &Files) {
+ Sources.reset(new SourceManager(Diagnostics, Files));
+ Rewrite.reset(new Rewriter(*Sources, DefaultLangOptions));
+ }
-void collectResults(clang::Rewriter &Rewrite,
- const FileOverrides &InputStates,
- FileOverrides &Results) {
- // Copy the contents of InputStates to be modified.
- Results = InputStates;
+ void applyOverrides(const SourceOverrides &Overrides) {
+ Overrides.applyOverrides(*Sources);
+ }
+
+ Rewriter &getRewriter() { return *Rewrite; }
+private:
+ LangOptions DefaultLangOptions;
+ llvm::IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
+ TextDiagnosticPrinter DiagnosticPrinter;
+ DiagnosticsEngine Diagnostics;
+ llvm::OwningPtr<SourceManager> Sources;
+ llvm::OwningPtr<Rewriter> Rewrite;
+};
+
+/// \brief Flatten the Rewriter buffers of \p Rewrite and store results as
+/// file content overrides in \p Overrides.
+void collectResults(clang::Rewriter &Rewrite, SourceOverrides &Overrides) {
for (Rewriter::buffer_iterator I = Rewrite.buffer_begin(),
E = Rewrite.buffer_end();
I != E; ++I) {
const FileEntry *Entry = Rewrite.getSourceMgr().getFileEntryForID(I->first);
assert(Entry != 0 && "Expected a FileEntry");
assert(Entry->getName() != 0 &&
"Unexpected NULL return from FileEntry::getName()");
- FileOverrides::iterator OverrideI = Results.find(Entry->getName());
- if (OverrideI == Results.end()) {
- OverrideI = Results.insert(FileOverrides::value_type(
- Entry->getName(), Entry->getName())).first;
- }
-
std::string ResultBuf;
// Get a copy of the rewritten buffer from the Rewriter.
@@ -103,30 +127,72 @@
// FIXME: Use move semantics to avoid copies of the buffer contents if
// benchmarking shows the copies are expensive, especially for large source
// files.
- OverrideI->second.MainFileOverride = ResultBuf;
+
+ if (Overrides.MainFileName == Entry->getName()) {
+ Overrides.MainFileOverride = 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.
+
+ HeaderOverrides &Headers = Overrides.Headers;
+ HeaderOverrides::iterator HeaderI = Headers.find(Entry->getName());
+ if (HeaderI == Headers.end())
+ HeaderI = Headers.insert(HeaderOverrides::value_type(
+ Entry->getName(), Entry->getName())).first;
+
+ HeaderI->second.FileOverride = ResultBuf;
}
}
+Transform::Transform(llvm::StringRef Name, const TransformOptions &Options)
+ : Name(Name), GlobalOptions(Options), Overrides(0),
+ RewriterOwner(new RewriterManager) {
+ Reset();
+}
+
+Transform::~Transform() {}
+
bool Transform::handleBeginSource(CompilerInstance &CI, StringRef Filename) {
- assert(InputState != 0 && "Subclass transform didn't provide InputState");
+ assert(Overrides != 0 && "Subclass transform didn't provide InputState");
+
+ CurrentSource = Filename.str();
- FileOverrides::const_iterator I = InputState->find(Filename.str());
- if (I != InputState->end()) {
- I->second.applyOverrides(CI.getSourceManager(), CI.getFileManager());
+ RewriterOwner->prepare(CI.getFileManager());
+ FileOverrides::const_iterator I = Overrides->find(CurrentSource);
+ if (I != Overrides->end()) {
+ I->second.applyOverrides(CI.getSourceManager());
+ RewriterOwner->applyOverrides(I->second);
}
+ Replace.clear();
+
if (Options().EnableTiming) {
Timings.push_back(std::make_pair(Filename.str(), llvm::TimeRecord()));
Timings.back().second -= llvm::TimeRecord::getCurrentTime(true);
}
return true;
}
void Transform::handleEndSource() {
- if (!Options().EnableTiming)
- return;
+ if (!getReplacements().empty()) {
+ // FIXME: applyAllReplacements will indicate if it couldn't apply all
+ // replacements. Handle that case.
+ applyAllReplacements(getReplacements(), RewriterOwner->getRewriter());
+
+ FileOverrides::iterator I = Overrides->find(CurrentSource);
+ if (I == Overrides->end())
+ I = Overrides
+ ->insert(FileOverrides::value_type(CurrentSource, CurrentSource)).first;
+
+ collectResults(RewriterOwner->getRewriter(), I->second);
+ }
- Timings.back().second += llvm::TimeRecord::getCurrentTime(false);
+ if (Options().EnableTiming)
+ Timings.back().second += llvm::TimeRecord::getCurrentTime(false);
}
void Transform::addTiming(llvm::StringRef Label, llvm::TimeRecord Duration) {
Index: cpp11-migrate/Core/Transform.h
===================================================================
--- cpp11-migrate/Core/Transform.h
+++ cpp11-migrate/Core/Transform.h
@@ -19,16 +19,9 @@
#include <vector>
#include "Core/IncludeExcludeInfo.h"
#include "Core/FileOverrides.h"
+#include "clang/Tooling/Refactoring.h"
#include "llvm/Support/Timer.h"
-
-// For RewriterContainer
-#include "clang/Rewrite/Core/Rewriter.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/DiagnosticOptions.h"
-#include "clang/Frontend/TextDiagnosticPrinter.h"
-#include "clang/Basic/SourceManager.h"
-#include "llvm/Support/raw_ostream.h"
-////
+#include "llvm/ADT/OwningPtr.h"
/// \brief Description of the riskiness of actions that can be taken by
@@ -56,41 +49,7 @@
} // namespace ast_matchers
} // namespace clang
-
-/// \brief In \p Results place copies of the buffers resulting from applying
-/// all rewrites represented by \p Rewrite.
-///
-/// \p Results is made up of pairs {filename, buffer contents}. Pairs are
-/// simply appended to \p Results.
-void collectResults(clang::Rewriter &Rewrite,
- const FileOverrides &InputStates,
- FileOverrides &Results);
-
-/// \brief Class for containing a Rewriter instance and all of
-/// its lifetime dependencies.
-///
-/// Subclasses of Transform using RefactoringTools will need to create
-/// Rewriters in order to apply Replacements and get the resulting buffer.
-/// Rewriter requires some objects to exist at least as long as it does so this
-/// class contains instances of those objects.
-///
-/// FIXME: These objects should really come from somewhere more global instead
-/// of being recreated for every Transform subclass, especially diagnostics.
-class RewriterContainer {
-public:
- RewriterContainer(clang::FileManager &Files,
- const FileOverrides &InputStates);
-
- clang::Rewriter &getRewriter() { return Rewrite; }
-
-private:
- clang::LangOptions DefaultLangOptions;
- llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts;
- clang::TextDiagnosticPrinter DiagnosticPrinter;
- clang::DiagnosticsEngine Diagnostics;
- clang::SourceManager Sources;
- clang::Rewriter Rewrite;
-};
+class RewriterManager;
/// \brief Container for global options affecting all transforms.
struct TransformOptions {
@@ -125,24 +84,21 @@
/// \param Name Name of the transform for human-readable purposes (e.g. -help
/// text)
/// \param Options Collection of options that affect all transforms.
- Transform(llvm::StringRef Name, const TransformOptions &Options)
- : Name(Name), GlobalOptions(Options), InputState(0) {
- Reset();
- }
+ /// \param InitialState File Contents to override content on disk.
+ Transform(llvm::StringRef Name, const TransformOptions &Options);
- virtual ~Transform() {}
+ virtual ~Transform();
/// \brief Apply a transform to all files listed in \p SourcePaths.
///
/// \p Database must contain information for how to compile all files in \p
/// SourcePaths. \p InputStates contains the file contents of files in \p
/// 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(const FileOverrides &InputStates,
+ virtual int apply(FileOverrides &InputStates,
const clang::tooling::CompilationDatabase &Database,
- const std::vector<std::string> &SourcePaths,
- FileOverrides &ResultStates) = 0;
+ const std::vector<std::string> &SourcePaths) = 0;
/// \brief Query if changes were made during the last call to apply().
bool getChangesMade() const { return AcceptedChanges > 0; }
@@ -221,14 +177,22 @@
/// data for all sources processed by this transform.
void addTiming(llvm::StringRef Label, llvm::TimeRecord Duration);
+ /// \brief Provide access for subclasses to the TransformOptions they were
+ /// created with.
const TransformOptions &Options() { return GlobalOptions; }
- /// \brief Allows a subclass to provide file contents overrides before
+ /// \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(const FileOverrides &Overrides) { InputState = &Overrides; }
+ void setOverrides(FileOverrides &Overrides) {
+ this->Overrides = &Overrides;
+ }
/// \brief Subclasses must call this function to create a
/// FrontendActionFactory to pass to ClangTool.
@@ -241,8 +205,11 @@
private:
const std::string Name;
const TransformOptions &GlobalOptions;
+ FileOverrides *Overrides;
+ clang::tooling::Replacements Replace;
+ llvm::OwningPtr<RewriterManager> RewriterOwner;
+ std::string CurrentSource;
TimingVec Timings;
- const FileOverrides *InputState;
unsigned AcceptedChanges;
unsigned RejectedChanges;
unsigned DeferredChanges;
Index: cpp11-migrate/LoopConvert/LoopConvert.cpp
===================================================================
--- cpp11-migrate/LoopConvert/LoopConvert.cpp
+++ cpp11-migrate/LoopConvert/LoopConvert.cpp
@@ -25,11 +25,10 @@
using namespace clang::tooling;
using namespace clang;
-int LoopConvertTransform::apply(const FileOverrides &InputStates,
+int LoopConvertTransform::apply(FileOverrides &InputStates,
const CompilationDatabase &Database,
- const std::vector<std::string> &SourcePaths,
- FileOverrides &ResultStates) {
- RefactoringTool LoopTool(Database, SourcePaths);
+ const std::vector<std::string> &SourcePaths) {
+ ClangTool LoopTool(Database, SourcePaths);
StmtAncestorASTVisitor ParentFinder;
StmtGeneratedVarNameMap GeneratedDecls;
@@ -39,22 +38,19 @@
unsigned RejectedChanges = 0;
MatchFinder Finder;
- LoopFixer ArrayLoopFixer(&ParentFinder, &LoopTool.getReplacements(),
- &GeneratedDecls, &ReplacedVars, &AcceptedChanges,
- &DeferredChanges, &RejectedChanges,
- Options().MaxRiskLevel, LFK_Array);
+ LoopFixer ArrayLoopFixer(&ParentFinder, &getReplacements(), &GeneratedDecls,
+ &ReplacedVars, &AcceptedChanges, &DeferredChanges,
+ &RejectedChanges, Options().MaxRiskLevel, LFK_Array);
Finder.addMatcher(makeArrayLoopMatcher(), &ArrayLoopFixer);
- LoopFixer IteratorLoopFixer(&ParentFinder, &LoopTool.getReplacements(),
- &GeneratedDecls, &ReplacedVars,
- &AcceptedChanges, &DeferredChanges,
- &RejectedChanges,
+ LoopFixer IteratorLoopFixer(&ParentFinder, &getReplacements(),
+ &GeneratedDecls, &ReplacedVars, &AcceptedChanges,
+ &DeferredChanges, &RejectedChanges,
Options().MaxRiskLevel, LFK_Iterator);
Finder.addMatcher(makeIteratorLoopMatcher(), &IteratorLoopFixer);
- LoopFixer PseudoarrrayLoopFixer(&ParentFinder, &LoopTool.getReplacements(),
- &GeneratedDecls, &ReplacedVars,
- &AcceptedChanges, &DeferredChanges,
- &RejectedChanges,
- Options().MaxRiskLevel, LFK_PseudoArray);
+ LoopFixer PseudoarrrayLoopFixer(
+ &ParentFinder, &getReplacements(), &GeneratedDecls, &ReplacedVars,
+ &AcceptedChanges, &DeferredChanges, &RejectedChanges,
+ Options().MaxRiskLevel, LFK_PseudoArray);
Finder.addMatcher(makePseudoArrayLoopMatcher(), &PseudoarrrayLoopFixer);
setOverrides(InputStates);
@@ -64,13 +60,6 @@
return result;
}
- RewriterContainer Rewrite(LoopTool.getFiles(), InputStates);
-
- // FIXME: Do something if some replacements didn't get applied?
- LoopTool.applyAllReplacements(Rewrite.getRewriter());
-
- collectResults(Rewrite.getRewriter(), InputStates, ResultStates);
-
setAcceptedChanges(AcceptedChanges);
setRejectedChanges(RejectedChanges);
setDeferredChanges(DeferredChanges);
Index: cpp11-migrate/LoopConvert/LoopConvert.h
===================================================================
--- cpp11-migrate/LoopConvert/LoopConvert.h
+++ cpp11-migrate/LoopConvert/LoopConvert.h
@@ -27,10 +27,9 @@
: Transform("LoopConvert", Options) {}
/// \see Transform::run().
- virtual int apply(const FileOverrides &InputStates,
+ virtual int apply(FileOverrides &InputStates,
const clang::tooling::CompilationDatabase &Database,
- const std::vector<std::string> &SourcePaths,
- FileOverrides &ResultStates) LLVM_OVERRIDE;
+ const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE;
};
#endif // LLVM_TOOLS_CLANG_TOOLS_EXTRA_CPP11_MIGRATE_LOOP_CONVERT_H
Index: cpp11-migrate/UseAuto/UseAuto.cpp
===================================================================
--- cpp11-migrate/UseAuto/UseAuto.cpp
+++ cpp11-migrate/UseAuto/UseAuto.cpp
@@ -20,18 +20,17 @@
using namespace clang;
using namespace clang::tooling;
-int UseAutoTransform::apply(const FileOverrides &InputStates,
+int UseAutoTransform::apply(FileOverrides &InputStates,
const clang::tooling::CompilationDatabase &Database,
- const std::vector<std::string> &SourcePaths,
- FileOverrides &ResultStates) {
- RefactoringTool UseAutoTool(Database, SourcePaths);
+ const std::vector<std::string> &SourcePaths) {
+ ClangTool UseAutoTool(Database, SourcePaths);
unsigned AcceptedChanges = 0;
MatchFinder Finder;
- IteratorReplacer ReplaceIterators(UseAutoTool.getReplacements(),
- AcceptedChanges, Options().MaxRiskLevel);
- NewReplacer ReplaceNew(UseAutoTool.getReplacements(), AcceptedChanges,
+ IteratorReplacer ReplaceIterators(getReplacements(), AcceptedChanges,
+ Options().MaxRiskLevel);
+ NewReplacer ReplaceNew(getReplacements(), AcceptedChanges,
Options().MaxRiskLevel);
Finder.addMatcher(makeIteratorDeclMatcher(), &ReplaceIterators);
@@ -44,13 +43,6 @@
return Result;
}
- RewriterContainer Rewrite(UseAutoTool.getFiles(), InputStates);
-
- // FIXME: Do something if some replacements didn't get applied?
- UseAutoTool.applyAllReplacements(Rewrite.getRewriter());
-
- collectResults(Rewrite.getRewriter(), InputStates, ResultStates);
-
setAcceptedChanges(AcceptedChanges);
return 0;
Index: cpp11-migrate/UseAuto/UseAuto.h
===================================================================
--- cpp11-migrate/UseAuto/UseAuto.h
+++ cpp11-migrate/UseAuto/UseAuto.h
@@ -29,13 +29,13 @@
/// p2 are not handled by this transform.
class UseAutoTransform : public Transform {
public:
- UseAutoTransform(const TransformOptions &Options) : Transform("UseAuto", Options) {}
+ UseAutoTransform(const TransformOptions &Options)
+ : Transform("UseAuto", Options) {}
/// \see Transform::run().
- virtual int apply(const FileOverrides &InputStates,
+ virtual int apply(FileOverrides &InputStates,
const clang::tooling::CompilationDatabase &Database,
- const std::vector<std::string> &SourcePaths,
- FileOverrides &ResultStates) LLVM_OVERRIDE;
+ const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE;
};
#endif // LLVM_TOOLS_CLANG_TOOLS_EXTRA_CPP11_MIGRATE_USE_AUTO_H
Index: cpp11-migrate/UseNullptr/UseNullptr.cpp
===================================================================
--- cpp11-migrate/UseNullptr/UseNullptr.cpp
+++ cpp11-migrate/UseNullptr/UseNullptr.cpp
@@ -25,17 +25,15 @@
using namespace clang::tooling;
using namespace clang;
-int UseNullptrTransform::apply(const FileOverrides &InputStates,
+int UseNullptrTransform::apply(FileOverrides &InputStates,
const CompilationDatabase &Database,
- const std::vector<std::string> &SourcePaths,
- FileOverrides &ResultStates) {
- RefactoringTool UseNullptrTool(Database, SourcePaths);
+ const std::vector<std::string> &SourcePaths) {
+ ClangTool UseNullptrTool(Database, SourcePaths);
unsigned AcceptedChanges = 0;
MatchFinder Finder;
- NullptrFixer Fixer(UseNullptrTool.getReplacements(),
- AcceptedChanges,
+ NullptrFixer Fixer(getReplacements(), AcceptedChanges,
Options().MaxRiskLevel);
Finder.addMatcher(makeCastSequenceMatcher(), &Fixer);
@@ -46,13 +44,6 @@
return result;
}
- RewriterContainer Rewrite(UseNullptrTool.getFiles(), InputStates);
-
- // FIXME: Do something if some replacements didn't get applied?
- UseNullptrTool.applyAllReplacements(Rewrite.getRewriter());
-
- collectResults(Rewrite.getRewriter(), InputStates, ResultStates);
-
setAcceptedChanges(AcceptedChanges);
return 0;
Index: cpp11-migrate/UseNullptr/UseNullptr.h
===================================================================
--- cpp11-migrate/UseNullptr/UseNullptr.h
+++ cpp11-migrate/UseNullptr/UseNullptr.h
@@ -27,10 +27,9 @@
: Transform("UseNullptr", Options) {}
/// \see Transform::run().
- virtual int apply(const FileOverrides &InputStates,
+ virtual int apply(FileOverrides &InputStates,
const clang::tooling::CompilationDatabase &Database,
- const std::vector<std::string> &SourcePaths,
- FileOverrides &ResultStates) LLVM_OVERRIDE;
+ const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE;
};
#endif // LLVM_TOOLS_CLANG_TOOLS_EXTRA_CPP11_MIGRATE_USE_NULLPTR_H
Index: cpp11-migrate/tool/Cpp11Migrate.cpp
===================================================================
--- cpp11-migrate/tool/Cpp11Migrate.cpp
+++ cpp11-migrate/tool/Cpp11Migrate.cpp
@@ -130,17 +130,15 @@
return 1;
}
- FileOverrides FileStates1, FileStates2,
- *InputFileStates = &FileStates1, *OutputFileStates = &FileStates2;
-
+ FileOverrides FileStates;
SourcePerfData PerfData;
// Apply transforms.
for (Transforms::const_iterator I = TransformManager.begin(),
E = TransformManager.end();
I != E; ++I) {
- if ((*I)->apply(*InputFileStates, OptionsParser.getCompilations(),
- OptionsParser.getSourcePathList(), *OutputFileStates) !=
+ if ((*I)->apply(FileStates, OptionsParser.getCompilations(),
+ OptionsParser.getSourcePathList()) !=
0) {
// FIXME: Improve ClangTool to not abort if just one file fails.
return 1;
@@ -161,24 +159,25 @@
}
llvm::outs() << "\n";
}
- std::swap(InputFileStates, OutputFileStates);
- OutputFileStates->clear();
}
if (FinalSyntaxCheck)
- // Final state of files is pointed at by InputFileStates.
if (!doSyntaxCheck(OptionsParser.getCompilations(),
- OptionsParser.getSourcePathList(), *InputFileStates))
+ OptionsParser.getSourcePathList(), FileStates))
return 1;
// Write results to file.
- for (FileOverrides::const_iterator I = InputFileStates->begin(),
- E = InputFileStates->end();
+ for (FileOverrides::const_iterator I = FileStates.begin(),
+ E = FileStates.end();
I != E; ++I) {
- std::string ErrorInfo;
- llvm::raw_fd_ostream FileStream(I->first.c_str(), ErrorInfo,
- llvm::raw_fd_ostream::F_Binary);
- FileStream << I->second.MainFileOverride;
+ if (I->second.isSourceOverriden()) {
+ llvm::errs() << "Writing source: " << I->first << "\n";
+
+ std::string ErrorInfo;
+ llvm::raw_fd_ostream FileStream(I->first.c_str(), ErrorInfo,
+ llvm::raw_fd_ostream::F_Binary);
+ FileStream << I->second.MainFileOverride;
+ }
// FIXME: The Migrator shouldn't be responsible for writing headers
// to disk. Instead, it should write replacement info and another tool
@@ -188,7 +187,11 @@
for (HeaderOverrides::const_iterator HeaderI = I->second.Headers.begin(),
HeaderE = I->second.Headers.end();
HeaderI != HeaderE; ++HeaderI) {
- llvm::raw_fd_ostream HeaderStream(I->first.c_str(), ErrorInfo,
+ llvm::errs() << "Writing header: " << HeaderI->first << "\n";
+ assert(!HeaderI->second.FileOverride.empty() &&
+ "A header override should not be empty");
+ std::string ErrorInfo;
+ llvm::raw_fd_ostream HeaderStream(HeaderI->first.c_str(), ErrorInfo,
llvm::raw_fd_ostream::F_Binary);
HeaderStream << HeaderI->second.FileOverride;
}
Index: unittests/cpp11-migrate/PerfSupportTest.cpp
===================================================================
--- unittests/cpp11-migrate/PerfSupportTest.cpp
+++ unittests/cpp11-migrate/PerfSupportTest.cpp
@@ -9,9 +9,9 @@
TransformA(const TransformOptions &Options)
: Transform("TransformA", Options) {}
- virtual int apply(const FileOverrides &,
+ virtual int apply(FileOverrides &,
const tooling::CompilationDatabase &,
- const std::vector<std::string> &, FileOverrides &) {
+ const std::vector<std::string> &) {
return 0;
}
@@ -25,9 +25,9 @@
TransformB(const TransformOptions &Options)
: Transform("TransformB", Options) {}
- virtual int apply(const FileOverrides &,
+ virtual int apply(FileOverrides &,
const tooling::CompilationDatabase &,
- const std::vector<std::string> &, FileOverrides &) {
+ const std::vector<std::string> &) {
return 0;
}
Index: unittests/cpp11-migrate/TransformTest.cpp
===================================================================
--- unittests/cpp11-migrate/TransformTest.cpp
+++ unittests/cpp11-migrate/TransformTest.cpp
@@ -14,10 +14,9 @@
DummyTransform(llvm::StringRef Name, const TransformOptions &Options)
: Transform(Name, Options) {}
- virtual int apply(const FileOverrides &,
+ virtual int apply(FileOverrides &,
const tooling::CompilationDatabase &,
- const std::vector<std::string> &,
- FileOverrides &) { return 0; }
+ const std::vector<std::string> &) { return 0; }
void setAcceptedChanges(unsigned Changes) {
Transform::setAcceptedChanges(Changes);
@@ -29,7 +28,7 @@
Transform::setDeferredChanges(Changes);
}
- void setOverrides(const FileOverrides &Overrides) {
+ void setOverrides(FileOverrides &Overrides) {
Transform::setOverrides(Overrides);
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits