diff options
Diffstat (limited to 'clang-tools-extra/cpp11-migrate/Core/FileOverrides.cpp')
-rw-r--r-- | clang-tools-extra/cpp11-migrate/Core/FileOverrides.cpp | 227 |
1 files changed, 60 insertions, 167 deletions
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; +} |