diff options
author | Kirill Bobyrev <omtcyfz@gmail.com> | 2016-09-16 08:45:19 +0000 |
---|---|---|
committer | Kirill Bobyrev <omtcyfz@gmail.com> | 2016-09-16 08:45:19 +0000 |
commit | e5e7e153b5c7691b861b014844e760dccca42a16 (patch) | |
tree | 55b9afd6c1fbd30736653efbcc4d6f679cb166b9 /clang-tools-extra/clang-rename/tool/ClangRename.cpp | |
parent | b4e15b8ceeaf891a5ca5a8192f0719c5bda6d7ce (diff) | |
download | bcm5719-llvm-e5e7e153b5c7691b861b014844e760dccca42a16.tar.gz bcm5719-llvm-e5e7e153b5c7691b861b014844e760dccca42a16.zip |
[clang-rename] Merge rename-{at|all} & optimise.
Having both rename-at and rename-all both seems confusing and introduces
unneeded difficulties. After merging rename-at and rename-all maintaining main
function wrappers and custom help becomes redundant while CLI becomes less
confusing.
D24224 (which was the original patch causing buildbot failures) wasn't aware of
bugs caused by passing both -offset and -qualified-name. After D24224 was landed
it caused buildbot failures and therefor I just reverted it.
Two things that make this patch different from D24224 are:
* unittests/clang-rename was deleted, because it is unmaintained and doesn't do
much.
* Passing both `-offset` and `-qualified-name` isn't allowed anymore for the
sake of preventing bugs.
This patch is a trivial enhancement of accepted D24224 revision.
Tested with `ninja check-all`.
Differential Revision: https://reviews.llvm.org/D24567
llvm-svn: 281710
Diffstat (limited to 'clang-tools-extra/clang-rename/tool/ClangRename.cpp')
-rw-r--r-- | clang-tools-extra/clang-rename/tool/ClangRename.cpp | 211 |
1 files changed, 66 insertions, 145 deletions
diff --git a/clang-tools-extra/clang-rename/tool/ClangRename.cpp b/clang-tools-extra/clang-rename/tool/ClangRename.cpp index 8e59994b582..9cc29ff963f 100644 --- a/clang-tools-extra/clang-rename/tool/ClangRename.cpp +++ b/clang-tools-extra/clang-rename/tool/ClangRename.cpp @@ -38,28 +38,12 @@ #include <system_error> using namespace llvm; - using namespace clang; -cl::OptionCategory ClangRenameAtCategory("clang-rename rename-at options"); -cl::OptionCategory ClangRenameAllCategory("clang-rename rename-all options"); - -const char RenameAtUsage[] = "A tool to rename symbols in C/C++ code.\n\ -clang-rename renames every occurrence of a symbol found at <offset> in\n\ -<source0>. If -i is specified, the edited files are overwritten to disk.\n\ -Otherwise, the results are written to stdout.\n"; - -const char RenameAllUsage[] = "A tool to rename symbols in C/C++ code.\n\ -clang-rename performs renaming given pairs {offset | old-name} -> new-name.\n"; - -static int renameAtMain(int argc, const char *argv[]); -static int renameAllMain(int argc, const char *argv[]); -static int helpMain(int argc, const char *argv[]); - /// \brief An oldname -> newname rename. struct RenameAllInfo { - std::string OldName; unsigned Offset = 0; + std::string QualifiedName; std::string NewName; }; @@ -72,8 +56,8 @@ namespace yaml { /// (de)serialized. template <> struct MappingTraits<RenameAllInfo> { static void mapping(IO &IO, RenameAllInfo &Info) { - IO.mapOptional("OldName", Info.OldName); IO.mapOptional("Offset", Info.Offset); + IO.mapOptional("QualifiedName", Info.QualifiedName); IO.mapRequired("NewName", Info.NewName); } }; @@ -81,72 +65,42 @@ template <> struct MappingTraits<RenameAllInfo> { } // end namespace yaml } // end namespace llvm -int main(int argc, const char **argv) { - if (argc > 1) { - using MainFunction = std::function<int(int, const char *[])>; - MainFunction Func = StringSwitch<MainFunction>(argv[1]) - .Case("rename-at", renameAtMain) - .Case("rename-all", renameAllMain) - .Cases("-help", "--help", helpMain) - .Default(nullptr); +static cl::OptionCategory ClangRenameOptions("clang-rename common options"); + +static cl::list<unsigned> SymbolOffsets( + "offset", + cl::desc("Locates the symbol by offset as opposed to <line>:<column>."), + cl::ZeroOrMore, cl::cat(ClangRenameOptions)); +static cl::opt<bool> Inplace("i", cl::desc("Overwrite edited <file>s."), + cl::cat(ClangRenameOptions)); +static cl::list<std::string> + QualifiedNames("qualified-name", + cl::desc("The fully qualified name of the symbol."), + cl::ZeroOrMore, cl::cat(ClangRenameOptions)); + +static cl::list<std::string> + NewNames("new-name", cl::desc("The new name to change the symbol to."), + cl::ZeroOrMore, cl::cat(ClangRenameOptions)); +static cl::opt<bool> PrintName( + "pn", + cl::desc("Print the found symbol's name prior to renaming to stderr."), + cl::cat(ClangRenameOptions)); +static cl::opt<bool> PrintLocations( + "pl", cl::desc("Print the locations affected by renaming to stderr."), + cl::cat(ClangRenameOptions)); +static cl::opt<std::string> + ExportFixes("export-fixes", + cl::desc("YAML file to store suggested fixes in."), + cl::value_desc("filename"), cl::cat(ClangRenameOptions)); +static cl::opt<std::string> + Input("input", cl::desc("YAML file to load oldname-newname pairs from."), + cl::Optional, cl::cat(ClangRenameOptions)); - if (Func) { - std::string Invocation = std::string(argv[0]) + " " + argv[1]; - argv[1] = Invocation.c_str(); - return Func(argc - 1, argv + 1); - } else { - return renameAtMain(argc, argv); - } - } - - helpMain(argc, argv); - return 1; -} - -int subcommandMain(bool isRenameAll, int argc, const char **argv) { - cl::OptionCategory *Category = nullptr; - const char *Usage = nullptr; - if (isRenameAll) { - Category = &ClangRenameAllCategory; - Usage = RenameAllUsage; - } else { - Category = &ClangRenameAtCategory; - Usage = RenameAtUsage; - } - - cl::list<std::string> NewNames( - "new-name", cl::desc("The new name to change the symbol to."), - (isRenameAll ? cl::ZeroOrMore : cl::Required), cl::cat(*Category)); - cl::list<unsigned> SymbolOffsets( - "offset", - cl::desc("Locates the symbol by offset as opposed to <line>:<column>."), - (isRenameAll ? cl::ZeroOrMore : cl::Required), cl::cat(*Category)); - cl::list<std::string> OldNames( - "old-name", - cl::desc( - "The fully qualified name of the symbol, if -offset is not used."), - (isRenameAll ? cl::ZeroOrMore : cl::Optional), - cl::cat(ClangRenameAllCategory)); - cl::opt<bool> Inplace("i", cl::desc("Overwrite edited <file>s."), - cl::cat(*Category)); - cl::opt<bool> PrintName( - "pn", - cl::desc("Print the found symbol's name prior to renaming to stderr."), - cl::cat(ClangRenameAtCategory)); - cl::opt<bool> PrintLocations( - "pl", cl::desc("Print the locations affected by renaming to stderr."), - cl::cat(ClangRenameAtCategory)); - cl::opt<std::string> ExportFixes( - "export-fixes", cl::desc("YAML file to store suggested fixes in."), - cl::value_desc("filename"), cl::cat(*Category)); - cl::opt<std::string> Input( - "input", cl::desc("YAML file to load oldname-newname pairs from."), - cl::Optional, cl::cat(ClangRenameAllCategory)); - - tooling::CommonOptionsParser OP(argc, argv, *Category, Usage); +int main(int argc, const char **argv) { + tooling::CommonOptionsParser OP(argc, argv, ClangRenameOptions); if (!Input.empty()) { - // Populate OldNames and NewNames from a YAML file. + // Populate QualifiedNames and NewNames from a YAML file. ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer = llvm::MemoryBuffer::getFile(Input); if (!Buffer) { @@ -159,8 +113,8 @@ int subcommandMain(bool isRenameAll, int argc, const char **argv) { llvm::yaml::Input YAML(Buffer.get()->getBuffer()); YAML >> Infos; for (const auto &Info : Infos) { - if (!Info.OldName.empty()) - OldNames.push_back(Info.OldName); + if (!Info.QualifiedName.empty()) + QualifiedNames.push_back(Info.QualifiedName); else SymbolOffsets.push_back(Info.Offset); NewNames.push_back(Info.NewName); @@ -168,18 +122,23 @@ int subcommandMain(bool isRenameAll, int argc, const char **argv) { } // Check the arguments for correctness. - if (NewNames.empty()) { - errs() << "clang-rename: either -new-name or -input is required.\n\n"; + errs() << "clang-rename: -new-name must be specified.\n\n"; + exit(1); + } + + if (SymbolOffsets.empty() == QualifiedNames.empty()) { + errs() << "clang-rename: -offset and -qualified-name can't be present at " + "the same time.\n"; exit(1); } // Check if NewNames is a valid identifier in C++17. + LangOptions Options; + Options.CPlusPlus = true; + Options.CPlusPlus1z = true; + IdentifierTable Table(Options); for (const auto &NewName : NewNames) { - LangOptions Options; - Options.CPlusPlus = true; - Options.CPlusPlus1z = true; - IdentifierTable Table(Options); auto NewNameTokKind = Table.get(NewName).getTokenID(); if (!tok::isAnyIdentifier(NewNameTokKind)) { errs() << "ERROR: new name is not a valid identifier in C++17.\n\n"; @@ -187,55 +146,38 @@ int subcommandMain(bool isRenameAll, int argc, const char **argv) { } } - if (!OldNames.empty() && OldNames.size() != NewNames.size()) { - errs() << "clang-rename: number of old names (" << OldNames.size() - << ") do not equal to number of new names (" << NewNames.size() - << ").\n\n"; - cl::PrintHelpMessage(); - exit(1); - } - - if (!SymbolOffsets.empty() && SymbolOffsets.size() != NewNames.size()) { - errs() << "clang-rename: number of symbol offsets (" << SymbolOffsets.size() - << ") do not equal to number of new names (" << NewNames.size() + if (SymbolOffsets.size() + QualifiedNames.size() != NewNames.size()) { + errs() << "clang-rename: number of symbol offsets(" << SymbolOffsets.size() + << ") + number of qualified names (" << QualifiedNames.size() + << ") must be equal to number of new names(" << NewNames.size() << ").\n\n"; cl::PrintHelpMessage(); exit(1); } - std::vector<std::vector<std::string>> USRList; - std::vector<std::string> PrevNames; auto Files = OP.getSourcePathList(); tooling::RefactoringTool Tool(OP.getCompilations(), Files); - unsigned Count = OldNames.size() ? OldNames.size() : SymbolOffsets.size(); - for (unsigned I = 0; I < Count; ++I) { - unsigned SymbolOffset = SymbolOffsets.empty() ? 0 : SymbolOffsets[I]; - const std::string &OldName = OldNames.empty() ? std::string() : OldNames[I]; - - // Get the USRs. - rename::USRFindingAction USRAction(SymbolOffset, OldName); - - // Find the USRs. - Tool.run(tooling::newFrontendActionFactory(&USRAction).get()); - const auto &USRs = USRAction.getUSRs(); - USRList.push_back(USRs); - const auto &PrevName = USRAction.getUSRSpelling(); - PrevNames.push_back(PrevName); - - if (PrevName.empty()) { - // An error should have already been printed. - exit(1); + rename::USRFindingAction FindingAction(SymbolOffsets, QualifiedNames); + Tool.run(tooling::newFrontendActionFactory(&FindingAction).get()); + const std::vector<std::vector<std::string>> &USRList = + FindingAction.getUSRList(); + const std::vector<std::string> &PrevNames = FindingAction.getUSRSpellings(); + if (PrintName) { + for (const auto &PrevName : PrevNames) { + outs() << "clang-rename found name: " << PrevName << '\n'; } + } - if (PrintName) { - errs() << "clang-rename: found name: " << PrevName << '\n'; - } + if (FindingAction.errorOccurred()) { + // Diagnostics are already issued at this point. + exit(1); } // Perform the renaming. rename::RenamingAction RenameAction(NewNames, PrevNames, USRList, Tool.getReplacements(), PrintLocations); - auto Factory = tooling::newFrontendActionFactory(&RenameAction); + std::unique_ptr<tooling::FrontendActionFactory> Factory = + tooling::newFrontendActionFactory(&RenameAction); int ExitCode; if (Inplace) { @@ -287,24 +229,3 @@ int subcommandMain(bool isRenameAll, int argc, const char **argv) { exit(ExitCode); } - -/// \brief Top level help. -/// FIXME It would be better if this could be auto-generated. -static int helpMain(int argc, const char *argv[]) { - errs() << "Usage: clang-rename {rename-at|rename-all} [OPTION]...\n\n" - "A tool to rename symbols in C/C++ code.\n\n" - "Subcommands:\n" - " rename-at: Perform rename off of a location in a file. (This " - "is the default.)\n" - " rename-all: Perform rename of all symbols matching one or more " - "fully qualified names.\n"; - return 0; -} - -static int renameAtMain(int argc, const char *argv[]) { - return subcommandMain(false, argc, argv); -} - -static int renameAllMain(int argc, const char *argv[]) { - return subcommandMain(true, argc, argv); -} |