diff options
Diffstat (limited to 'clang-tools-extra/cpp11-migrate/Core')
7 files changed, 182 insertions, 35 deletions
diff --git a/clang-tools-extra/cpp11-migrate/Core/CMakeLists.txt b/clang-tools-extra/cpp11-migrate/Core/CMakeLists.txt index 1cd42f0b237..562ae65e1eb 100644 --- a/clang-tools-extra/cpp11-migrate/Core/CMakeLists.txt +++ b/clang-tools-extra/cpp11-migrate/Core/CMakeLists.txt @@ -1,6 +1,8 @@ set(LLVM_LINK_COMPONENTS support) add_clang_library(migrateCore + FileOverrides.cpp + SyntaxCheck.cpp Transforms.cpp Transform.cpp IncludeExcludeInfo.cpp diff --git a/clang-tools-extra/cpp11-migrate/Core/FileOverrides.cpp b/clang-tools-extra/cpp11-migrate/Core/FileOverrides.cpp new file mode 100644 index 00000000000..0f7e5214ff1 --- /dev/null +++ b/clang-tools-extra/cpp11-migrate/Core/FileOverrides.cpp @@ -0,0 +1,10 @@ +#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)); +} diff --git a/clang-tools-extra/cpp11-migrate/Core/FileOverrides.h b/clang-tools-extra/cpp11-migrate/Core/FileOverrides.h new file mode 100644 index 00000000000..d33cddf4c50 --- /dev/null +++ b/clang-tools-extra/cpp11-migrate/Core/FileOverrides.h @@ -0,0 +1,44 @@ +//===-- Core/FileOverrides.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief This file provides types and functionality for dealing with source +/// and header file content overrides. +/// +//===----------------------------------------------------------------------===// +#ifndef CPP11_MIGRATE_FILE_OVERRIDES_H +#define CPP11_MIGRATE_FILE_OVERRIDES_H + +#include <map> +#include <string> + +// Forward Declarations +namespace clang { +class SourceManager; +class FileManager; +} // namespace clang + + +/// \brief Container storing the file content overrides for a source file. +struct SourceOverrides { + SourceOverrides(const char *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; + + std::string MainFileName; + std::string MainFileOverride; +}; + +/// \brief Maps source file names to content override information. +typedef std::map<std::string, SourceOverrides> FileOverrides; + +#endif // CPP11_MIGRATE_FILE_OVERRIDES_H diff --git a/clang-tools-extra/cpp11-migrate/Core/SyntaxCheck.cpp b/clang-tools-extra/cpp11-migrate/Core/SyntaxCheck.cpp new file mode 100644 index 00000000000..65877668ee4 --- /dev/null +++ b/clang-tools-extra/cpp11-migrate/Core/SyntaxCheck.cpp @@ -0,0 +1,59 @@ +#include "SyntaxCheck.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/FrontendActions.h" +#include "clang/Tooling/Tooling.h" + +using namespace clang; +using namespace tooling; + +class SyntaxCheck : public SyntaxOnlyAction { +public: + SyntaxCheck(const FileOverrides &Overrides) : Overrides(Overrides) {} + + virtual bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) { + if (!SyntaxOnlyAction::BeginSourceFileAction(CI, Filename)) + return false; + + FileOverrides::const_iterator I = Overrides.find(Filename); + if (I != Overrides.end()) + I->second.applyOverrides(CI.getSourceManager(), CI.getFileManager()); + + return true; + } + +private: + const FileOverrides &Overrides; +}; + +class SyntaxCheckFactory : public FrontendActionFactory { +public: + SyntaxCheckFactory(const FileOverrides &Overrides) + : Overrides(Overrides) {} + + virtual FrontendAction *create() { return new SyntaxCheck(Overrides); } + +private: + const FileOverrides &Overrides; +}; + +class SyntaxArgumentsAdjuster : public ArgumentsAdjuster { + CommandLineArguments Adjust(const CommandLineArguments &Args) { + CommandLineArguments AdjustedArgs = Args; + AdjustedArgs.push_back("-fsyntax-only"); + AdjustedArgs.push_back("-std=c++11"); + return AdjustedArgs; + } +}; + +bool doSyntaxCheck(const CompilationDatabase &Database, + const std::vector<std::string> &SourcePaths, + const FileOverrides &Overrides) { + ClangTool SyntaxTool(Database, SourcePaths); + + // Ensure C++11 support is enabled. + // FIXME: This isn't necessary anymore since the Migrator requires C++11 + // to be enabled in the CompilationDatabase. Remove later. + SyntaxTool.setArgumentsAdjuster(new SyntaxArgumentsAdjuster); + + return SyntaxTool.run(new SyntaxCheckFactory(Overrides)) == 0; +} diff --git a/clang-tools-extra/cpp11-migrate/Core/SyntaxCheck.h b/clang-tools-extra/cpp11-migrate/Core/SyntaxCheck.h new file mode 100644 index 00000000000..570f955a8bf --- /dev/null +++ b/clang-tools-extra/cpp11-migrate/Core/SyntaxCheck.h @@ -0,0 +1,35 @@ +//===-- Core/SyntaxCheck.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 exposes functionaliy for doing a syntax-only check on +/// files with overridden contents. +/// +//===----------------------------------------------------------------------===// +#ifndef CPP11_MIGRATE_SYNTAX_CHECK_H +#define CPP11_MIGRATE_SYNTAX_CHECK_H + +#include <vector> +#include "Core/FileOverrides.h" + +// Forward Declarations +namespace clang { +namespace tooling { +class CompilationDatabase; +} // namespace tooling +} // namespace clang + +/// \brief Perform a syntax-only check over all files in \c SourcePaths using +/// options provided by \c Database using file contents from \c Overrides if +/// available. +extern bool doSyntaxCheck(const clang::tooling::CompilationDatabase &Database, + const std::vector<std::string> &SourcePaths, + const FileOverrides &Overrides); + +#endif // CPP11_MIGRATE_SYNTAX_CHECK_H diff --git a/clang-tools-extra/cpp11-migrate/Core/Transform.cpp b/clang-tools-extra/cpp11-migrate/Core/Transform.cpp index 718ed0785ad..3a054e330df 100644 --- a/clang-tools-extra/cpp11-migrate/Core/Transform.cpp +++ b/clang-tools-extra/cpp11-migrate/Core/Transform.cpp @@ -1,7 +1,5 @@ #include "Core/Transform.h" #include "clang/ASTMatchers/ASTMatchFinder.h" -#include "clang/Basic/FileManager.h" -#include "clang/Basic/SourceManager.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Rewrite/Core/Rewriter.h" #include "llvm/Support/raw_ostream.h" @@ -22,7 +20,7 @@ using namespace ast_matchers; /// SourceFileCallbacks. class ActionFactory : public clang::tooling::FrontendActionFactory { public: - ActionFactory(MatchFinder &Finder, const FileContentsByPath &Overrides, + ActionFactory(MatchFinder &Finder, const FileOverrides &Overrides, SourceFileCallbacks &Callbacks) : Finder(Finder), Overrides(Overrides), Callbacks(Callbacks) {} @@ -33,7 +31,7 @@ public: private: class FactoryAdaptor : public ASTFrontendAction { public: - FactoryAdaptor(MatchFinder &Finder, const FileContentsByPath &Overrides, + FactoryAdaptor(MatchFinder &Finder, const FileOverrides &Overrides, SourceFileCallbacks &Callbacks) : Finder(Finder), Overrides(Overrides), Callbacks(Callbacks) {} @@ -46,12 +44,10 @@ private: if (!ASTFrontendAction::BeginSourceFileAction(CI, Filename)) return false; - FileContentsByPath::const_iterator I = Overrides.find(Filename.str()); - if (I != Overrides.end()) - // If an override exists, use it. - CI.getSourceManager() - .overrideFileContents(CI.getFileManager().getFile(I->first), - llvm::MemoryBuffer::getMemBuffer(I->second)); + FileOverrides::const_iterator I = Overrides.find(Filename.str()); + if (I != Overrides.end()) { + I->second.applyOverrides(CI.getSourceManager(), CI.getFileManager()); + } return Callbacks.handleBeginSource(CI, Filename); } @@ -63,38 +59,34 @@ private: private: MatchFinder &Finder; - const FileContentsByPath &Overrides; + const FileOverrides &Overrides; SourceFileCallbacks &Callbacks; }; MatchFinder &Finder; - const FileContentsByPath &Overrides; + const FileOverrides &Overrides; SourceFileCallbacks &Callbacks; }; } // namespace RewriterContainer::RewriterContainer(clang::FileManager &Files, - const FileContentsByPath &InputStates) + 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) { - - // Overwrite source manager's file contents with data from InputStates - for (FileContentsByPath::const_iterator I = InputStates.begin(), - E = InputStates.end(); - I != E; ++I) { - Sources.overrideFileContents(Files.getFile(I->first), - llvm::MemoryBuffer::getMemBuffer(I->second)); - } + for (FileOverrides::const_iterator I = InputStates.begin(), + E = InputStates.end(); + I != E; ++I) + I->second.applyOverrides(Sources, Files); } void collectResults(clang::Rewriter &Rewrite, - const FileContentsByPath &InputStates, - FileContentsByPath &Results) { + const FileOverrides &InputStates, + FileOverrides &Results) { // Copy the contents of InputStates to be modified. Results = InputStates; @@ -106,6 +98,12 @@ void collectResults(clang::Rewriter &Rewrite, 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. @@ -118,7 +116,7 @@ void collectResults(clang::Rewriter &Rewrite, // FIXME: Use move semantics to avoid copies of the buffer contents if // benchmarking shows the copies are expensive, especially for large source // files. - Results[Entry->getName()] = ResultBuf; + OverrideI->second.MainFileOverride = ResultBuf; } } @@ -144,6 +142,6 @@ void Transform::addTiming(llvm::StringRef Label, llvm::TimeRecord Duration) { FrontendActionFactory * Transform::createActionFactory(MatchFinder &Finder, - const FileContentsByPath &InputStates) { + const FileOverrides &InputStates) { return new ActionFactory(Finder, InputStates, *this); } diff --git a/clang-tools-extra/cpp11-migrate/Core/Transform.h b/clang-tools-extra/cpp11-migrate/Core/Transform.h index 1312cf42ed6..d990b4ec65c 100644 --- a/clang-tools-extra/cpp11-migrate/Core/Transform.h +++ b/clang-tools-extra/cpp11-migrate/Core/Transform.h @@ -17,7 +17,9 @@ #include <string> #include <vector> -#include "IncludeExcludeInfo.h" +#include "Core/IncludeExcludeInfo.h" +#include "Core/FileOverrides.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Tooling/Tooling.h" #include "llvm/Support/Timer.h" @@ -54,9 +56,6 @@ class MatchFinder; } // namespace ast_matchers } // namespace clang -/// \brief The key is the path of a file, which is mapped to a -/// buffer with the possibly modified contents of that file. -typedef std::map<std::string, std::string> FileContentsByPath; /// \brief In \p Results place copies of the buffers resulting from applying /// all rewrites represented by \p Rewrite. @@ -64,8 +63,8 @@ typedef std::map<std::string, std::string> FileContentsByPath; /// \p Results is made up of pairs {filename, buffer contents}. Pairs are /// simply appended to \p Results. void collectResults(clang::Rewriter &Rewrite, - const FileContentsByPath &InputStates, - FileContentsByPath &Results); + const FileOverrides &InputStates, + FileOverrides &Results); /// \brief Class for containing a Rewriter instance and all of /// its lifetime dependencies. @@ -80,7 +79,7 @@ void collectResults(clang::Rewriter &Rewrite, class RewriterContainer { public: RewriterContainer(clang::FileManager &Files, - const FileContentsByPath &InputStates); + const FileOverrides &InputStates); clang::Rewriter &getRewriter() { return Rewrite; } @@ -140,10 +139,10 @@ 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(const FileContentsByPath &InputStates, + virtual int apply(const FileOverrides &InputStates, const clang::tooling::CompilationDatabase &Database, const std::vector<std::string> &SourcePaths, - FileContentsByPath &ResultStates) = 0; + FileOverrides &ResultStates) = 0; /// \brief Query if changes were made during the last call to apply(). bool getChangesMade() const { return AcceptedChanges > 0; } @@ -225,7 +224,7 @@ protected: /// for overriding source file contents with results of previous transforms. clang::tooling::FrontendActionFactory * createActionFactory(clang::ast_matchers::MatchFinder &Finder, - const FileContentsByPath &InputStates); + const FileOverrides &InputStates); private: const std::string Name; |

