diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2013-09-04 17:35:07 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2013-09-04 17:35:07 +0000 |
commit | d9063c46f59f4bec47bcbeddca8ca2f789348c03 (patch) | |
tree | 76505542df7a05016dc71ffe44ed3ba264fb54be /clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp | |
parent | 6a23d212897d5402035cfaea82260f6dae1c8f2a (diff) | |
download | bcm5719-llvm-d9063c46f59f4bec47bcbeddca8ca2f789348c03.tar.gz bcm5719-llvm-d9063c46f59f4bec47bcbeddca8ca2f789348c03.zip |
Rename cpp11-migrate to clang-modernize.
There is no reason to expect this tool to be limited to C++11, it seems
very likely to be of on-going interest. It seems likely to be useful for
modernizing even as new libraries come out in TSes and other formats
than a complete standard. Fundamentally, we need something a bit more
general. After some discussion on the list, going with
'clang-modernize'.
I've tried to do a reasonably comprehensive job of fixing up the names,
but I may still have missed some. Feel free to poke me if you spot any
fallout here. Things I've tried reasonably hard to find and fix:
- cpp11-migrate -> clang-modernize
- Migrator -> Modernizer
- Clean up the introductory documentation that was C++11 specific.
I'll also point out that this tool continues to delight me. =] Also,
a huge thanks to those who have so carefully, thoroughly documented the
tool. The docs here are simply phenomenal. Every tool should be this
well documented. I hope I have updated the documentation reasonably
well, but I'm not very good at documentation, so review much
appreciated.
llvm-svn: 189960
Diffstat (limited to 'clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp')
-rw-r--r-- | clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp | 494 |
1 files changed, 0 insertions, 494 deletions
diff --git a/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp b/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp deleted file mode 100644 index 14d55609b22..00000000000 --- a/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp +++ /dev/null @@ -1,494 +0,0 @@ -//===-- cpp11-migrate/Cpp11Migrate.cpp - Main file C++11 migration tool ---===// -// -// 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 implements the C++11 feature migration tool main function -/// and transformation framework. -/// -/// See user documentation for usage instructions. -/// -//===----------------------------------------------------------------------===// - -#include "Core/FileOverrides.h" -#include "Core/PerfSupport.h" -#include "Core/SyntaxCheck.h" -#include "Core/Transform.h" -#include "Core/Transforms.h" -#include "Core/Reformatting.h" -#include "clang/Basic/Diagnostic.h" -#include "clang/Basic/DiagnosticOptions.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Frontend/FrontendActions.h" -#include "clang/Rewrite/Core/Rewriter.h" -#include "clang/Tooling/CommonOptionsParser.h" -#include "clang/Tooling/Tooling.h" -#include "clang-apply-replacements/Tooling/ApplyReplacements.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/StringSwitch.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/Signals.h" - -namespace cl = llvm::cl; -using namespace clang; -using namespace clang::tooling; - -TransformOptions GlobalOptions; - -static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); -static cl::opt<std::string> BuildPath( - "p", cl::desc("Build Path"), cl::Optional); -static cl::list<std::string> SourcePaths( - cl::Positional, cl::desc("<source0> [... <sourceN>]"), cl::OneOrMore); -static cl::extrahelp MoreHelp( - "EXAMPLES:\n\n" - "Apply all transforms on a given file, no compilation database:\n\n" - " cpp11-migrate path/to/file.cpp -- -Ipath/to/include/\n" - "\n" - "Convert for loops to the new ranged-based for loops on all files in a " - "subtree\nand reformat the code automatically using the LLVM style:\n\n" - " find path/in/subtree -name '*.cpp' -exec \\\n" - " cpp11-migrate -p build/path -format-style=LLVM -loop-convert {} ';'\n" - "\n" - "Make use of both nullptr and the override specifier, using git ls-files:\n" - "\n" - " git ls-files '*.cpp' | xargs -I{} cpp11-migrate -p build/path \\\n" - " -use-nullptr -add-override -override-macros {}\n" - "\n" - "Apply all transforms supported by both clang >= 3.0 and gcc >= 4.7:\n\n" - " cpp11-migrate -for-compilers=clang-3.0,gcc-4.7 foo.cpp -- -Ibar\n"); - -static cl::opt<RiskLevel, /*ExternalStorage=*/true> MaxRiskLevel( - "risk", cl::desc("Select a maximum risk level:"), - cl::values(clEnumValN(RL_Safe, "safe", "Only safe transformations"), - clEnumValN(RL_Reasonable, "reasonable", - "Enable transformations that might change " - "semantics (default)"), - clEnumValN(RL_Risky, "risky", - "Enable transformations that are likely to " - "change semantics"), - clEnumValEnd), - cl::location(GlobalOptions.MaxRiskLevel), - cl::init(RL_Reasonable)); - -static cl::opt<bool> FinalSyntaxCheck( - "final-syntax-check", - cl::desc("Check for correct syntax after applying transformations"), - cl::init(false)); - -static cl::opt<std::string> FormatStyleOpt( - "format-style", - cl::desc("Coding style to use on the replacements, either a builtin style\n" - "or a YAML config file (see: clang-format -dump-config).\n" - "Currently supports 4 builtins style:\n" - " LLVM, Google, Chromium, Mozilla.\n"), - cl::value_desc("string")); - -static cl::opt<bool> -SummaryMode("summary", cl::desc("Print transform summary"), - cl::init(false)); - -const char NoTiming[] = "no_timing"; -static cl::opt<std::string> TimingDirectoryName( - "perf", cl::desc("Capture performance data and output to specified " - "directory. Default: ./migrate_perf"), - cl::init(NoTiming), cl::ValueOptional, cl::value_desc("directory name")); - -// TODO: Remove cl::Hidden when functionality for acknowledging include/exclude -// options are implemented in the tool. -static cl::opt<std::string> -IncludePaths("include", cl::Hidden, - cl::desc("Comma seperated list of paths to consider to be " - "transformed")); -static cl::opt<std::string> -ExcludePaths("exclude", cl::Hidden, - cl::desc("Comma seperated list of paths that can not " - "be transformed")); -static cl::opt<std::string> -IncludeFromFile("include-from", cl::Hidden, cl::value_desc("filename"), - cl::desc("File containing a list of paths to consider to " - "be transformed")); -static cl::opt<std::string> -ExcludeFromFile("exclude-from", cl::Hidden, cl::value_desc("filename"), - cl::desc("File containing a list of paths that can not be " - "transforms")); - -// Header modifications will probably be always on eventually. For now, they -// need to be explicitly enabled. -static cl::opt<bool, /*ExternalStorage=*/true> EnableHeaderModifications( - "headers", - cl::Hidden, // Experimental feature for now. - cl::desc("Enable modifications to headers"), - cl::location(GlobalOptions.EnableHeaderModifications), - cl::init(false)); - -static cl::opt<bool> -SerializeReplacements("serialize-replacements", - cl::Hidden, // Associated with -headers - cl::desc("Serialize translation unit replacements to " - "disk instead of changing files."), - cl::init(false)); - -cl::opt<std::string> SupportedCompilers( - "for-compilers", cl::value_desc("string"), - cl::desc("Select transforms targeting the intersection of\n" - "language features supported by the given compilers.\n" - "Takes a comma-seperated list of <compiler>-<version>.\n" - "\t<compiler> can be any of: clang, gcc, icc, msvc\n" - "\t<version> is <major>[.<minor>]\n")); - -/// \brief Extract the minimum compiler versions as requested on the command -/// line by the switch \c -for-compilers. -/// -/// \param ProgName The name of the program, \c argv[0], used to print errors. -/// \param Error If an error occur while parsing the versions this parameter is -/// set to \c true, otherwise it will be left untouched. -static CompilerVersions handleSupportedCompilers(const char *ProgName, - bool &Error) { - if (SupportedCompilers.getNumOccurrences() == 0) - return CompilerVersions(); - CompilerVersions RequiredVersions; - llvm::SmallVector<llvm::StringRef, 4> Compilers; - - llvm::StringRef(SupportedCompilers).split(Compilers, ","); - - for (llvm::SmallVectorImpl<llvm::StringRef>::iterator I = Compilers.begin(), - E = Compilers.end(); - I != E; ++I) { - llvm::StringRef Compiler, VersionStr; - llvm::tie(Compiler, VersionStr) = I->split('-'); - Version *V = llvm::StringSwitch<Version *>(Compiler) - .Case("clang", &RequiredVersions.Clang) - .Case("gcc", &RequiredVersions.Gcc).Case("icc", &RequiredVersions.Icc) - .Case("msvc", &RequiredVersions.Msvc).Default(NULL); - - if (V == NULL) { - llvm::errs() << ProgName << ": " << Compiler - << ": unsupported platform\n"; - Error = true; - continue; - } - if (VersionStr.empty()) { - llvm::errs() << ProgName << ": " << *I - << ": missing version number in platform\n"; - Error = true; - continue; - } - - Version Version = Version::getFromString(VersionStr); - if (Version.isNull()) { - llvm::errs() - << ProgName << ": " << *I - << ": invalid version, please use \"<major>[.<minor>]\" instead of \"" - << VersionStr << "\"\n"; - Error = true; - continue; - } - // support the lowest version given - if (V->isNull() || Version < *V) - *V = Version; - } - return RequiredVersions; -} - -/// \brief Creates the Reformatter if the format style option is provided, -/// return a null pointer otherwise. -/// -/// \param ProgName The name of the program, \c argv[0], used to print errors. -/// \param Error If the \c -format-style is provided but with wrong parameters -/// this is parameter is set to \c true, left untouched otherwise. An error -/// message is printed with an explanation. -static Reformatter *handleFormatStyle(const char *ProgName, bool &Error) { - if (FormatStyleOpt.getNumOccurrences() > 0) { - format::FormatStyle Style; - if (!format::getPredefinedStyle(FormatStyleOpt, &Style)) { - llvm::StringRef ConfigFilePath = FormatStyleOpt; - llvm::OwningPtr<llvm::MemoryBuffer> Text; - llvm::error_code ec; - - ec = llvm::MemoryBuffer::getFile(ConfigFilePath, Text); - if (!ec) - ec = parseConfiguration(Text->getBuffer(), &Style); - - if (ec) { - llvm::errs() << ProgName << ": invalid format style " << FormatStyleOpt - << ": " << ec.message() << "\n"; - Error = true; - return 0; - } - } - - // force mode to C++11 - Style.Standard = clang::format::FormatStyle::LS_Cpp11; - return new Reformatter(Style); - } - return 0; -} - -/// \brief Use \c ChangesReformatter to reformat all changed regions of all -/// files stored in \c Overrides and write the result to disk. -/// -/// \returns \li true if reformatting replacements were successfully applied -/// without conflicts and all files were successfully written to -/// disk. -/// \li false if reformatting could not be successfully applied or -/// if at least one file failed to write to disk. -bool reformat(Reformatter &ChangesReformatter, const FileOverrides &Overrides, - DiagnosticsEngine &Diagnostics) { - FileManager Files((FileSystemOptions())); - SourceManager SM(Diagnostics, Files); - - replace::TUReplacements AllReplacements(1); - ChangesReformatter.reformatChanges(Overrides, SM, - AllReplacements.front().Replacements); - - replace::FileToReplacementsMap GroupedReplacements; - if (!replace::mergeAndDeduplicate(AllReplacements, GroupedReplacements, SM)) { - llvm::errs() << "Warning: Reformatting produced conflicts.\n"; - return false; - } - - Rewriter DestRewriter(SM, LangOptions()); - if (!replace::applyReplacements(GroupedReplacements, DestRewriter)) { - llvm::errs() << "Warning: Failed to apply reformatting conflicts!\n"; - return false; - } - - return replace::writeFiles(DestRewriter); -} - -bool serializeReplacements(const replace::TUReplacements &Replacements) { - bool Errors = false; - for (replace::TUReplacements::const_iterator I = Replacements.begin(), - E = Replacements.end(); - I != E; ++I) { - llvm::SmallString<128> ReplacementsFileName; - llvm::SmallString<64> Error; - bool Result = generateReplacementsFileName(I->MainSourceFile, - ReplacementsFileName, Error); - if (!Result) { - llvm::errs() << "Failed to generate replacements filename:" << Error - << "\n"; - Errors = true; - continue; - } - - std::string ErrorInfo; - llvm::raw_fd_ostream ReplacementsFile(ReplacementsFileName.c_str(), - ErrorInfo, llvm::sys::fs::F_Binary); - if (!ErrorInfo.empty()) { - llvm::errs() << "Error opening file: " << ErrorInfo << "\n"; - Errors = true; - continue; - } - llvm::yaml::Output YAML(ReplacementsFile); - YAML << const_cast<TranslationUnitReplacements &>(*I); - } - return !Errors; -} - -int main(int argc, const char **argv) { - llvm::sys::PrintStackTraceOnErrorSignal(); - Transforms TransformManager; - - TransformManager.registerTransforms(); - - // Parse options and generate compilations. - OwningPtr<CompilationDatabase> Compilations( - FixedCompilationDatabase::loadFromCommandLine(argc, argv)); - cl::ParseCommandLineOptions(argc, argv); - - if (!Compilations) { - std::string ErrorMessage; - if (BuildPath.getNumOccurrences() > 0) { - Compilations.reset(CompilationDatabase::autoDetectFromDirectory( - BuildPath, ErrorMessage)); - } else { - Compilations.reset(CompilationDatabase::autoDetectFromSource( - SourcePaths[0], ErrorMessage)); - // If no compilation database can be detected from source then we create - // a new FixedCompilationDatabase with c++11 support. - if (!Compilations) { - std::string CommandLine[] = {"-std=c++11"}; - Compilations.reset(new FixedCompilationDatabase(".", CommandLine)); - } - } - if (!Compilations) - llvm::report_fatal_error(ErrorMessage); - } - - // Since ExecutionTimeDirectoryName could be an empty string we compare - // against the default value when the command line option is not specified. - GlobalOptions.EnableTiming = (TimingDirectoryName != NoTiming); - - // Check the reformatting style option - bool CmdSwitchError = false; - llvm::OwningPtr<Reformatter> ChangesReformatter( - handleFormatStyle(argv[0], CmdSwitchError)); - - CompilerVersions RequiredVersions = - handleSupportedCompilers(argv[0], CmdSwitchError); - if (CmdSwitchError) - return 1; - - // Populate the ModifiableHeaders structure if header modifications are - // enabled. - if (GlobalOptions.EnableHeaderModifications) { - GlobalOptions.ModifiableHeaders - .readListFromString(IncludePaths, ExcludePaths); - GlobalOptions.ModifiableHeaders - .readListFromFile(IncludeFromFile, ExcludeFromFile); - } - - TransformManager.createSelectedTransforms(GlobalOptions, RequiredVersions); - - llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts( - new DiagnosticOptions()); - DiagnosticsEngine Diagnostics( - llvm::IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), - DiagOpts.getPtr()); - - // FIXME: Make this DiagnosticsEngine available to all Transforms probably via - // GlobalOptions. - - if (TransformManager.begin() == TransformManager.end()) { - if (SupportedCompilers.empty()) - llvm::errs() << argv[0] << ": no selected transforms\n"; - else - llvm::errs() << argv[0] - << ": no transforms available for specified compilers\n"; - return 1; - } - - // If SerializeReplacements is requested, then change reformatting must be - // turned off and only one transform should be requested. Reformatting is - // basically another transform so even if there's only one other transform, - // the reformatting pass would make two. - if (SerializeReplacements && - (std::distance(TransformManager.begin(), TransformManager.end()) > 1 || - ChangesReformatter)) { - llvm::errs() << "Serialization of replacements requested for multiple " - "transforms.\nChanges from only one transform can be " - "serialized.\n"; - return 1; - } - - SourcePerfData PerfData; - FileOverrides FileStates; - - for (Transforms::const_iterator I = TransformManager.begin(), - E = TransformManager.end(); - I != E; ++I) { - Transform *T = *I; - - if (T->apply(FileStates, *Compilations, SourcePaths) != 0) { - // FIXME: Improve ClangTool to not abort if just one file fails. - return 1; - } - - if (GlobalOptions.EnableTiming) - collectSourcePerfData(*T, PerfData); - - if (SummaryMode) { - llvm::outs() << "Transform: " << T->getName() - << " - Accepted: " << T->getAcceptedChanges(); - if (T->getChangesNotMade()) { - llvm::outs() << " - Rejected: " << T->getRejectedChanges() - << " - Deferred: " << T->getDeferredChanges(); - } - llvm::outs() << "\n"; - } - - // Collect all TranslationUnitReplacements generated from the translation - // units the transform worked on and store them in AllReplacements. - replace::TUReplacements AllReplacements; - const TUReplacementsMap &ReplacementsMap = T->getAllReplacements(); - const TranslationUnitReplacements &( - TUReplacementsMap::value_type::*getValue)() const = - &TUReplacementsMap::value_type::getValue; - std::transform(ReplacementsMap.begin(), ReplacementsMap.end(), - std::back_inserter(AllReplacements), - std::mem_fun_ref(getValue)); - - if (SerializeReplacements) - serializeReplacements(AllReplacements); - - FileManager Files((FileSystemOptions())); - SourceManager SM(Diagnostics, Files); - - // Make sure SourceManager is updated to have the same initial state as the - // transforms. - FileStates.applyOverrides(SM); - - replace::FileToReplacementsMap GroupedReplacements; - if (!replace::mergeAndDeduplicate(AllReplacements, GroupedReplacements, - SM)) { - llvm::outs() << "Transform " << T->getName() - << " resulted in conflicts. Discarding all " - << "replacements.\n"; - continue; - } - - // Apply replacements and update FileStates with new state. - Rewriter DestRewriter(SM, LangOptions()); - if (!replace::applyReplacements(GroupedReplacements, DestRewriter)) { - llvm::outs() << "Some replacements failed to apply. Discarding " - "all replacements.\n"; - continue; - } - - // Update contents of files in memory to serve as initial state for next - // transform. - FileStates.updateState(DestRewriter); - - // Update changed ranges for reformatting - if (ChangesReformatter) - FileStates.adjustChangedRanges(GroupedReplacements); - } - - // Skip writing final file states to disk if we were asked to serialize - // replacements. Otherwise reformat changes if reformatting is enabled. If - // not enabled or if reformatting fails write un-formated changes to disk - // instead. reformat() takes care of writing successfully formatted changes. - if (!SerializeReplacements && - (!ChangesReformatter || - !reformat(*ChangesReformatter, FileStates, Diagnostics))) - FileStates.writeToDisk(Diagnostics); - - if (FinalSyntaxCheck) - if (!doSyntaxCheck(*Compilations, SourcePaths, FileStates)) - return 1; - - // Report execution times. - if (GlobalOptions.EnableTiming && !PerfData.empty()) { - std::string DirectoryName = TimingDirectoryName; - // Use default directory name. - if (DirectoryName.empty()) - DirectoryName = "./migrate_perf"; - writePerfDataJSON(DirectoryName, PerfData); - } - - return 0; -} - -// These anchors are used to force the linker to link the transforms -extern volatile int AddOverrideTransformAnchorSource; -extern volatile int LoopConvertTransformAnchorSource; -extern volatile int PassByValueTransformAnchorSource; -extern volatile int ReplaceAutoPtrTransformAnchorSource; -extern volatile int UseAutoTransformAnchorSource; -extern volatile int UseNullptrTransformAnchorSource; - -static int TransformsAnchorsDestination[] = { - AddOverrideTransformAnchorSource, - LoopConvertTransformAnchorSource, - PassByValueTransformAnchorSource, - ReplaceAutoPtrTransformAnchorSource, - UseAutoTransformAnchorSource, - UseNullptrTransformAnchorSource -}; |