summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2013-09-04 17:35:07 +0000
committerChandler Carruth <chandlerc@gmail.com>2013-09-04 17:35:07 +0000
commitd9063c46f59f4bec47bcbeddca8ca2f789348c03 (patch)
tree76505542df7a05016dc71ffe44ed3ba264fb54be /clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp
parent6a23d212897d5402035cfaea82260f6dae1c8f2a (diff)
downloadbcm5719-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.cpp494
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
-};
OpenPOWER on IntegriCloud