diff options
author | Tareq A. Siraj <tareq.a.sriaj@intel.com> | 2013-07-12 14:36:20 +0000 |
---|---|---|
committer | Tareq A. Siraj <tareq.a.sriaj@intel.com> | 2013-07-12 14:36:20 +0000 |
commit | e0a03c3c64b176c272982835798b9adce8056df2 (patch) | |
tree | 97ed539f1117bbcf465c5bdd55847feba9ac415c /clang-tools-extra | |
parent | 9895ac1119f3df3d42205e08f9ad32ee15281c6a (diff) | |
download | bcm5719-llvm-e0a03c3c64b176c272982835798b9adce8056df2.tar.gz bcm5719-llvm-e0a03c3c64b176c272982835798b9adce8056df2.zip |
cpp11-migrate: FileOverrides/Transform refactoring.
This commit include the following changes:
- SourceOverrides is now a class
- it simplifies the usage for the Transform class, since now the
replacements can be applied directly to the file overrides with
SourceOverrides::applyReplacements().
- it contains a method applyRewrites() which was previously named
collectResults() in Transform.cpp. The method has been "optimized"
a bit to re-use the allocated buffer (std::string::clear() is called).
- since the class has some logic it's now unit tested
- Now FileOverrides is a class (not a std::map typedef) and store pointers
to the SourceOverrides. The reason is that the SourceOverrides can't be
copied anymore (which was already something to avoid since it's can be a
quite large object).
Author: Guillaume Papin <guillaume.papin@epitech.eu>
Differential Revision: http://llvm-reviews.chandlerc.com/D1122
llvm-svn: 186161
Diffstat (limited to 'clang-tools-extra')
10 files changed, 259 insertions, 152 deletions
diff --git a/clang-tools-extra/cpp11-migrate/Core/FileOverrides.cpp b/clang-tools-extra/cpp11-migrate/Core/FileOverrides.cpp index 8140cf576a3..200b7fa2d9e 100644 --- a/clang-tools-extra/cpp11-migrate/Core/FileOverrides.cpp +++ b/clang-tools-extra/cpp11-migrate/Core/FileOverrides.cpp @@ -14,23 +14,99 @@ //===----------------------------------------------------------------------===// #include "Core/FileOverrides.h" - +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/SourceManager.h" -#include "llvm/Support/Path.h" +#include "clang/Format/Format.h" +#include "clang/Lex/Lexer.h" +#include "clang/Rewrite/Core/Rewriter.h" +#include "clang/Tooling/Tooling.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/system_error.h" -void SourceOverrides::applyOverrides(clang::SourceManager &SM) const { - clang::FileManager &FM = SM.getFileManager(); +using namespace clang; +using namespace clang::tooling; + +SourceOverrides::SourceOverrides(llvm::StringRef MainFileName) + : MainFileName(MainFileName) {} + +void SourceOverrides::applyReplacements(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(tooling::Replacements &Replaces, + 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."; + + applyRewrites(Rewrites); +} + +void SourceOverrides::applyRewrites(Rewriter &Rewrites) { + 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]; + HeaderOv.FileOverride.swap(ResultBuf); + // "Create" HeaderOverride if not already existing + if (HeaderOv.FileName.empty()) + HeaderOv.FileName = FileName; + } +} + +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.FileOverride.empty() && "Header override should not be empty!"); + for (HeaderOverrides::const_iterator I = Headers.begin(), 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)); @@ -68,3 +144,16 @@ 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); + return *Override; +} diff --git a/clang-tools-extra/cpp11-migrate/Core/FileOverrides.h b/clang-tools-extra/cpp11-migrate/Core/FileOverrides.h index b0bc9682d64..7f8c8d20011 100644 --- a/clang-tools-extra/cpp11-migrate/Core/FileOverrides.h +++ b/clang-tools-extra/cpp11-migrate/Core/FileOverrides.h @@ -16,10 +16,8 @@ #ifndef CPP11_MIGRATE_FILE_OVERRIDES_H #define CPP11_MIGRATE_FILE_OVERRIDES_H -#include "llvm/ADT/StringRef.h" - -#include <map> -#include <string> +#include "clang/Tooling/Refactoring.h" +#include "llvm/ADT/StringMap.h" // Forward Declarations namespace llvm { @@ -28,7 +26,7 @@ class SmallVectorImpl; } // namespace llvm namespace clang { class SourceManager; -class FileManager; +class Rewriter; } // namespace clang /// \brief Container for storing override information for a single headers. @@ -41,16 +39,20 @@ struct HeaderOverride { }; /// \brief Container mapping header file names to override information. -typedef std::map<std::string, HeaderOverride> HeaderOverrides; +typedef llvm::StringMap<HeaderOverride> HeaderOverrides; -/// \brief Container storing the file content overrides for a source file. -struct SourceOverrides { - SourceOverrides(const std::string &MainFileName) - : MainFileName(MainFileName) {} +/// \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); - /// \brief Convenience function for applying this source's overrides to - /// the given SourceManager. - void applyOverrides(clang::SourceManager &SM) const; + /// \brief Accessors. + /// @{ + llvm::StringRef getMainFileName() const { return MainFileName; } + llvm::StringRef getMainFileContent() const { return MainFileOverride; } + /// @} /// \brief Indicates if the source file has been overridden. /// @@ -58,13 +60,67 @@ struct SourceOverrides { /// changed. bool isSourceOverriden() const { return !MainFileOverride.empty(); } - std::string MainFileName; + /// \brief Override the file contents by applying all the replacements. + /// + /// \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: + /// \brief Flatten the Rewriter buffers of \p Rewrite and store results as + /// file content overrides. + void applyRewrites(clang::Rewriter &Rewrite); + + const std::string MainFileName; std::string MainFileOverride; HeaderOverrides Headers; }; /// \brief Maps source file names to content override information. -typedef std::map<std::string, SourceOverrides> FileOverrides; +class FileOverrides { +public: + typedef llvm::StringMap<SourceOverrides *> SourceOverridesMap; + typedef SourceOverridesMap::const_iterator const_iterator; + + FileOverrides() {} + ~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(); } + /// @} + +private: + FileOverrides(const FileOverrides &) LLVM_DELETED_FUNCTION; + FileOverrides &operator=(const FileOverrides &) LLVM_DELETED_FUNCTION; + + SourceOverridesMap Overrides; +}; /// \brief Generate a unique filename to store the replacements. /// diff --git a/clang-tools-extra/cpp11-migrate/Core/SyntaxCheck.cpp b/clang-tools-extra/cpp11-migrate/Core/SyntaxCheck.cpp index 9db47fadf69..7315768f360 100644 --- a/clang-tools-extra/cpp11-migrate/Core/SyntaxCheck.cpp +++ b/clang-tools-extra/cpp11-migrate/Core/SyntaxCheck.cpp @@ -13,7 +13,8 @@ /// //===----------------------------------------------------------------------===// -#include "SyntaxCheck.h" +#include "Core/SyntaxCheck.h" +#include "Core/FileOverrides.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendActions.h" #include "clang/Tooling/Tooling.h" @@ -31,7 +32,7 @@ public: FileOverrides::const_iterator I = Overrides.find(Filename); if (I != Overrides.end()) - I->second.applyOverrides(CI.getSourceManager()); + I->second->applyOverrides(CI.getSourceManager()); return true; } diff --git a/clang-tools-extra/cpp11-migrate/Core/SyntaxCheck.h b/clang-tools-extra/cpp11-migrate/Core/SyntaxCheck.h index e845971af7a..1651a7e7acc 100644 --- a/clang-tools-extra/cpp11-migrate/Core/SyntaxCheck.h +++ b/clang-tools-extra/cpp11-migrate/Core/SyntaxCheck.h @@ -16,8 +16,7 @@ #ifndef CPP11_MIGRATE_SYNTAX_CHECK_H #define CPP11_MIGRATE_SYNTAX_CHECK_H -#include "Core/FileOverrides.h" - +#include <string> #include <vector> // Forward Declarations @@ -27,6 +26,8 @@ class CompilationDatabase; } // namespace tooling } // namespace clang +class FileOverrides; + /// \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. diff --git a/clang-tools-extra/cpp11-migrate/Core/Transform.cpp b/clang-tools-extra/cpp11-migrate/Core/Transform.cpp index 312ef39a6c0..d75fc10291d 100644 --- a/clang-tools-extra/cpp11-migrate/Core/Transform.cpp +++ b/clang-tools-extra/cpp11-migrate/Core/Transform.cpp @@ -14,15 +14,12 @@ //===----------------------------------------------------------------------===// #include "Core/Transform.h" +#include "Core/FileOverrides.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" using namespace clang; @@ -77,96 +74,8 @@ private: }; } // namespace -/// \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 are (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 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()"); - - std::string ResultBuf; - - // Get a copy of the rewritten buffer from the Rewriter. - llvm::raw_string_ostream StringStream(ResultBuf); - I->second.write(StringStream); - - // Cause results to be written to ResultBuf. - StringStream.str(); - - // FIXME: Use move semantics to avoid copies of the buffer contents if - // benchmarking shows the copies are expensive, especially for large source - // files. - - 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. - - // Create HeaderOverride if not already existing - HeaderOverride &Header = Overrides.Headers[Entry->getName()]; - if (Header.FileName.empty()) - Header.FileName = Entry->getName(); - - Header.FileOverride = ResultBuf; - } -} - Transform::Transform(llvm::StringRef Name, const TransformOptions &Options) - : Name(Name), GlobalOptions(Options), Overrides(0), - RewriterOwner(new RewriterManager) { + : Name(Name), GlobalOptions(Options), Overrides(0) { Reset(); } @@ -192,12 +101,9 @@ bool Transform::handleBeginSource(CompilerInstance &CI, StringRef Filename) { CurrentSource = Filename.str(); - RewriterOwner->prepare(CI.getFileManager()); FileOverrides::const_iterator I = Overrides->find(CurrentSource); - if (I != Overrides->end()) { - I->second.applyOverrides(CI.getSourceManager()); - RewriterOwner->applyOverrides(I->second); - } + if (I != Overrides->end()) + I->second->applyOverrides(CI.getSourceManager()); Replace.clear(); @@ -210,16 +116,8 @@ bool Transform::handleBeginSource(CompilerInstance &CI, StringRef Filename) { void Transform::handleEndSource() { 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); + SourceOverrides &SO = Overrides->getOrCreate(CurrentSource); + SO.applyReplacements(getReplacements()); } if (Options().EnableTiming) diff --git a/clang-tools-extra/cpp11-migrate/Core/Transform.h b/clang-tools-extra/cpp11-migrate/Core/Transform.h index 26462db7fe1..1f4403c26b9 100644 --- a/clang-tools-extra/cpp11-migrate/Core/Transform.h +++ b/clang-tools-extra/cpp11-migrate/Core/Transform.h @@ -17,7 +17,6 @@ #define CPP11_MIGRATE_TRANSFORM_H #include "Core/IncludeExcludeInfo.h" -#include "Core/FileOverrides.h" #include "clang/Tooling/Refactoring.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/Support/CommandLine.h" @@ -51,7 +50,7 @@ class MatchFinder; } // namespace ast_matchers } // namespace clang -class RewriterManager; +class FileOverrides; /// \brief To group transforms' options together when printing the help. extern llvm::cl::OptionCategory TransformsOptionsCategory; @@ -216,7 +215,6 @@ private: const TransformOptions &GlobalOptions; FileOverrides *Overrides; clang::tooling::Replacements Replace; - llvm::OwningPtr<RewriterManager> RewriterOwner; std::string CurrentSource; TimingVec Timings; unsigned AcceptedChanges; diff --git a/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp b/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp index 2ebd92d2ff6..4153d9a6403 100644 --- a/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp +++ b/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp @@ -15,10 +15,11 @@ /// //===----------------------------------------------------------------------===// +#include "Core/FileOverrides.h" +#include "Core/PerfSupport.h" #include "Core/SyntaxCheck.h" -#include "Core/Transforms.h" #include "Core/Transform.h" -#include "Core/PerfSupport.h" +#include "Core/Transforms.h" #include "LoopConvert/LoopConvert.h" #include "UseNullptr/UseNullptr.h" #include "UseAuto/UseAuto.h" @@ -30,6 +31,7 @@ #include "llvm/Support/Signals.h" namespace cl = llvm::cl; +using namespace clang; using namespace clang::tooling; TransformOptions GlobalOptions; @@ -190,25 +192,28 @@ int main(int argc, const char **argv) { for (FileOverrides::const_iterator I = FileStates.begin(), E = FileStates.end(); I != E; ++I) { - if (I->second.isSourceOverriden()) { + const SourceOverrides &Overrides = *I->second; + if (Overrides.isSourceOverriden()) { std::string ErrorInfo; - llvm::raw_fd_ostream FileStream(I->first.c_str(), ErrorInfo, + std::string MainFileName = I->getKey(); + llvm::raw_fd_ostream FileStream(MainFileName.c_str(), ErrorInfo, llvm::raw_fd_ostream::F_Binary); - FileStream << I->second.MainFileOverride; + FileStream << Overrides.getMainFileContent(); } - // FIXME: The Migrator shouldn't be responsible for writing headers - // to disk. Instead, it should write replacement info and another tool - // should take all replacement info for a header from possibly many other - // migration processes and merge it into a final form. For now, the - // updated header is written to disk for testing purposes. - for (HeaderOverrides::const_iterator HeaderI = I->second.Headers.begin(), - HeaderE = I->second.Headers.end(); + // FIXME: The Migrator shouldn't be responsible for writing headers to disk. + // Instead, it should write replacement info and another tool should take + // all replacement info for a header from possibly many other migration + // processes and merge it into a final form. For now, the updated header is + // written to disk for testing purposes. + for (HeaderOverrides::const_iterator HeaderI = Overrides.headers_begin(), + HeaderE = Overrides.headers_end(); HeaderI != HeaderE; ++HeaderI) { 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, + std::string HeaderFileName = HeaderI->getKey(); + llvm::raw_fd_ostream HeaderStream(HeaderFileName.c_str(), ErrorInfo, llvm::raw_fd_ostream::F_Binary); HeaderStream << HeaderI->second.FileOverride; } diff --git a/clang-tools-extra/unittests/cpp11-migrate/CMakeLists.txt b/clang-tools-extra/unittests/cpp11-migrate/CMakeLists.txt index 8cdf386f17b..75bf35e9f14 100644 --- a/clang-tools-extra/unittests/cpp11-migrate/CMakeLists.txt +++ b/clang-tools-extra/unittests/cpp11-migrate/CMakeLists.txt @@ -7,10 +7,12 @@ get_filename_component(CPP11_MIGRATE_SOURCE_DIR include_directories(${CPP11_MIGRATE_SOURCE_DIR})
add_extra_unittest(Cpp11MigrateTests
- TransformTest.cpp
+ FileOverridesTest.cpp
IncludeExcludeTest.cpp
PerfSupportTest.cpp
- UniqueHeaderNameTest.cpp)
+ TransformTest.cpp
+ UniqueHeaderNameTest.cpp
+ )
target_link_libraries(Cpp11MigrateTests
migrateCore
diff --git a/clang-tools-extra/unittests/cpp11-migrate/FileOverridesTest.cpp b/clang-tools-extra/unittests/cpp11-migrate/FileOverridesTest.cpp new file mode 100644 index 00000000000..cc1f30155c5 --- /dev/null +++ b/clang-tools-extra/unittests/cpp11-migrate/FileOverridesTest.cpp @@ -0,0 +1,56 @@ +//===- cpp11-migrate/FileOverridesTest.cpp - File overrides unit tests ----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "Core/FileOverrides.h" +#include "gtest/gtest.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticOptions.h" +#include "clang/Basic/FileManager.h" +#include "clang/Basic/SourceManager.h" + +using namespace llvm; +using namespace clang; + +TEST(SourceOverridesTest, Interface) { + llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts( + new DiagnosticOptions()); + DiagnosticsEngine Diagnostics( + llvm::IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), + DiagOpts.getPtr()); + FileManager Files((FileSystemOptions())); + SourceManager SM(Diagnostics, Files); + StringRef FileName = "<text>"; + StringRef Code = + "std::vector<such_a_long_name_for_a_type>::const_iterator long_type =\n" + " vec.begin();\n" + "int x;"; // to test that it's not the whole file that is reformatted + llvm::MemoryBuffer *Buf = llvm::MemoryBuffer::getMemBuffer(Code, FileName); + const clang::FileEntry *Entry = + Files.getVirtualFile(FileName, Buf->getBufferSize(), 0); + SM.overrideFileContents(Entry, Buf); + + SourceOverrides Overrides(FileName); + + EXPECT_EQ(FileName, Overrides.getMainFileName()); + EXPECT_FALSE(Overrides.isSourceOverriden()); + + tooling::Replacements Replaces; + unsigned ReplacementLength = + strlen("std::vector<such_a_long_name_for_a_type>::const_iterator"); + Replaces.insert( + tooling::Replacement(FileName, 0, ReplacementLength, "auto")); + Overrides.applyReplacements(Replaces, SM); + EXPECT_TRUE(Overrides.isSourceOverriden()); + + std::string ExpectedContent = "auto long_type =\n" + " vec.begin();\n" + "int x;"; + + EXPECT_EQ(ExpectedContent, Overrides.getMainFileContent()); +} diff --git a/clang-tools-extra/unittests/cpp11-migrate/TransformTest.cpp b/clang-tools-extra/unittests/cpp11-migrate/TransformTest.cpp index dd794f2eb15..555237e073c 100644 --- a/clang-tools-extra/unittests/cpp11-migrate/TransformTest.cpp +++ b/clang-tools-extra/unittests/cpp11-migrate/TransformTest.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "gtest/gtest.h" +#include "Core/FileOverrides.h" #include "Core/Transform.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/DeclGroup.h" |