diff options
Diffstat (limited to 'clang-tools-extra/cpp11-migrate/Core')
20 files changed, 0 insertions, 2350 deletions
diff --git a/clang-tools-extra/cpp11-migrate/Core/CMakeLists.txt b/clang-tools-extra/cpp11-migrate/Core/CMakeLists.txt deleted file mode 100644 index 0ac52230e6a..00000000000 --- a/clang-tools-extra/cpp11-migrate/Core/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -set(LLVM_LINK_COMPONENTS support) - -add_clang_library(migrateCore - FileOverrides.cpp - SyntaxCheck.cpp - Transforms.cpp - Transform.cpp - IncludeExcludeInfo.cpp - PerfSupport.cpp - Reformatting.cpp - IncludeDirectives.cpp - ) -target_link_libraries(migrateCore - clangFormat - clangTooling - clangBasic - clangASTMatchers - clangRewriteFrontend - ) diff --git a/clang-tools-extra/cpp11-migrate/Core/CustomMatchers.h b/clang-tools-extra/cpp11-migrate/Core/CustomMatchers.h deleted file mode 100644 index 9af04977996..00000000000 --- a/clang-tools-extra/cpp11-migrate/Core/CustomMatchers.h +++ /dev/null @@ -1,59 +0,0 @@ -//===-- Core/CustomMatchers.h - Perf measurement helpers -----------*- 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 custom matchers to be used by different -/// transforms that requier the same matchers. -/// -//===----------------------------------------------------------------------===// - -#ifndef CPP11_MIGRATE_CUSTOMMATCHERS_H -#define CPP11_MIGRATE_CUSTOMMATCHERS_H - -#include "clang/ASTMatchers/ASTMatchers.h" - -namespace clang { -namespace ast_matchers { - -/// \brief Matches declarations whose declaration context is the C++ standard -/// library namespace \c std. -/// -/// Note that inline namespaces are silently ignored during the lookup since -/// both libstdc++ and libc++ are known to use them for versioning purposes. -/// -/// Given -/// \code -/// namespace ns { -/// struct my_type {}; -/// using namespace std; -/// } -/// -/// using std::vector; -/// using ns::my_type; -/// using ns::list; -/// \endcode -/// usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(isFromStdNamespace()))) -/// matches "using std::vector" and "using ns::list". -AST_MATCHER(Decl, isFromStdNamespace) { - const DeclContext *D = Node.getDeclContext(); - - while (D->isInlineNamespace()) - D = D->getParent(); - - if (!D->isNamespace() || !D->getParent()->isTranslationUnit()) - return false; - - const IdentifierInfo *Info = cast<NamespaceDecl>(D)->getIdentifier(); - - return Info && Info->isStr("std"); -} -} // namespace ast_matchers -} // namespace clang - -#endif // CPP11_MIGRATE_CUSTOMMATCHERS_H diff --git a/clang-tools-extra/cpp11-migrate/Core/FileOverrides.cpp b/clang-tools-extra/cpp11-migrate/Core/FileOverrides.cpp deleted file mode 100644 index 7ab7e91c30c..00000000000 --- a/clang-tools-extra/cpp11-migrate/Core/FileOverrides.cpp +++ /dev/null @@ -1,198 +0,0 @@ -//===-- Core/FileOverrides.cpp --------------------------------------------===// -// -// 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. -/// -//===----------------------------------------------------------------------===// - -#include "Core/FileOverrides.h" -#include "clang/Basic/Diagnostic.h" -#include "clang/Basic/DiagnosticOptions.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Rewrite/Core/Rewriter.h" -#include "clang/Tooling/Tooling.h" -#include "clang/Tooling/ReplacementsYaml.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/system_error.h" -#include <algorithm> - -using namespace clang; -using namespace clang::tooling; - -bool generateReplacementsFileName(const llvm::StringRef MainSourceFile, - llvm::SmallVectorImpl<char> &Result, - llvm::SmallVectorImpl<char> &Error) { - using namespace llvm::sys; - - Error.clear(); - if (llvm::error_code EC = fs::createUniqueFile( - MainSourceFile + "_%%_%%_%%_%%_%%_%%.yaml", Result)) { - Error.append(EC.message().begin(), EC.message().end()); - return false; - } - - return true; -} - -namespace { - -/// \brief Comparator to be able to order tooling::Range based on their offset. -bool rangeLess(clang::tooling::Range A, clang::tooling::Range B) { - if (A.getOffset() == B.getOffset()) - return A.getLength() < B.getLength(); - return A.getOffset() < B.getOffset(); -} - -/// \brief Functor that returns the given range without its overlaps with the -/// replacement given in the constructor. -struct RangeReplacedAdjuster { - RangeReplacedAdjuster(const tooling::Replacement &Replace) - : Replace(Replace.getOffset(), Replace.getLength()), - ReplaceNewSize(Replace.getReplacementText().size()) {} - - tooling::Range operator()(clang::tooling::Range Range) const { - if (!Range.overlapsWith(Replace)) - return Range; - // range inside replacement -> make the range length null - if (Replace.contains(Range)) - return tooling::Range(Range.getOffset(), 0); - // replacement inside range -> resize the range - if (Range.contains(Replace)) { - int Difference = ReplaceNewSize - Replace.getLength(); - return tooling::Range(Range.getOffset(), Range.getLength() + Difference); - } - // beginning of the range replaced -> truncate range beginning - if (Range.getOffset() > Replace.getOffset()) { - unsigned ReplaceEnd = Replace.getOffset() + Replace.getLength(); - unsigned RangeEnd = Range.getOffset() + Range.getLength(); - return tooling::Range(ReplaceEnd, RangeEnd - ReplaceEnd); - } - // end of the range replaced -> truncate range end - if (Range.getOffset() < Replace.getOffset()) - return tooling::Range(Range.getOffset(), - Replace.getOffset() - Range.getOffset()); - llvm_unreachable("conditions not handled properly"); - } - - const tooling::Range Replace; - const unsigned ReplaceNewSize; -}; - -} // end anonymous namespace - -void -ChangedRanges::adjustChangedRanges(const tooling::ReplacementsVec &Replaces) { - // first adjust existing ranges in case they overlap with the replacements - 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(), - RangeReplacedAdjuster(Replace)); - } - - // then shift existing ranges to reflect the new positions - for (RangeVec::iterator I = Ranges.begin(), E = Ranges.end(); I != E; ++I) { - unsigned ShiftedOffset = - tooling::shiftedCodePosition(Replaces, I->getOffset()); - *I = tooling::Range(ShiftedOffset, I->getLength()); - } - - // then generate the new ranges from the replacements - 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(); - - Ranges.push_back(tooling::Range(Offset, Length)); - } - - // cleanups unecessary ranges to finish - coalesceRanges(); -} - -void ChangedRanges::coalesceRanges() { - // sort the ranges by offset and then for each group of adjacent/overlapping - // ranges the first one in the group is extended to cover the whole group. - std::sort(Ranges.begin(), Ranges.end(), &rangeLess); - RangeVec::iterator FirstInGroup = Ranges.begin(); - assert(!Ranges.empty() && "unexpected empty vector"); - for (RangeVec::iterator I = Ranges.begin() + 1, E = Ranges.end(); I != E; - ++I) { - unsigned GroupEnd = FirstInGroup->getOffset() + FirstInGroup->getLength(); - - // no contact - if (I->getOffset() > GroupEnd) - FirstInGroup = I; - else { - unsigned GrpBegin = FirstInGroup->getOffset(); - unsigned GrpEnd = std::max(GroupEnd, I->getOffset() + I->getLength()); - *FirstInGroup = tooling::Range(GrpBegin, GrpEnd - GrpBegin); - } - } - - // remove the ranges that are covered by the first member of the group - Ranges.erase(std::unique(Ranges.begin(), Ranges.end(), - 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; -} diff --git a/clang-tools-extra/cpp11-migrate/Core/FileOverrides.h b/clang-tools-extra/cpp11-migrate/Core/FileOverrides.h deleted file mode 100644 index 8ed2914f0d2..00000000000 --- a/clang-tools-extra/cpp11-migrate/Core/FileOverrides.h +++ /dev/null @@ -1,129 +0,0 @@ -//===-- 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 "Core/Refactoring.h" -#include "clang-apply-replacements/Tooling/ApplyReplacements.h" -#include "clang/Tooling/ReplacementsYaml.h" -#include "llvm/ADT/StringMap.h" - -// Forward Declarations -namespace llvm { -template <typename T> -class SmallVectorImpl; -} // namespace llvm -namespace clang { -class SourceManager; -class Rewriter; -} // namespace clang - -/// \brief Class encapsulating a list of \c tooling::Range with some -/// convenience methods. -/// -/// The ranges stored are used to keep track of the overriden parts of a file. -class ChangedRanges { - typedef std::vector<clang::tooling::Range> RangeVec; - -public: - typedef RangeVec::const_iterator const_iterator; - - /// \brief Create new ranges from the replacements and adjust existing one - /// to remove replaced parts. - /// - /// Note that all replacements should come from the same file. - void adjustChangedRanges(const clang::tooling::ReplacementsVec &Replaces); - - /// \brief Iterators. - /// \{ - const_iterator begin() const { return Ranges.begin(); } - const_iterator end() const { return Ranges.end(); } - /// \} - -private: - void coalesceRanges(); - - RangeVec Ranges; -}; - -/// \brief Maintains current state of transformed files and tracks source ranges -/// where changes have been made. -class FileOverrides { -public: - /// \brief Maps file names to file contents. - typedef llvm::StringMap<std::string> FileStateMap; - - /// \brief Maps file names to change tracking info for a file. - typedef llvm::StringMap<ChangedRanges> ChangeMap; - - - /// \brief Override file contents seen by \c SM for all files stored by this - /// object. - void applyOverrides(clang::SourceManager &SM) const; - - /// \brief Update change tracking information based on replacements stored in - /// \c Replaces. - void - adjustChangedRanges(const clang::replace::FileToReplacementsMap &Replaces); - - /// \brief Accessor for change tracking information. - const ChangeMap &getChangedRanges() const { - return ChangeTracking; - } - - /// \brief Coalesce changes stored in \c Rewrites and replace file contents - /// overrides stored in this object. - /// - /// \param Rewrites Rewriter containing changes to files. - void updateState(const clang::Rewriter &Rewrites); - - /// \brief Accessor for current file state. - const FileStateMap &getState() const { return FileStates; } - - /// \brief Write all file contents overrides to disk. - /// - /// \param Diagnostics DiagnosticsEngine for error output. - /// - /// \returns \li true if all files with overridden file contents were written - /// to disk successfully. - /// \li false if any failure occurred. - bool writeToDisk(clang::DiagnosticsEngine &Diagnostics) const; - -private: - FileStateMap FileStates; - ChangeMap ChangeTracking; -}; - -/// \brief Generate a unique filename to store the replacements. -/// -/// Generates a unique filename in the same directory as \c MainSourceFile. The -/// filename is generated following this pattern: -/// -/// MainSourceFile_%%_%%_%%_%%_%%_%%.yaml -/// -/// where all '%' will be replaced by a randomly chosen hex number. -/// -/// \param[in] MainSourceFile Full path to the source file. -/// \param[out] Result The resulting unique filename in the same directory as -/// the \c MainSourceFile. -/// \param[out] Error If an error occurs a description of that error is -/// placed in this string. -/// \returns true on success, false if a unique file name could not be created. -bool generateReplacementsFileName(const llvm::StringRef MainSourceFile, - llvm::SmallVectorImpl<char> &Result, - llvm::SmallVectorImpl<char> &Error); - -#endif // CPP11_MIGRATE_FILE_OVERRIDES_H diff --git a/clang-tools-extra/cpp11-migrate/Core/IncludeDirectives.cpp b/clang-tools-extra/cpp11-migrate/Core/IncludeDirectives.cpp deleted file mode 100644 index f240950790b..00000000000 --- a/clang-tools-extra/cpp11-migrate/Core/IncludeDirectives.cpp +++ /dev/null @@ -1,474 +0,0 @@ -//===-- Core/IncludeDirectives.cpp - Include directives handling ----------===// -// -// 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 defines the IncludeDirectives class that helps with -/// detecting and modifying \#include directives. -/// -//===----------------------------------------------------------------------===// - -#include "IncludeDirectives.h" -#include "clang/Basic/CharInfo.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Lex/HeaderSearch.h" -#include "clang/Lex/Preprocessor.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/StringSwitch.h" -#include <stack> - -using namespace clang; -using namespace clang::tooling; -using llvm::StringRef; - -/// \brief PPCallbacks that fills-in the include information in the given -/// \c IncludeDirectives. -class IncludeDirectivesPPCallback : public clang::PPCallbacks { - // Struct helping the detection of header guards in the various callbacks - struct GuardDetection { - GuardDetection(FileID FID) - : FID(FID), Count(0), TheMacro(0), CountAtEndif(0) {} - - FileID FID; - // count for relevant preprocessor directives - unsigned Count; - // the macro that is tested in the top most ifndef for the header guard - // (e.g: GUARD_H) - const IdentifierInfo *TheMacro; - // the hash locations of #ifndef, #define, #endif - SourceLocation IfndefLoc, DefineLoc, EndifLoc; - // the value of Count once the #endif is reached - unsigned CountAtEndif; - - /// \brief Check that with all the information gathered if this is a - /// potential header guard. - /// - /// Meaning a top-most \#ifndef has been found, followed by a define and the - /// last preprocessor directive was the terminating \#endif. - /// - /// FIXME: accept the \#if !defined identifier form too. - bool isPotentialHeaderGuard() const { - return Count == CountAtEndif && DefineLoc.isValid(); - } - }; - -public: - IncludeDirectivesPPCallback(IncludeDirectives *Self) : Self(Self), Guard(0) {} - -private: - virtual ~IncludeDirectivesPPCallback() {} - void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, - StringRef FileName, bool IsAngled, - CharSourceRange FilenameRange, const FileEntry *File, - StringRef SearchPath, StringRef RelativePath, - const Module *Imported) LLVM_OVERRIDE { - SourceManager &SM = Self->Sources; - const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(HashLoc)); - assert(FE && "Valid file expected."); - - IncludeDirectives::Entry E(HashLoc, File, IsAngled); - Self->FileToEntries[FE].push_back(E); - Self->IncludeAsWrittenToLocationsMap[FileName].push_back(HashLoc); - } - - // Keep track of the current file in the stack - virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason, - SrcMgr::CharacteristicKind FileType, - FileID PrevFID) { - SourceManager &SM = Self->Sources; - switch (Reason) { - case EnterFile: - Files.push(GuardDetection(SM.getFileID(Loc))); - Guard = &Files.top(); - break; - - case ExitFile: - if (Guard->isPotentialHeaderGuard()) - handlePotentialHeaderGuard(*Guard); - Files.pop(); - Guard = &Files.top(); - break; - - default: - break; - } - } - - /// \brief Mark this header as guarded in the IncludeDirectives if it's a - /// proper header guard. - void handlePotentialHeaderGuard(const GuardDetection &Guard) { - SourceManager &SM = Self->Sources; - const FileEntry *File = SM.getFileEntryForID(Guard.FID); - const LangOptions &LangOpts = Self->CI.getLangOpts(); - - // Null file can happen for the <built-in> buffer for example. They - // shouldn't have header guards though... - if (!File) - return; - - // The #ifndef should be the next thing after the preamble. We aren't - // checking for equality because it can also be part of the preamble if the - // preamble is the whole file. - unsigned Preamble = - Lexer::ComputePreamble(SM.getBuffer(Guard.FID), LangOpts).first; - unsigned IfndefOffset = SM.getFileOffset(Guard.IfndefLoc); - if (IfndefOffset > (Preamble + 1)) - return; - - // No code is allowed in the code remaining after the #endif. - const llvm::MemoryBuffer *Buffer = SM.getBuffer(Guard.FID); - Lexer Lex(SM.getLocForStartOfFile(Guard.FID), LangOpts, - Buffer->getBufferStart(), - Buffer->getBufferStart() + SM.getFileOffset(Guard.EndifLoc), - Buffer->getBufferEnd()); - - // Find the first newline not part of a multi-line comment. - Token Tok; - Lex.LexFromRawLexer(Tok); // skip endif - Lex.LexFromRawLexer(Tok); - - // Not a proper header guard, the remainder of the file contains something - // else than comments or whitespaces. - if (Tok.isNot(tok::eof)) - return; - - // Add to the location of the define to the IncludeDirectives for this file. - Self->HeaderToGuard[File] = Guard.DefineLoc; - } - - virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok, - const MacroDirective *MD) { - Guard->Count++; - - // If this #ifndef is the top-most directive and the symbol isn't defined - // store those information in the guard detection, the next step will be to - // check for the define. - if (Guard->Count == 1 && MD == 0) { - IdentifierInfo *MII = MacroNameTok.getIdentifierInfo(); - - if (MII->hasMacroDefinition()) - return; - Guard->IfndefLoc = Loc; - Guard->TheMacro = MII; - } - } - - virtual void MacroDefined(const Token &MacroNameTok, - const MacroDirective *MD) { - Guard->Count++; - - // If this #define is the second directive of the file and the symbol - // defined is the same as the one checked in the #ifndef then store the - // information about this define. - if (Guard->Count == 2 && Guard->TheMacro != 0) { - IdentifierInfo *MII = MacroNameTok.getIdentifierInfo(); - - // macro unrelated to the ifndef, doesn't look like a proper header guard - if (MII->getName() != Guard->TheMacro->getName()) - return; - - Guard->DefineLoc = MacroNameTok.getLocation(); - } - } - - virtual void Endif(SourceLocation Loc, SourceLocation IfLoc) { - Guard->Count++; - - // If it's the #endif corresponding to the top-most #ifndef - if (Self->Sources.getDecomposedLoc(Guard->IfndefLoc) != - Self->Sources.getDecomposedLoc(IfLoc)) - return; - - // And that the top-most #ifndef was followed by the right #define - if (Guard->DefineLoc.isInvalid()) - return; - - // Then save the information about this #endif. Once the file is exited we - // will check if it was the final preprocessor directive. - Guard->CountAtEndif = Guard->Count; - Guard->EndifLoc = Loc; - } - - virtual void MacroExpands(const Token &, const MacroDirective *, SourceRange, - const MacroArgs *) { - Guard->Count++; - } - virtual void MacroUndefined(const Token &, const MacroDirective *) { - Guard->Count++; - } - virtual void Defined(const Token &, const MacroDirective *, SourceRange) { - Guard->Count++; - } - virtual void If(SourceLocation, SourceRange, bool) { Guard->Count++; } - virtual void Elif(SourceLocation, SourceRange, bool, SourceLocation) { - Guard->Count++; - } - virtual void Ifdef(SourceLocation, const Token &, const MacroDirective *) { - Guard->Count++; - } - virtual void Else(SourceLocation, SourceLocation) { Guard->Count++; } - - IncludeDirectives *Self; - // keep track of the guard info through the include stack - std::stack<GuardDetection> Files; - // convenience field pointing to Files.top().second - GuardDetection *Guard; -}; - -// Flags that describes where to insert newlines. -enum NewLineFlags { - // Prepend a newline at the beginning of the insertion. - NL_Prepend = 0x1, - - // Prepend another newline at the end of the insertion. - NL_PrependAnother = 0x2, - - // Add two newlines at the end of the insertion. - NL_AppendTwice = 0x4, - - // Convenience value to enable both \c NL_Prepend and \c NL_PrependAnother. - NL_PrependTwice = NL_Prepend | NL_PrependAnother -}; - -/// \brief Guess the end-of-line sequence used in the given FileID. If the -/// sequence can't be guessed return an Unix-style newline. -static StringRef guessEOL(SourceManager &SM, FileID ID) { - StringRef Content = SM.getBufferData(ID); - StringRef Buffer = Content.substr(Content.find_first_of("\r\n")); - - return llvm::StringSwitch<StringRef>(Buffer) - .StartsWith("\r\n", "\r\n") - .StartsWith("\n\r", "\n\r") - .StartsWith("\r", "\r") - .Default("\n"); -} - -/// \brief Find the end of the end of the directive, either the beginning of a -/// newline or the end of file. -// -// \return The offset into the file where the directive ends along with a -// boolean value indicating whether the directive ends because the end of file -// was reached or not. -static std::pair<unsigned, bool> findDirectiveEnd(SourceLocation HashLoc, - SourceManager &SM, - const LangOptions &LangOpts) { - FileID FID = SM.getFileID(HashLoc); - unsigned Offset = SM.getFileOffset(HashLoc); - StringRef Content = SM.getBufferData(FID); - Lexer Lex(SM.getLocForStartOfFile(FID), LangOpts, Content.begin(), - Content.begin() + Offset, Content.end()); - Lex.SetCommentRetentionState(true); - Token Tok; - - // This loop look for the newline after our directive but avoids the ones part - // of a multi-line comments: - // - // #include <foo> /* long \n comment */\n - // ~~ no ~~ yes - for (;;) { - // find the beginning of the end-of-line sequence - StringRef::size_type EOLOffset = Content.find_first_of("\r\n", Offset); - // ends because EOF was reached - if (EOLOffset == StringRef::npos) - return std::make_pair(Content.size(), true); - - // find the token that contains our end-of-line - unsigned TokEnd = 0; - do { - Lex.LexFromRawLexer(Tok); - TokEnd = SM.getFileOffset(Tok.getLocation()) + Tok.getLength(); - - // happens when the whitespaces are eaten after a multiline comment - if (Tok.is(tok::eof)) - return std::make_pair(EOLOffset, false); - } while (TokEnd < EOLOffset); - - // the end-of-line is not part of a multi-line comment, return its location - if (Tok.isNot(tok::comment)) - return std::make_pair(EOLOffset, false); - - // for the next search to start after the end of this token - Offset = TokEnd; - } -} - -IncludeDirectives::IncludeDirectives(clang::CompilerInstance &CI) - : CI(CI), Sources(CI.getSourceManager()) { - // addPPCallbacks takes ownership of the callback - CI.getPreprocessor().addPPCallbacks(new IncludeDirectivesPPCallback(this)); -} - -bool IncludeDirectives::lookForInclude(const FileEntry *File, - const LocationVec &IncludeLocs, - SeenFilesSet &Seen) const { - // mark this file as visited - Seen.insert(File); - - // First check if included directly in this file - for (LocationVec::const_iterator I = IncludeLocs.begin(), - E = IncludeLocs.end(); - I != E; ++I) - if (Sources.getFileEntryForID(Sources.getFileID(*I)) == File) - return true; - - // Otherwise look recursively all the included files - FileToEntriesMap::const_iterator EntriesIt = FileToEntries.find(File); - if (EntriesIt == FileToEntries.end()) - return false; - for (EntryVec::const_iterator I = EntriesIt->second.begin(), - E = EntriesIt->second.end(); - I != E; ++I) { - // skip if this header has already been checked before - if (Seen.count(I->getIncludedFile())) - continue; - if (lookForInclude(I->getIncludedFile(), IncludeLocs, Seen)) - return true; - } - return false; -} - -bool IncludeDirectives::hasInclude(const FileEntry *File, - StringRef Include) const { - llvm::StringMap<LocationVec>::const_iterator It = - IncludeAsWrittenToLocationsMap.find(Include); - - // Include isn't included in any file - if (It == IncludeAsWrittenToLocationsMap.end()) - return false; - - SeenFilesSet Seen; - return lookForInclude(File, It->getValue(), Seen); -} - -Replacement IncludeDirectives::addAngledInclude(const clang::FileEntry *File, - llvm::StringRef Include) { - FileID FID = Sources.translateFile(File); - assert(!FID.isInvalid() && "Invalid file entry given!"); - - if (hasInclude(File, Include)) - return Replacement(); - - unsigned Offset, NLFlags; - llvm::tie(Offset, NLFlags) = angledIncludeInsertionOffset(FID); - - StringRef EOL = guessEOL(Sources, FID); - llvm::SmallString<32> InsertionText; - if (NLFlags & NL_Prepend) - InsertionText += EOL; - if (NLFlags & NL_PrependAnother) - InsertionText += EOL; - InsertionText += "#include <"; - InsertionText += Include; - InsertionText += ">"; - if (NLFlags & NL_AppendTwice) { - InsertionText += EOL; - InsertionText += EOL; - } - return Replacement(File->getName(), Offset, 0, InsertionText); -} - -Replacement IncludeDirectives::addAngledInclude(llvm::StringRef File, - llvm::StringRef Include) { - const FileEntry *Entry = Sources.getFileManager().getFile(File); - assert(Entry && "Invalid file given!"); - return addAngledInclude(Entry, Include); -} - -std::pair<unsigned, unsigned> -IncludeDirectives::findFileHeaderEndOffset(FileID FID) const { - unsigned NLFlags = NL_Prepend; - StringRef Content = Sources.getBufferData(FID); - Lexer Lex(Sources.getLocForStartOfFile(FID), CI.getLangOpts(), - Content.begin(), Content.begin(), Content.end()); - Lex.SetCommentRetentionState(true); - Lex.SetKeepWhitespaceMode(true); - - // find the first newline not part of a multi-line comment - Token Tok; - do { - Lex.LexFromRawLexer(Tok); - unsigned Offset = Sources.getFileOffset(Tok.getLocation()); - // allow one newline between the comments - if (Tok.is(tok::unknown) && isWhitespace(Content[Offset])) { - StringRef Whitespaces(Content.substr(Offset, Tok.getLength())); - if (Whitespaces.count('\n') == 1 || Whitespaces.count('\r') == 1) - Lex.LexFromRawLexer(Tok); - else { - // add an empty line to separate the file header and the inclusion - NLFlags = NL_PrependTwice; - } - } - } while (Tok.is(tok::comment)); - - // apparently there is no header, insertion point is the beginning of the file - if (Tok.isNot(tok::unknown)) - return std::make_pair(0, NL_AppendTwice); - return std::make_pair(Sources.getFileOffset(Tok.getLocation()), NLFlags); -} - -SourceLocation -IncludeDirectives::angledIncludeHintLoc(FileID FID) const { - FileToEntriesMap::const_iterator EntriesIt = - FileToEntries.find(Sources.getFileEntryForID(FID)); - - if (EntriesIt == FileToEntries.end()) - return SourceLocation(); - - HeaderSearch &HeaderInfo = CI.getPreprocessor().getHeaderSearchInfo(); - const EntryVec &Entries = EntriesIt->second; - EntryVec::const_reverse_iterator QuotedCandidate = Entries.rend(); - for (EntryVec::const_reverse_iterator I = Entries.rbegin(), - E = Entries.rend(); - I != E; ++I) { - // Headers meant for multiple inclusion can potentially appears in the - // middle of the code thus making them a poor choice for an insertion point. - if (!HeaderInfo.isFileMultipleIncludeGuarded(I->getIncludedFile())) - continue; - - // return preferably the last angled include - if (I->isAngled()) - return I->getHashLocation(); - - // keep track of the last quoted include that is guarded - if (QuotedCandidate == Entries.rend()) - QuotedCandidate = I; - } - - if (QuotedCandidate == Entries.rend()) - return SourceLocation(); - - // return the last quoted-include if we couldn't find an angled one - return QuotedCandidate->getHashLocation(); -} - -std::pair<unsigned, unsigned> -IncludeDirectives::angledIncludeInsertionOffset(FileID FID) const { - SourceLocation Hint = angledIncludeHintLoc(FID); - unsigned NL_Flags = NL_Prepend; - - // If we can't find a similar include and we are in a header check if it's a - // guarded header. If so the hint will be the location of the #define from the - // guard. - if (Hint.isInvalid()) { - const FileEntry *File = Sources.getFileEntryForID(FID); - HeaderToGuardMap::const_iterator GuardIt = HeaderToGuard.find(File); - if (GuardIt != HeaderToGuard.end()) { - // get the hash location from the #define - Hint = GuardIt->second; - // we want a blank line between the #define and the #include - NL_Flags = NL_PrependTwice; - } - } - - // no hints, insertion is done after the file header - if (Hint.isInvalid()) - return findFileHeaderEndOffset(FID); - - unsigned Offset = findDirectiveEnd(Hint, Sources, CI.getLangOpts()).first; - return std::make_pair(Offset, NL_Flags); -} diff --git a/clang-tools-extra/cpp11-migrate/Core/IncludeDirectives.h b/clang-tools-extra/cpp11-migrate/Core/IncludeDirectives.h deleted file mode 100644 index c1c5a7acf77..00000000000 --- a/clang-tools-extra/cpp11-migrate/Core/IncludeDirectives.h +++ /dev/null @@ -1,141 +0,0 @@ -//===-- Core/IncludeDirectives.h - Include directives handling --*- 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 declares the IncludeDirectives class that helps with -/// detecting and modifying \#include directives. -/// -//===----------------------------------------------------------------------===// - -#ifndef CPP11_MIGRATE_INCLUDE_DIRECTIVES_H -#define CPP11_MIGRATE_INCLUDE_DIRECTIVES_H - -#include "clang/Basic/SourceLocation.h" -#include "clang/Tooling/Refactoring.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/ADT/SmallPtrSet.h" -#include <vector> - -namespace clang { -class Preprocessor; -} // namespace clang - -/// \brief Support for include directives handling. -/// -/// This class should be created with a \c clang::CompilerInstance before the -/// file is preprocessed in order to collect the inclusion information. It can -/// be queried as long as the compiler instance is valid. -class IncludeDirectives { -public: - IncludeDirectives(clang::CompilerInstance &CI); - - /// \brief Add an angled include to a the given file. - /// - /// \param File A file accessible by a SourceManager - /// \param Include The include file as it should be written in the code. - /// - /// \returns - /// \li A null Replacement (check using \c Replacement::isApplicable()), if - /// the \c Include is already visible from \c File. - /// \li Otherwise, a non-null Replacement that, when applied, inserts an - /// \c \#include into \c File. - clang::tooling::Replacement addAngledInclude(llvm::StringRef File, - llvm::StringRef Include); - clang::tooling::Replacement addAngledInclude(const clang::FileEntry *File, - llvm::StringRef Include); - - /// \brief Check if \p Include is included by \p File or any of the files - /// \p File includes. - bool hasInclude(const clang::FileEntry *File, llvm::StringRef Include) const; - -private: - friend class IncludeDirectivesPPCallback; - - /// \brief Contains information about an inclusion. - class Entry { - public: - Entry(clang::SourceLocation HashLoc, const clang::FileEntry *IncludedFile, - bool Angled) - : HashLoc(HashLoc), IncludedFile(IncludedFile), Angled(Angled) {} - - /// \brief The location of the '#'. - clang::SourceLocation getHashLocation() const { return HashLoc; } - - /// \brief The file included by this include directive. - const clang::FileEntry *getIncludedFile() const { return IncludedFile; } - - /// \brief \c true if the include use angle brackets, \c false otherwise - /// when using of quotes. - bool isAngled() const { return Angled; } - - private: - clang::SourceLocation HashLoc; - const clang::FileEntry *IncludedFile; - bool Angled; - }; - - // A list of entries. - typedef std::vector<Entry> EntryVec; - - // A list of source locations. - typedef std::vector<clang::SourceLocation> LocationVec; - - // Associates files to their includes. - typedef llvm::DenseMap<const clang::FileEntry *, EntryVec> FileToEntriesMap; - - // Associates headers to their include guards if any. The location is the - // location of the hash from the #define. - typedef llvm::DenseMap<const clang::FileEntry *, clang::SourceLocation> - HeaderToGuardMap; - - /// \brief Type used by \c lookForInclude() to keep track of the files that - /// have already been processed. - typedef llvm::SmallPtrSet<const clang::FileEntry *, 32> SeenFilesSet; - - /// \brief Recursively look if an include is included by \p File or any of the - /// headers \p File includes. - /// - /// \param File The file where to start the search. - /// \param IncludeLocs These are the hash locations of the \#include - /// directives we are looking for. - /// \param Seen Used to avoid visiting a same file more than once during the - /// recursion. - bool lookForInclude(const clang::FileEntry *File, - const LocationVec &IncludeLocs, SeenFilesSet &Seen) const; - - /// \brief Find the end of a file header and returns a pair (FileOffset, - /// NewLineFlags). - /// - /// Source files often contain a file header (copyright, license, explanation - /// of the file content). An \#include should preferrably be put after this. - std::pair<unsigned, unsigned> - findFileHeaderEndOffset(clang::FileID FID) const; - - /// \brief Finds the offset where an angled include should be added and - /// returns a pair (FileOffset, NewLineFlags). - std::pair<unsigned, unsigned> - angledIncludeInsertionOffset(clang::FileID FID) const; - - /// \brief Find the location of an include directive that can be used to - /// insert an inclusion after. - /// - /// If no such include exists returns a null SourceLocation. - clang::SourceLocation angledIncludeHintLoc(clang::FileID FID) const; - - clang::CompilerInstance &CI; - clang::SourceManager &Sources; - FileToEntriesMap FileToEntries; - // maps include filename as written in the source code to the source locations - // where it appears - llvm::StringMap<LocationVec> IncludeAsWrittenToLocationsMap; - HeaderToGuardMap HeaderToGuard; -}; - -#endif // CPP11_MIGRATE_INCLUDE_DIRECTIVES_H diff --git a/clang-tools-extra/cpp11-migrate/Core/IncludeExcludeInfo.cpp b/clang-tools-extra/cpp11-migrate/Core/IncludeExcludeInfo.cpp deleted file mode 100644 index e3f07c5f0d3..00000000000 --- a/clang-tools-extra/cpp11-migrate/Core/IncludeExcludeInfo.cpp +++ /dev/null @@ -1,169 +0,0 @@ -//===-- Core/IncludeExcludeInfo.cpp - IncludeExclude class impl -----------===// -// -// 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 the implementation of the IncludeExcludeInfo class -/// to handle the include and exclude command line options. -/// -//===----------------------------------------------------------------------===// - -#include "IncludeExcludeInfo.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/raw_ostream.h" - -using namespace llvm; - -/// A string type to represent paths. -typedef SmallString<64> PathString; - -namespace { -/// \brief Helper function to determine whether a file has the same path -/// prefix as \a Path. -/// -/// \a Path must be an absolute path. -bool fileHasPathPrefix(StringRef File, StringRef Path) { - // Converts File to its absolute path. - PathString AbsoluteFile = File; - sys::fs::make_absolute(AbsoluteFile); - - // Convert path strings to sys::path to iterate over each of its directories. - sys::path::const_iterator FileI = sys::path::begin(AbsoluteFile), - FileE = sys::path::end(AbsoluteFile), - PathI = sys::path::begin(Path), - PathE = sys::path::end(Path); - while (FileI != FileE && PathI != PathE) { - // If the strings aren't equal then the two paths aren't contained within - // each other. - bool IsSeparator = ((FileI->size() == 1) && (PathI->size() == 1) && - sys::path::is_separator((*FileI)[0]) && - sys::path::is_separator((*PathI)[0])); - if (!FileI->equals(*PathI) && !IsSeparator) - return false; - ++FileI; - ++PathI; - } - return true; -} - -/// \brief Helper function for removing relative operators from a given -/// path i.e. "..", ".". -/// \a Path must be a absolute path. -std::string removeRelativeOperators(StringRef Path) { - sys::path::const_iterator PathI = sys::path::begin(Path); - sys::path::const_iterator PathE = sys::path::end(Path); - SmallVector<StringRef, 16> PathT; - while (PathI != PathE) { - if (PathI->equals("..")) { - // Test if we have reached the root then Path is invalid. - if (PathT.empty()) - return ""; - PathT.pop_back(); - } else if (!PathI->equals(".")) - PathT.push_back(*PathI); - ++PathI; - } - // Rebuild the new path. - PathString NewPath; - for (SmallVectorImpl<StringRef>::iterator I = PathT.begin(), E = PathT.end(); - I != E; ++I) { - llvm::sys::path::append(NewPath, *I); - } - return NewPath.str(); -} - -/// \brief Helper function to tokenize a string of paths and populate -/// the vector. -error_code parseCLInput(StringRef Line, std::vector<std::string> &List, - StringRef Separator) { - SmallVector<StringRef, 32> Tokens; - Line.split(Tokens, Separator, /*MaxSplit=*/ -1, /*KeepEmpty=*/ false); - for (SmallVectorImpl<StringRef>::iterator I = Tokens.begin(), - E = Tokens.end(); - I != E; ++I) { - // Convert each path to its absolute path. - PathString Path = I->rtrim(); - if (error_code Err = sys::fs::make_absolute(Path)) - return Err; - // Remove relative operators from the path. - std::string AbsPath = removeRelativeOperators(Path); - // Add only non-empty paths to the list. - if (!AbsPath.empty()) - List.push_back(AbsPath); - else - llvm::errs() << "Unable to parse input path: " << *I << "\n"; - - llvm::errs() << "Parse: " <<List.back() << "\n"; - } - return error_code::success(); -} -} // end anonymous namespace - -error_code IncludeExcludeInfo::readListFromString(StringRef IncludeString, - StringRef ExcludeString) { - if (error_code Err = parseCLInput(IncludeString, IncludeList, - /*Separator=*/ ",")) - return Err; - if (error_code Err = parseCLInput(ExcludeString, ExcludeList, - /*Separator=*/ ",")) - return Err; - return error_code::success(); -} - -error_code IncludeExcludeInfo::readListFromFile(StringRef IncludeListFile, - StringRef ExcludeListFile) { - if (!IncludeListFile.empty()) { - OwningPtr<MemoryBuffer> FileBuf; - if (error_code Err = MemoryBuffer::getFile(IncludeListFile, FileBuf)) { - errs() << "Unable to read from include file.\n"; - return Err; - } - if (error_code Err = parseCLInput(FileBuf->getBuffer(), IncludeList, - /*Separator=*/ "\n")) - return Err; - } - if (!ExcludeListFile.empty()) { - OwningPtr<MemoryBuffer> FileBuf; - if (error_code Err = MemoryBuffer::getFile(ExcludeListFile, FileBuf)) { - errs() << "Unable to read from exclude file.\n"; - return Err; - } - if (error_code Err = parseCLInput(FileBuf->getBuffer(), ExcludeList, - /*Separator=*/ "\n")) - return Err; - } - return error_code::success(); -} - -bool IncludeExcludeInfo::isFileIncluded(StringRef FilePath) const { - bool InIncludeList = false; - - for (std::vector<std::string>::const_iterator I = IncludeList.begin(), - E = IncludeList.end(); - I != E; ++I) - if ((InIncludeList = fileHasPathPrefix(FilePath, *I))) - break; - - // If file is not in the list of included paths then it is not necessary - // to check the excluded path list. - if (!InIncludeList) - return false; - - for (std::vector<std::string>::const_iterator I = ExcludeList.begin(), - E = ExcludeList.end(); - I != E; ++I) - if (fileHasPathPrefix(FilePath, *I)) - return false; - - // If the file is in the included list but not in the excluded list, then - // it is safe to transform. - return true; -} diff --git a/clang-tools-extra/cpp11-migrate/Core/IncludeExcludeInfo.h b/clang-tools-extra/cpp11-migrate/Core/IncludeExcludeInfo.h deleted file mode 100644 index a5e73efae0f..00000000000 --- a/clang-tools-extra/cpp11-migrate/Core/IncludeExcludeInfo.h +++ /dev/null @@ -1,56 +0,0 @@ -//===-- Core/IncludeExcludeInfo.h - IncludeExclude class def'n --*- 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 the definition for the IncludeExcludeInfo class -/// to handle the include and exclude command line options. -/// -//===----------------------------------------------------------------------===// - -#ifndef CPP11_MIGRATE_INCLUDEEXCLUDEINFO_H -#define CPP11_MIGRATE_INCLUDEEXCLUDEINFO_H - -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/system_error.h" -#include <vector> - -/// \brief Class encapsulating the handling of include and exclude paths -/// provided by the user through command line options. -class IncludeExcludeInfo { -public: - /// \brief Read and parse a comma-seperated lists of paths from - /// \a IncludeString and \a ExcludeString. - /// - /// Returns error_code::success() on successful parse of the strings or - /// an error_code indicating the encountered error. - llvm::error_code readListFromString(llvm::StringRef IncludeString, - llvm::StringRef ExcludeString); - - /// \brief Read and parse the lists of paths from \a IncludeListFile - /// and \a ExcludeListFile. Each file should contain one path per line. - /// - /// Returns error_code::success() on successful read and parse of both files - /// or an error_code indicating the encountered error. - llvm::error_code readListFromFile(llvm::StringRef IncludeListFile, - llvm::StringRef ExcludeListFile); - - /// \brief Determine if the given path is in the list of include paths but - /// not in the list of exclude paths. - /// - /// \a FilePath shouldn't contain relative operators i.e. ".." or "." since - /// Path comes from the include/exclude list of paths in which relative - /// operators were removed. - bool isFileIncluded(llvm::StringRef FilePath) const; - -private: - std::vector<std::string> IncludeList; - std::vector<std::string> ExcludeList; -}; - -#endif // CPP11_MIGRATE_INCLUDEEXCLUDEINFO_H diff --git a/clang-tools-extra/cpp11-migrate/Core/Makefile b/clang-tools-extra/cpp11-migrate/Core/Makefile deleted file mode 100644 index e60e11364f6..00000000000 --- a/clang-tools-extra/cpp11-migrate/Core/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -##===- cpp11-migrate/Core/Makefile -------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -CLANG_LEVEL := ../../../.. -LIBRARYNAME := migrateCore - -include $(CLANG_LEVEL)/Makefile - -CPP.Flags += -I$(PROJ_SRC_DIR)/.. -I$(PROJ_SRC_DIR)/../../clang-apply-replacements/include diff --git a/clang-tools-extra/cpp11-migrate/Core/PerfSupport.cpp b/clang-tools-extra/cpp11-migrate/Core/PerfSupport.cpp deleted file mode 100644 index e074bd123ef..00000000000 --- a/clang-tools-extra/cpp11-migrate/Core/PerfSupport.cpp +++ /dev/null @@ -1,101 +0,0 @@ -//===-- Core/PerfSupport.cpp - Perf measurement helpers -------------------===// -// -// 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 implementations for performance measuring helpers. -/// -//===----------------------------------------------------------------------===// - -#include "PerfSupport.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Format.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/Process.h" -#include "llvm/Support/Path.h" - -void collectSourcePerfData(const Transform &T, SourcePerfData &Data) { - for (Transform::TimingVec::const_iterator I = T.timing_begin(), - E = T.timing_end(); - I != E; ++I) { - SourcePerfData::iterator DataI = Data.insert( - SourcePerfData::value_type(I->first, std::vector<PerfItem>())).first; - DataI->second - .push_back(PerfItem(T.getName(), I->second.getProcessTime() * 1000.0)); - } -} - -void writePerfDataJSON( - const llvm::StringRef DirectoryName, - const SourcePerfData &TimingResults) { - // Create directory path if it doesn't exist - llvm::sys::fs::create_directories(DirectoryName); - - // Get PID and current time. - // FIXME: id_type on Windows is NOT a process id despite the function name. - // Need to call GetProcessId() providing it what get_id() returns. For now - // disabling PID-based file names until this is fixed properly. - //llvm::sys::self_process *SP = llvm::sys::process::get_self(); - //id_type Pid = SP->get_id(); - unsigned Pid = 0; - llvm::TimeRecord T = llvm::TimeRecord::getCurrentTime(); - - std::string FileName; - llvm::raw_string_ostream SS(FileName); - SS << DirectoryName << "/" << static_cast<int>(T.getWallTime()) << "_" << Pid - << ".json"; - - std::string ErrorInfo; - llvm::raw_fd_ostream FileStream(SS.str().c_str(), ErrorInfo); - FileStream << "{\n"; - FileStream << " \"Sources\" : [\n"; - for (SourcePerfData::const_iterator I = TimingResults.begin(), - E = TimingResults.end(); - I != E; ++I) { - // Terminate the last source with a comma before continuing to the next one. - if (I != TimingResults.begin()) - FileStream << ",\n"; - - FileStream << " {\n"; - FileStream << " \"Source \" : \"" << I->first << "\",\n"; - FileStream << " \"Data\" : [\n"; - for (std::vector<PerfItem>::const_iterator IE = I->second.begin(), - EE = I->second.end(); - IE != EE; ++IE) { - // Terminate the last perf item with a comma before continuing to the next - // one. - if (IE != I->second.begin()) - FileStream << ",\n"; - - FileStream << " {\n"; - FileStream << " \"TimerId\" : \"" << IE->Label << "\",\n"; - FileStream << " \"Time\" : " << llvm::format("%.2f", IE->Duration) - << "\n"; - - FileStream << " }"; - - } - FileStream << "\n ]\n"; - FileStream << " }"; - } - FileStream << "\n ]\n"; - FileStream << "}"; -} - -void dumpPerfData(const SourcePerfData &Data) { - for (SourcePerfData::const_iterator I = Data.begin(), E = Data.end(); I != E; - ++I) { - llvm::errs() << I->first << ":\n"; - for (std::vector<PerfItem>::const_iterator VecI = I->second.begin(), - VecE = I->second.end(); - VecI != VecE; ++VecI) { - llvm::errs() << " " << VecI->Label << ": " - << llvm::format("%.1f", VecI->Duration) << "ms\n"; - } - } -} diff --git a/clang-tools-extra/cpp11-migrate/Core/PerfSupport.h b/clang-tools-extra/cpp11-migrate/Core/PerfSupport.h deleted file mode 100644 index 58ddded2207..00000000000 --- a/clang-tools-extra/cpp11-migrate/Core/PerfSupport.h +++ /dev/null @@ -1,57 +0,0 @@ -//===-- Core/PerfSupport.h - Perf measurement helpers -----------*- 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 helper functionality for measuring performance and -/// recording data to file. -/// -//===----------------------------------------------------------------------===// - -#ifndef CPP11_MIGRATE_PERFSUPPORT_H -#define CPP11_MIGRATE_PERFSUPPORT_H - -#include "Transform.h" -#include "llvm/ADT/StringRef.h" - -#include <map> -#include <vector> - -/// \brief A single piece of performance data: a duration in milliseconds and a -/// label for that duration. -struct PerfItem { - PerfItem(const llvm::StringRef Label, float Duration) - : Label(Label), Duration(Duration) {} - - /// Label for this performance measurement. - std::string Label; - - /// Duration in milliseconds. - float Duration; -}; - -/// Maps source file names to a vector of durations/labels. -typedef std::map<std::string, std::vector<PerfItem> > SourcePerfData; - -/// Extracts durations collected by a Transform for all sources and adds them -/// to a SourcePerfData map where data is organized by source file. -extern void collectSourcePerfData(const Transform &T, SourcePerfData &Data); - -/// Write timing results to a JSON formatted file. -/// -/// File is placed in the directory given by \p DirectoryName. File is named in -/// a unique way with time and process ID to avoid naming collisions with -/// existing files or files being generated by other migrator processes. -void writePerfDataJSON( - const llvm::StringRef DirectoryName, - const SourcePerfData &TimingResults); - -/// Dump a SourcePerfData map to llvm::errs(). -extern void dumpPerfData(const SourcePerfData &Data); - -#endif // CPP11_MIGRATE_PERFSUPPORT_H diff --git a/clang-tools-extra/cpp11-migrate/Core/Refactoring.h b/clang-tools-extra/cpp11-migrate/Core/Refactoring.h deleted file mode 100644 index a15634a3704..00000000000 --- a/clang-tools-extra/cpp11-migrate/Core/Refactoring.h +++ /dev/null @@ -1,31 +0,0 @@ -//===-- Core/Refactoring.h - Stand-in for Tooling/Refactoring.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 is meant to be used instead of clang/Tooling/Refactoring.h -/// until such time as clang::tooling::Replacements is re-implemented as a -/// vector instead of a set. -/// -//===----------------------------------------------------------------------===// - -#ifndef CPP11_MIGRATE_REPLACEMENTS_VEC_H -#define CPP11_MIGRATE_REPLACEMENTS_VEC_H - -#include "clang/Tooling/Refactoring.h" - -// FIXME: Remove this file when clang::tooling::Replacements becomes a vector -// instead of a set. - -namespace clang { -namespace tooling { -typedef std::vector<clang::tooling::Replacement> ReplacementsVec; -} -} - -#endif // CPP11_MIGRATE_REPLACEMENTS_VEC_H diff --git a/clang-tools-extra/cpp11-migrate/Core/Reformatting.cpp b/clang-tools-extra/cpp11-migrate/Core/Reformatting.cpp deleted file mode 100644 index 50ba1f19f7a..00000000000 --- a/clang-tools-extra/cpp11-migrate/Core/Reformatting.cpp +++ /dev/null @@ -1,62 +0,0 @@ -//===-- Core/Reformatting.cpp - LibFormat integration ---------------------===// -// -// 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 the LibFormat integration used to reformat -/// migrated code. -/// -//===----------------------------------------------------------------------===// - -#include "Core/Reformatting.h" -#include "Core/FileOverrides.h" -#include "clang/Basic/Diagnostic.h" -#include "clang/Basic/DiagnosticOptions.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Lex/Lexer.h" - -using namespace clang; - -void Reformatter::reformatChanges(const FileOverrides &FileStates, - clang::SourceManager &SM, - clang::tooling::ReplacementsVec &Replaces) { - FileStates.applyOverrides(SM); - - for (FileOverrides::ChangeMap::const_iterator - I = FileStates.getChangedRanges().begin(), - E = FileStates.getChangedRanges().end(); - I != E; ++I) { - reformatSingleFile(I->getKey(), I->getValue(), SM, Replaces); - } -} - -void Reformatter::reformatSingleFile( - const llvm::StringRef FileName, const ChangedRanges &Changes, - SourceManager &SM, clang::tooling::ReplacementsVec &FormatReplacements) { - - const clang::FileEntry *Entry = SM.getFileManager().getFile(FileName); - assert(Entry && "expected an existing file"); - - FileID ID = SM.translateFile(Entry); - if (ID.isInvalid()) - ID = SM.createFileID(Entry, SourceLocation(), clang::SrcMgr::C_User); - - std::vector<CharSourceRange> ReformatRanges; - SourceLocation StartOfFile = SM.getLocForStartOfFile(ID); - for (ChangedRanges::const_iterator I = Changes.begin(), E = Changes.end(); - I != E; ++I) { - SourceLocation Start = StartOfFile.getLocWithOffset(I->getOffset()); - SourceLocation End = Start.getLocWithOffset(I->getLength()); - ReformatRanges.push_back(CharSourceRange::getCharRange(Start, End)); - } - - Lexer Lex(ID, SM.getBuffer(ID), SM, getFormattingLangOpts(Style.Standard)); - const tooling::Replacements &R = - format::reformat(Style, Lex, SM, ReformatRanges); - std::copy(R.begin(), R.end(), std::back_inserter(FormatReplacements)); -} diff --git a/clang-tools-extra/cpp11-migrate/Core/Reformatting.h b/clang-tools-extra/cpp11-migrate/Core/Reformatting.h deleted file mode 100644 index 9a10171a742..00000000000 --- a/clang-tools-extra/cpp11-migrate/Core/Reformatting.h +++ /dev/null @@ -1,60 +0,0 @@ -//===-- Core/Reformatting.h - LibFormat integration -------------*- 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 the LibFormat integration used to reformat -/// migrated code. -/// -//===----------------------------------------------------------------------===// - -#ifndef CPP11_MIGRATE_REFORMATTING_H -#define CPP11_MIGRATE_REFORMATTING_H - -#include "Core/Refactoring.h" -#include "clang/Format/Format.h" - -class FileOverrides; -class ChangedRanges; - -class Reformatter { -public: - Reformatter(const clang::format::FormatStyle &Style) : Style(Style) {} - - /// \brief Reformat the changes made to the file overrides. - /// - /// This function will apply the state of files stored in \c FileState to \c - /// SM. - /// - /// \param[in] FileState Files to reformat. - /// \param[in] SM SourceManager for access to source files. - /// \param[out] Replaces Container to store all reformatting replacements. - void reformatChanges(const FileOverrides &FileState, clang::SourceManager &SM, - clang::tooling::ReplacementsVec &Replaces); - - /// \brief Produce a list of replacements to apply on \p FileName, only the - /// ranges in \p Changes are replaced. - /// - /// Since this routine use \c clang::format::reformat() the rules that - /// function applies to ranges also apply here. - /// - /// \param[in] FileName Name of file to reformat. - /// \param[in] Changes Description of where changes were made to the file. - /// \param[in] SM SourceManager required to create replacements. - /// \param[out] FormatReplacements New reformatting replacements are appended - /// to this container. - void reformatSingleFile(const llvm::StringRef FileName, - const ChangedRanges &Changes, - clang::SourceManager &SM, - clang::tooling::ReplacementsVec &FormatReplacements); - -private: - clang::format::FormatStyle Style; -}; - -#endif // CPP11_MIGRATE_REFORMATTING_H diff --git a/clang-tools-extra/cpp11-migrate/Core/SyntaxCheck.cpp b/clang-tools-extra/cpp11-migrate/Core/SyntaxCheck.cpp deleted file mode 100644 index bd2eb63044f..00000000000 --- a/clang-tools-extra/cpp11-migrate/Core/SyntaxCheck.cpp +++ /dev/null @@ -1,73 +0,0 @@ -//===-- Core/SyntaxCheck.cpp ----------------------------------------------===// -// -// 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. -/// -//===----------------------------------------------------------------------===// - -#include "Core/SyntaxCheck.h" -#include "Core/FileOverrides.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; - - Overrides.applyOverrides(CI.getSourceManager()); - - 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 deleted file mode 100644 index 1651a7e7acc..00000000000 --- a/clang-tools-extra/cpp11-migrate/Core/SyntaxCheck.h +++ /dev/null @@ -1,38 +0,0 @@ -//===-- 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 <string> -#include <vector> - -// Forward Declarations -namespace clang { -namespace tooling { -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. -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 deleted file mode 100644 index cd76723d316..00000000000 --- a/clang-tools-extra/cpp11-migrate/Core/Transform.cpp +++ /dev/null @@ -1,172 +0,0 @@ -//===-- Core/Transform.cpp - Transform Base Class Def'n -------------------===// -// -// 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 the definition for the base Transform class from -/// which all transforms must subclass. -/// -//===----------------------------------------------------------------------===// - -#include "Core/Transform.h" -#include "Core/FileOverrides.h" -#include "clang/ASTMatchers/ASTMatchFinder.h" -#include "clang/Basic/LangOptions.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Tooling/Tooling.h" -#include "llvm/ADT/STLExtras.h" - -using namespace clang; - -llvm::cl::OptionCategory TransformsOptionsCategory("Transforms' options"); - -namespace { - -using namespace tooling; -using namespace ast_matchers; - -/// \brief Custom FrontendActionFactory to produce FrontendActions that simply -/// forward (Begin|End)SourceFileAction calls to a given Transform. -class ActionFactory : public clang::tooling::FrontendActionFactory { -public: - ActionFactory(MatchFinder &Finder, Transform &Owner) - : Finder(Finder), Owner(Owner) {} - - virtual FrontendAction *create() LLVM_OVERRIDE { - return new FactoryAdaptor(Finder, Owner); - } - -private: - class FactoryAdaptor : public ASTFrontendAction { - public: - FactoryAdaptor(MatchFinder &Finder, Transform &Owner) - : Finder(Finder), Owner(Owner) {} - - ASTConsumer *CreateASTConsumer(CompilerInstance &, StringRef) { - return Finder.newASTConsumer(); - } - - virtual bool BeginSourceFileAction(CompilerInstance &CI, - StringRef Filename) LLVM_OVERRIDE { - if (!ASTFrontendAction::BeginSourceFileAction(CI, Filename)) - return false; - - return Owner.handleBeginSource(CI, Filename); - } - - virtual void EndSourceFileAction() LLVM_OVERRIDE { - Owner.handleEndSource(); - return ASTFrontendAction::EndSourceFileAction(); - } - - private: - MatchFinder &Finder; - Transform &Owner; - }; - - MatchFinder &Finder; - Transform &Owner; -}; -} // namespace - -Transform::Transform(llvm::StringRef Name, const TransformOptions &Options) - : Name(Name), GlobalOptions(Options), Overrides(0) { - Reset(); -} - -Transform::~Transform() {} - -bool Transform::isFileModifiable(const SourceManager &SM, - const SourceLocation &Loc) const { - if (SM.isWrittenInMainFile(Loc)) - return true; - - if (!GlobalOptions.EnableHeaderModifications) - return false; - - const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Loc)); - if (!FE) - return false; - - return GlobalOptions.ModifiableHeaders.isFileIncluded(FE->getName()); -} - -bool Transform::handleBeginSource(CompilerInstance &CI, StringRef Filename) { - assert(Overrides != 0 && "Subclass transform didn't provide InputState"); - - Overrides->applyOverrides(CI.getSourceManager()); - CurrentSource = Filename; - - 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() { - CurrentSource.clear(); - if (Options().EnableTiming) - Timings.back().second += llvm::TimeRecord::getCurrentTime(false); -} - -void Transform::addTiming(llvm::StringRef Label, llvm::TimeRecord Duration) { - Timings.push_back(std::make_pair(Label.str(), Duration)); -} - -bool -Transform::addReplacementForCurrentTU(const clang::tooling::Replacement &R) { - if (CurrentSource.empty()) - return false; - - TranslationUnitReplacements &TU = Replacements[CurrentSource]; - if (TU.MainSourceFile.empty()) - TU.MainSourceFile = CurrentSource; - TU.Replacements.push_back(R); - - return true; -} - -FrontendActionFactory *Transform::createActionFactory(MatchFinder &Finder) { - return new ActionFactory(Finder, /*Owner=*/ *this); -} - -Version Version::getFromString(llvm::StringRef VersionStr) { - llvm::StringRef MajorStr, MinorStr; - Version V; - - llvm::tie(MajorStr, MinorStr) = VersionStr.split('.'); - if (!MinorStr.empty()) { - llvm::StringRef Ignore; - llvm::tie(MinorStr, Ignore) = MinorStr.split('.'); - if (MinorStr.getAsInteger(10, V.Minor)) - return Version(); - } - if (MajorStr.getAsInteger(10, V.Major)) - return Version(); - return V; -} - -TransformFactory::~TransformFactory() {} - -namespace { -bool versionSupported(Version Required, Version AvailableSince) { - // null version, means no requirements, means supported - if (Required.isNull()) - return true; - return Required >= AvailableSince; -} -} // end anonymous namespace - -bool TransformFactory::supportsCompilers(CompilerVersions Required) const { - return versionSupported(Required.Clang, Since.Clang) && - versionSupported(Required.Gcc, Since.Gcc) && - versionSupported(Required.Icc, Since.Icc) && - versionSupported(Required.Msvc, Since.Msvc); -} diff --git a/clang-tools-extra/cpp11-migrate/Core/Transform.h b/clang-tools-extra/cpp11-migrate/Core/Transform.h deleted file mode 100644 index 45e470d64e4..00000000000 --- a/clang-tools-extra/cpp11-migrate/Core/Transform.h +++ /dev/null @@ -1,344 +0,0 @@ -//===-- Core/Transform.h - Transform Base Class Def'n -----------*- 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 the declaration for the base Transform class from -/// which all transforms must subclass. -/// -//===----------------------------------------------------------------------===// - -#ifndef CPP11_MIGRATE_TRANSFORM_H -#define CPP11_MIGRATE_TRANSFORM_H - -#include "Core/IncludeExcludeInfo.h" -#include "Core/Refactoring.h" -#include "llvm/ADT/OwningPtr.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Registry.h" -#include "llvm/Support/Timer.h" -#include <string> -#include <vector> - -/// \brief Description of the riskiness of actions that can be taken by -/// transforms. -enum RiskLevel { - /// Transformations that will not change semantics. - RL_Safe, - - /// Transformations that might change semantics. - RL_Reasonable, - - /// Transformations that are likely to change semantics. - RL_Risky -}; - -// Forward declarations -namespace clang { -class CompilerInstance; -namespace tooling { -class CompilationDatabase; -class FrontendActionFactory; -} // namespace tooling -namespace ast_matchers { -class MatchFinder; -} // namespace ast_matchers -} // namespace clang - -class FileOverrides; - - -// \brief Maps main source file names to a TranslationUnitReplacements -// structure storing replacements for that translation unit. -typedef llvm::StringMap<clang::tooling::TranslationUnitReplacements> -TUReplacementsMap; - -/// \brief To group transforms' options together when printing the help. -extern llvm::cl::OptionCategory TransformsOptionsCategory; - -/// \brief Container for global options affecting all transforms. -struct TransformOptions { - /// \brief Enable the use of performance timers. - bool EnableTiming; - - /// \brief Allow changes to headers included from the main source file. - /// Transform sub-classes should use ModifiableHeaders to determine which - /// headers are modifiable and which are not. - bool EnableHeaderModifications; - - /// \brief Contains information on which headers are safe to transform and - /// which aren't. - IncludeExcludeInfo ModifiableHeaders; - - /// \brief Maximum allowed level of risk. - RiskLevel MaxRiskLevel; -}; - -/// \brief Abstract base class for all C++11 migration transforms. -/// -/// Subclasses must call createActionFactory() to create a -/// FrontendActionFactory to pass to ClangTool::run(). Subclasses are also -/// responsible for calling setOverrides() before calling ClangTool::run(). -/// -/// If timing is enabled (see TransformOptions), per-source performance timing -/// is recorded and stored in a TimingVec for later access with timing_begin() -/// and timing_end(). -class Transform { -public: - /// \brief Constructor - /// \param Name Name of the transform for human-readable purposes (e.g. -help - /// text) - /// \param Options Global options that affect all Transforms. - Transform(llvm::StringRef Name, const TransformOptions &Options); - - 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, - const clang::tooling::CompilationDatabase &Database, - 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; } - - /// \brief Query if changes were not made due to conflicts with other changes - /// made during the last call to apply() or if changes were too risky for the - /// requested risk level. - bool getChangesNotMade() const { - return RejectedChanges > 0 || DeferredChanges > 0; - } - - /// \brief Query the number of accepted changes. - unsigned getAcceptedChanges() const { return AcceptedChanges; } - /// \brief Query the number of changes considered too risky. - unsigned getRejectedChanges() const { return RejectedChanges; } - /// \brief Query the number of changes not made because they conflicted with - /// early changes. - unsigned getDeferredChanges() const { return DeferredChanges; } - - /// \brief Query transform name. - llvm::StringRef getName() const { return Name; } - - /// \brief Reset internal state of the transform. - /// - /// Useful if calling apply() several times with one instantiation of a - /// transform. - void Reset() { - AcceptedChanges = 0; - RejectedChanges = 0; - DeferredChanges = 0; - } - - /// \brief Tests if the file containing \a Loc is allowed to be modified by - /// the Migrator. - bool isFileModifiable(const clang::SourceManager &SM, - const clang::SourceLocation &Loc) const; - - /// \brief Whether a transformation with a risk level of \p RiskLevel is - /// acceptable or not. - bool isAcceptableRiskLevel(RiskLevel RiskLevel) const { - return RiskLevel <= GlobalOptions.MaxRiskLevel; - } - - /// \brief Called before parsing a translation unit for a FrontendAction. - /// - /// Transform uses this function to apply file overrides and start - /// performance timers. Subclasses overriding this function must call it - /// before returning. - virtual bool handleBeginSource(clang::CompilerInstance &CI, - llvm::StringRef Filename); - - /// \brief Called after FrontendAction has been run over a translation unit. - /// - /// Transform uses this function to stop performance timers. Subclasses - /// overriding this function must call it before returning. A call to - /// handleEndSource() for a given translation unit is expected to be called - /// immediately after the corresponding handleBeginSource() call. - virtual void handleEndSource(); - - /// \brief Performance timing data is stored as a vector of pairs. Pairs are - /// formed of: - /// \li Name of source file. - /// \li 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(); } - - /// \brief Add a Replacement to the list for the current translation unit. - /// - /// \returns \li true on success - /// \li false if there is no current translation unit - bool addReplacementForCurrentTU(const clang::tooling::Replacement &R); - - /// \brief Accessor to Replacements across all transformed translation units. - const TUReplacementsMap &getAllReplacements() const { - return Replacements; - } - -protected: - - void setAcceptedChanges(unsigned Changes) { - AcceptedChanges = Changes; - } - void setRejectedChanges(unsigned Changes) { - RejectedChanges = Changes; - } - void setDeferredChanges(unsigned Changes) { - DeferredChanges = Changes; - } - - /// \brief Allows subclasses to manually add performance timer data. - /// - /// \p Label should probably include the source file name somehow as the - /// duration info is simply added to the vector of timing data which holds - /// 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 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) { - this->Overrides = &Overrides; - } - - /// \brief Subclasses must call this function to create a - /// FrontendActionFactory to pass to ClangTool. - /// - /// The factory returned by this function is responsible for calling back to - /// Transform to call handleBeginSource() and handleEndSource(). - clang::tooling::FrontendActionFactory * - createActionFactory(clang::ast_matchers::MatchFinder &Finder); - -private: - const std::string Name; - const TransformOptions &GlobalOptions; - const FileOverrides *Overrides; - TUReplacementsMap Replacements; - std::string CurrentSource; - TimingVec Timings; - unsigned AcceptedChanges; - unsigned RejectedChanges; - unsigned DeferredChanges; -}; - -/// \brief Describes a version number of the form major[.minor] (minor being -/// optional). -struct Version { - explicit Version(unsigned Major = 0, unsigned Minor = 0) - : Major(Major), Minor(Minor) {} - - bool operator<(Version RHS) const { - if (Major < RHS.Major) - return true; - if (Major == RHS.Major) - return Minor < RHS.Minor; - return false; - } - - bool operator==(Version RHS) const { - return Major == RHS.Major && Minor == RHS.Minor; - } - - bool operator!=(Version RHS) const { return !(*this == RHS); } - bool operator>(Version RHS) const { return RHS < *this; } - bool operator<=(Version RHS) const { return !(*this > RHS); } - bool operator>=(Version RHS) const { return !(*this < RHS); } - - bool isNull() const { return Minor == 0 && Major == 0; } - unsigned getMajor() const { return Major; } - unsigned getMinor() const { return Minor; } - - /// \brief Creates a version from a string of the form \c major[.minor]. - /// - /// Note that any version component after \c minor is ignored. - /// - /// \return A null version is returned on error. - static Version getFromString(llvm::StringRef VersionStr); - -private: - unsigned Major; - unsigned Minor; -}; - -/// \brief Convenience structure to store the version of some compilers. -struct CompilerVersions { - Version Clang, Gcc, Icc, Msvc; -}; - -/// \brief A factory that can instantiate a specific transform. -/// -/// Each transform should subclass this class and implement -/// \c createTransform(). -/// -/// In the sub-classed factory constructor, specify the earliest versions since -/// the compilers in \c CompilerVersions support the feature introduced by the -/// transform. See the example below. -/// -/// Note that you should use \c TransformFactoryRegistry to register the -/// transform globally. -/// -/// Example: -/// \code -/// class MyTransform : public Transform { ... }; -/// -/// struct MyFactory : TransformFactory { -/// MyFactory() { -/// Since.Clang = Version(3, 0); -/// Since.Gcc = Version(4, 7); -/// Since.Icc = Version(12); -/// Since.Msvc = Version(10); -/// } -/// -/// Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE { -/// return new MyTransform(Opts); -/// } -/// }; -/// -/// // Register the factory using this statically initialized variable. -/// static TransformFactoryRegistry::Add<MyFactory> -/// X("my-transform", "<Short description of my transform>"); -/// -/// // This anchor is used to force the linker to link in the generated object -/// // file and thus register the factory. -/// volatile int MyTransformAnchorSource = 0; -/// \endcode -class TransformFactory { -public: - virtual ~TransformFactory(); - virtual Transform *createTransform(const TransformOptions &) = 0; - - /// \brief Whether the transform is supported by the required compilers or - /// not. - bool supportsCompilers(CompilerVersions Required) const; - -protected: - /// \brief Since when the C++11 feature introduced by this transform has been - /// available. - /// - /// Can be set by the sub-class in the constructor body. - CompilerVersions Since; -}; - -typedef llvm::Registry<TransformFactory> TransformFactoryRegistry; - -#endif // CPP11_MIGRATE_TRANSFORM_H diff --git a/clang-tools-extra/cpp11-migrate/Core/Transforms.cpp b/clang-tools-extra/cpp11-migrate/Core/Transforms.cpp deleted file mode 100644 index 93701796e24..00000000000 --- a/clang-tools-extra/cpp11-migrate/Core/Transforms.cpp +++ /dev/null @@ -1,71 +0,0 @@ -//===-- Core/Transforms.cpp - class Transforms Impl -----------------------===// -// -// 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 the implementation for class Transforms. -/// -//===----------------------------------------------------------------------===// - -#include "Core/Transforms.h" -#include "Core/Transform.h" - -namespace cl = llvm::cl; - -static cl::OptionCategory TransformCategory("Transforms"); - -Transforms::~Transforms() { - for (std::vector<Transform *>::iterator I = ChosenTransforms.begin(), - E = ChosenTransforms.end(); - I != E; ++I) - delete *I; - - for (OptionMap::iterator I = Options.begin(), E = Options.end(); I != E; ++I) - delete I->getValue(); -} - -void Transforms::registerTransforms() { - for (TransformFactoryRegistry::iterator I = TransformFactoryRegistry::begin(), - E = TransformFactoryRegistry::end(); - I != E; ++I) - Options[I->getName()] = new cl::opt<bool>( - I->getName(), cl::desc(I->getDesc()), cl::cat(TransformCategory)); -} - -bool Transforms::hasAnyExplicitOption() const { - for (OptionMap::const_iterator I = Options.begin(), E = Options.end(); I != E; - ++I) - if (*I->second) - return true; - return false; -} - -void -Transforms::createSelectedTransforms(const TransformOptions &GlobalOptions, - const CompilerVersions &RequiredVersions) { - // if at least one transform is set explicitly on the command line, do not - // enable non-explicit ones - bool EnableAllTransformsByDefault = !hasAnyExplicitOption(); - - for (TransformFactoryRegistry::iterator I = TransformFactoryRegistry::begin(), - E = TransformFactoryRegistry::end(); - I != E; ++I) { - bool ExplicitlyEnabled = *Options[I->getName()]; - bool OptionEnabled = EnableAllTransformsByDefault || ExplicitlyEnabled; - - if (!OptionEnabled) - continue; - - llvm::OwningPtr<TransformFactory> Factory(I->instantiate()); - if (Factory->supportsCompilers(RequiredVersions)) - ChosenTransforms.push_back(Factory->createTransform(GlobalOptions)); - else if (ExplicitlyEnabled) - llvm::errs() << "note: " << '-' << I->getName() - << ": transform not available for specified compilers\n"; - } -} diff --git a/clang-tools-extra/cpp11-migrate/Core/Transforms.h b/clang-tools-extra/cpp11-migrate/Core/Transforms.h deleted file mode 100644 index 18369407dda..00000000000 --- a/clang-tools-extra/cpp11-migrate/Core/Transforms.h +++ /dev/null @@ -1,82 +0,0 @@ -//===-- Core/Transforms.h - class Transforms Def'n --------------*- 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 the definition for class Transforms which is -/// responsible for defining the command-line arguments exposing -/// transformations to the user and applying requested transforms. -/// -//===----------------------------------------------------------------------===// - -#ifndef CPP11_MIGRATE_TRANSFORMS_H -#define CPP11_MIGRATE_TRANSFORMS_H - -#include "llvm/Support/CommandLine.h" -#include "llvm/ADT/StringRef.h" - -#include <vector> - -// Forward declarations -namespace llvm { -namespace cl { -class Option; -} // namespace cl -} // namespace llvm -class Transform; -struct TransformOptions; -struct CompilerVersions; - -typedef Transform *(*TransformCreator)(const TransformOptions &); -template <typename T> -Transform *ConstructTransform(const TransformOptions &Options) { - return new T(Options); -} - -/// \brief Class encapsulating the creation of command line bool options -/// for each transform and instantiating transforms chosen by the user. -class Transforms { -public: - typedef std::vector<Transform*> TransformVec; - typedef TransformVec::const_iterator const_iterator; - -public: - - ~Transforms(); - - /// \brief Registers all available transforms causing them to be made - /// available on the command line. - /// - /// Be sure to register all transforms *before* parsing command line options. - void registerTransforms(); - - /// \brief Instantiate all transforms that were selected on the command line. - /// - /// Call *after* parsing options. - void createSelectedTransforms(const TransformOptions &Options, - const CompilerVersions &RequiredVersions); - - /// \brief Return an iterator to the start of a container of instantiated - /// transforms. - const_iterator begin() const { return ChosenTransforms.begin(); } - - /// \brief Return an iterator to the end of a container of instantiated - /// transforms. - const_iterator end() const { return ChosenTransforms.end(); } - -private: - bool hasAnyExplicitOption() const; - - typedef llvm::StringMap<llvm::cl::opt<bool> *> OptionMap; - -private: - TransformVec ChosenTransforms; - OptionMap Options; -}; - -#endif // CPP11_MIGRATE_TRANSFORMS_H |