- Adding missing docs and other cleanup
Hi tareqsiraj, arielbernal,
http://llvm-reviews.chandlerc.com/D893
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D893?vs=2190&id=2191#toc
Files:
cpp11-migrate/AddOverride/AddOverride.cpp
cpp11-migrate/AddOverride/AddOverride.h
cpp11-migrate/Core/Transform.cpp
cpp11-migrate/Core/Transform.h
cpp11-migrate/Core/Transforms.cpp
cpp11-migrate/Core/Transforms.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/TransformTest.cpp
Index: cpp11-migrate/AddOverride/AddOverride.cpp
===================================================================
--- cpp11-migrate/AddOverride/AddOverride.cpp
+++ cpp11-migrate/AddOverride/AddOverride.cpp
@@ -45,7 +45,8 @@
Finder.addMatcher(makeCandidateForOverrideAttrMatcher(), &Fixer);
- if (int result = AddOverrideTool.run(newFrontendActionFactory(&Finder))) {
+ if (int result = AddOverrideTool.run(
+ newFrontendActionFactory(&Finder, /*Callbacks=*/ this))) {
llvm::errs() << "Error encountered during translation.\n";
return result;
}
Index: cpp11-migrate/AddOverride/AddOverride.h
===================================================================
--- cpp11-migrate/AddOverride/AddOverride.h
+++ cpp11-migrate/AddOverride/AddOverride.h
@@ -24,7 +24,8 @@
/// member functions overriding base class virtual functions.
class AddOverrideTransform : public Transform {
public:
- AddOverrideTransform() : Transform("AddOverride") {}
+ AddOverrideTransform(bool EnableTiming)
+ : Transform("AddOverride", EnableTiming) {}
/// \see Transform::run().
virtual int apply(const FileContentsByPath &InputStates,
Index: cpp11-migrate/Core/Transform.cpp
===================================================================
--- cpp11-migrate/Core/Transform.cpp
+++ cpp11-migrate/Core/Transform.cpp
@@ -35,3 +35,20 @@
Results[Entry->getName()] = ResultBuf;
}
}
+
+bool Transform::handleBeginSource(CompilerInstance &CI, StringRef Filename) {
+ if (!EnableTiming)
+ return true;
+
+ Timings.resize(Timings.size() + 1);
+ Timings.back().first = Filename;
+ Timings.back().second -= llvm::TimeRecord::getCurrentTime(true);
+ return true;
+}
+
+void Transform::handleEndSource() {
+ if (!EnableTiming)
+ return;
+
+ Timings.back().second += llvm::TimeRecord::getCurrentTime(false);
+}
Index: cpp11-migrate/Core/Transform.h
===================================================================
--- cpp11-migrate/Core/Transform.h
+++ cpp11-migrate/Core/Transform.h
@@ -17,6 +17,8 @@
#include <string>
#include <vector>
+#include "clang/Tooling/Tooling.h"
+#include "llvm/Support/Timer.h"
// For RewriterContainer
#include "clang/Rewrite/Core/Rewriter.h"
@@ -104,9 +106,20 @@
};
/// \brief Abstract base class for all C++11 migration transforms.
-class Transform {
+///
+/// Per-source performance timing is handled by the callbacks
+/// handleBeginSource() and handleEndSource() if timing is enabled. See
+/// clang::tooling::newFrontendActionFactory() for how to register
+/// a Transform object for callbacks.
+class Transform : public clang::tooling::SourceFileCallbacks {
public:
- Transform(llvm::StringRef Name) : Name(Name) {
+ /// \brief Constructor
+ /// \param Name Name of the transform for human-readable purposes (e.g. -help
+ /// text)
+ /// \param EnableTiming Enable the timing of applying a FrontendAction (generally
+ /// a MatchFinder).
+ Transform(llvm::StringRef Name, bool EnableTiming)
+ : Name(Name), EnableTiming(EnableTiming) {
Reset();
}
@@ -156,7 +169,29 @@
DeferredChanges = 0;
}
+ /// \brief Callback for notification of the start of processing of a source
+ /// file by a FrontendAction. Starts a per-source performance timer if
+ /// timing was enabled.
+ virtual bool handleBeginSource(clang::CompilerInstance &CI,
+ llvm::StringRef Filename) LLVM_OVERRIDE;
+
+ /// \brief Callback for notification of the end of processing of a source
+ /// file by a FrontendAction. Stops a per-source performance timer if
+ /// timing was enabled and records the elapsed time. handleBeginSource()
+ /// and handleEndSource() are expected to be called in pairs.
+ virtual void handleEndSource() LLVM_OVERRIDE;
+
+ /// \brief Performance timing data is stored as a simple vector of pairs of
+ /// source file name and elapsed time.
+ typedef std::vector<std::pair<std::string, llvm::TimeRecord> > TimingVec;
+
+ /// \brief Return an iterator to the start of collected timing data.
+ TimingVec::const_iterator timing_begin() const { return Timings.begin(); }
+ /// \brief Return an iterator to the start of collected timing data.
+ TimingVec::const_iterator timing_end() const { return Timings.end(); }
+
protected:
+
void setAcceptedChanges(unsigned Changes) {
AcceptedChanges = Changes;
}
@@ -169,6 +204,8 @@
private:
const std::string Name;
+ bool EnableTiming;
+ TimingVec Timings;
unsigned AcceptedChanges;
unsigned RejectedChanges;
unsigned DeferredChanges;
Index: cpp11-migrate/Core/Transforms.cpp
===================================================================
--- cpp11-migrate/Core/Transforms.cpp
+++ cpp11-migrate/Core/Transforms.cpp
@@ -35,11 +35,11 @@
new cl::opt<bool>(OptName.data(), cl::desc(Description.data())), Creator));
}
-void Transforms::createSelectedTransforms() {
+void Transforms::createSelectedTransforms(bool EnableTiming) {
for (OptionVec::iterator I = Options.begin(),
E = Options.end(); I != E; ++I) {
if (*I->first) {
- ChosenTransforms.push_back(I->second());
+ ChosenTransforms.push_back(I->second(EnableTiming));
}
}
}
Index: cpp11-migrate/Core/Transforms.h
===================================================================
--- cpp11-migrate/Core/Transforms.h
+++ cpp11-migrate/Core/Transforms.h
@@ -28,10 +28,10 @@
} // namespace llvm
class Transform;
-typedef Transform *(*TransformCreator)();
+typedef Transform *(*TransformCreator)(bool);
template <typename T>
-Transform *ConstructTransform() {
- return new T();
+Transform *ConstructTransform(bool EnableTiming) {
+ return new T(EnableTiming);
}
/// \brief Class encapsulating the creation of command line bool options
@@ -55,7 +55,7 @@
/// \brief Instantiate all transforms that were selected on the command line.
///
/// Call *after* parsing options.
- void createSelectedTransforms();
+ void createSelectedTransforms(bool EnableTiming);
/// \brief Return an iterator to the start of a container of instantiated
/// transforms.
Index: cpp11-migrate/LoopConvert/LoopConvert.cpp
===================================================================
--- cpp11-migrate/LoopConvert/LoopConvert.cpp
+++ cpp11-migrate/LoopConvert/LoopConvert.cpp
@@ -64,7 +64,8 @@
MaxRisk, LFK_PseudoArray);
Finder.addMatcher(makePseudoArrayLoopMatcher(), &PseudoarrrayLoopFixer);
- if (int result = LoopTool.run(newFrontendActionFactory(&Finder))) {
+ if (int result = LoopTool.run(
+ newFrontendActionFactory(&Finder, /*Callbacks=*/ this))) {
llvm::errs() << "Error encountered during translation.\n";
return result;
}
Index: cpp11-migrate/LoopConvert/LoopConvert.h
===================================================================
--- cpp11-migrate/LoopConvert/LoopConvert.h
+++ cpp11-migrate/LoopConvert/LoopConvert.h
@@ -23,7 +23,8 @@
/// for-loops where possible.
class LoopConvertTransform : public Transform {
public:
- LoopConvertTransform() : Transform("LoopConvert") {}
+ LoopConvertTransform(bool EnableTiming)
+ : Transform("LoopConvert", EnableTiming) {}
/// \see Transform::run().
virtual int apply(const FileContentsByPath &InputStates,
Index: cpp11-migrate/UseAuto/UseAuto.cpp
===================================================================
--- cpp11-migrate/UseAuto/UseAuto.cpp
+++ cpp11-migrate/UseAuto/UseAuto.cpp
@@ -43,7 +43,8 @@
Finder.addMatcher(makeIteratorDeclMatcher(), &ReplaceIterators);
Finder.addMatcher(makeDeclWithNewMatcher(), &ReplaceNew);
- if (int Result = UseAutoTool.run(newFrontendActionFactory(&Finder))) {
+ if (int Result = UseAutoTool.run(
+ newFrontendActionFactory(&Finder, /*Callbacks=*/ this))) {
llvm::errs() << "Error encountered during translation.\n";
return Result;
}
Index: cpp11-migrate/UseAuto/UseAuto.h
===================================================================
--- cpp11-migrate/UseAuto/UseAuto.h
+++ cpp11-migrate/UseAuto/UseAuto.h
@@ -29,7 +29,7 @@
/// p2 are not handled by this transform.
class UseAutoTransform : public Transform {
public:
- UseAutoTransform() : Transform("UseAuto") {}
+ UseAutoTransform(bool EnableTiming) : Transform("UseAuto", EnableTiming) {}
/// \see Transform::run().
virtual int apply(const FileContentsByPath &InputStates,
Index: cpp11-migrate/UseNullptr/UseNullptr.cpp
===================================================================
--- cpp11-migrate/UseNullptr/UseNullptr.cpp
+++ cpp11-migrate/UseNullptr/UseNullptr.cpp
@@ -47,7 +47,8 @@
Finder.addMatcher(makeCastSequenceMatcher(), &Fixer);
- if (int result = UseNullptrTool.run(newFrontendActionFactory(&Finder))) {
+ if (int result = UseNullptrTool.run(
+ newFrontendActionFactory(&Finder, /*Callbacks=*/ this))) {
llvm::errs() << "Error encountered during translation.\n";
return result;
}
Index: cpp11-migrate/UseNullptr/UseNullptr.h
===================================================================
--- cpp11-migrate/UseNullptr/UseNullptr.h
+++ cpp11-migrate/UseNullptr/UseNullptr.h
@@ -23,7 +23,8 @@
/// C++11's nullptr keyword where possible.
class UseNullptrTransform : public Transform {
public:
- UseNullptrTransform() : Transform("UseNullptr") {}
+ UseNullptrTransform(bool EnableTiming)
+ : Transform("UseNullptr", EnableTiming) {}
/// \see Transform::run().
virtual int apply(const FileContentsByPath &InputStates,
Index: cpp11-migrate/tool/Cpp11Migrate.cpp
===================================================================
--- cpp11-migrate/tool/Cpp11Migrate.cpp
+++ cpp11-migrate/tool/Cpp11Migrate.cpp
@@ -99,7 +99,7 @@
// This causes options to be parsed.
CommonOptionsParser OptionsParser(argc, argv);
- TransformManager.createSelectedTransforms();
+ TransformManager.createSelectedTransforms(/*EnableTiming=*/false);
if (TransformManager.begin() == TransformManager.end()) {
llvm::errs() << "No selected transforms\n";
Index: unittests/cpp11-migrate/TransformTest.cpp
===================================================================
--- unittests/cpp11-migrate/TransformTest.cpp
+++ unittests/cpp11-migrate/TransformTest.cpp
@@ -1,13 +1,20 @@
#include "gtest/gtest.h"
#include "Core/Transform.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/DeclGroup.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/Path.h"
+
+using namespace clang;
class DummyTransform : public Transform {
public:
- DummyTransform(llvm::StringRef Name) : Transform(Name) {}
+ DummyTransform(llvm::StringRef Name, bool EnableTiming)
+ : Transform(Name, EnableTiming) {}
virtual int apply(const FileContentsByPath &,
RiskLevel ,
- const clang::tooling::CompilationDatabase &,
+ const tooling::CompilationDatabase &,
const std::vector<std::string> &,
FileContentsByPath &) { return 0; }
@@ -23,7 +30,7 @@
};
TEST(Transform, Interface) {
- DummyTransform T("my_transform");
+ DummyTransform T("my_transform", /*EnableTiming=*/false);
ASSERT_EQ("my_transform", T.getName());
ASSERT_EQ(0u, T.getAcceptedChanges());
ASSERT_EQ(0u, T.getRejectedChanges());
@@ -48,3 +55,83 @@
T.setRejectedChanges(1);
ASSERT_TRUE(T.getChangesNotMade());
}
+
+class FindTopLevelDeclConsumer : public ASTConsumer {
+public:
+ FindTopLevelDeclConsumer(bool *Called) : Called(Called) {}
+
+ virtual bool HandleTopLevelDecl(DeclGroupRef DeclGroup) {
+ llvm::sys::TimeValue UserStart;
+ llvm::sys::TimeValue SystemStart;
+ llvm::sys::TimeValue UserNow;
+ llvm::sys::TimeValue SystemNow;
+ llvm::sys::TimeValue Wall;
+
+ // Busy-wait until the user/system time combined is more than 1ms
+ llvm::sys::TimeValue OneMS(0, 1000000);
+ llvm::sys::Process::GetTimeUsage(Wall, UserStart, SystemStart);
+ do {
+ llvm::sys::Process::GetTimeUsage(Wall, UserNow, SystemNow);
+ } while (UserNow - UserStart + SystemNow - SystemStart < OneMS);
+ *Called = true;
+ return true;
+ }
+ bool *Called;
+};
+
+struct ConsumerFactory {
+ ASTConsumer *newASTConsumer() {
+ return new FindTopLevelDeclConsumer(&Called);
+ }
+ bool Called;
+};
+
+TEST(Transform, Timings) {
+ DummyTransform T("timing_transform", /*EnableTiming=*/true);
+
+ // All the path stuff is to make the test work independently of OS.
+
+ // The directory used is not important since the path gets mapped to a virtual
+ // file anyway. What is important is that we have an absolute path with which
+ // to use with mapVirtualFile().
+ llvm::sys::Path FileA = llvm::sys::Path::GetCurrentDirectory();
+ std::string CurrentDir = FileA.str();
+ FileA.appendComponent("a.cc");
+ std::string FileAName = FileA.str();
+ llvm::sys::Path FileB = llvm::sys::Path::GetCurrentDirectory();
+ FileB.appendComponent("b.cc");
+ std::string FileBName = FileB.str();
+
+ tooling::FixedCompilationDatabase Compilations(CurrentDir, std::vector<std::string>());
+ std::vector<std::string> Sources;
+ Sources.push_back(FileAName);
+ Sources.push_back(FileBName);
+ tooling::ClangTool Tool(Compilations, Sources);
+
+ Tool.mapVirtualFile(FileAName, "void a() {}");
+ Tool.mapVirtualFile(FileBName, "void b() {}");
+
+ ConsumerFactory Factory;
+ Tool.run(newFrontendActionFactory(&Factory, &T));
+
+ EXPECT_TRUE(Factory.Called);
+ Transform::TimingVec::const_iterator I = T.timing_begin();
+ EXPECT_GT(I->second.getProcessTime(), 0.0);
+
+ // The success of the test shouldn't depend on the order of iteration through
+ // timers.
+ llvm::sys::Path FirstFile(I->first);
+ if (FileA == FirstFile) {
+ ++I;
+ EXPECT_EQ(FileB, llvm::sys::Path(I->first));
+ EXPECT_GT(I->second.getProcessTime(), 0.0);
+ } else if (FileB == FirstFile) {
+ ++I;
+ EXPECT_EQ(FileA, llvm::sys::Path(I->first));
+ EXPECT_GT(I->second.getProcessTime(), 0.0);
+ } else {
+ FAIL() << "Unexpected file name " << I->first << " in timing data.";
+ }
+ ++I;
+ EXPECT_EQ(T.timing_end(), I);
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits