From e5e7e153b5c7691b861b014844e760dccca42a16 Mon Sep 17 00:00:00 2001 From: Kirill Bobyrev Date: Fri, 16 Sep 2016 08:45:19 +0000 Subject: [PATCH] [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 --- .../clang-rename/USRFindingAction.cpp | 115 ++++++----- clang-tools-extra/clang-rename/USRFindingAction.h | 28 +-- .../clang-rename/tool/ClangRename.cpp | 211 +++++++-------------- clang-tools-extra/docs/clang-rename.rst | 106 ++++------- .../test/clang-rename/ClassFindByName.cpp | 2 +- .../test/clang-rename/ClassTestMulti.cpp | 2 +- .../test/clang-rename/ClassTestMultiByName.cpp | 2 +- .../test/clang-rename/ClassTestMultiByNameYAML.cpp | 10 - .../clang-rename/FunctionWithClassFindByName.cpp | 2 +- ...yNameYAMLRenameAt.yaml => OffsetToNewName.yaml} | 0 ...LRenameAll.yaml => QualifiedNameToNewName.yaml} | 4 +- .../test/clang-rename/InvalidOldName.cpp | 2 - clang-tools-extra/test/clang-rename/NoNewName.cpp | 2 +- clang-tools-extra/test/clang-rename/YAMLInput.cpp | 10 + clang-tools-extra/unittests/CMakeLists.txt | 1 - .../unittests/clang-rename/CMakeLists.txt | 25 --- .../unittests/clang-rename/USRLocFindingTest.cpp | 83 -------- 17 files changed, 211 insertions(+), 394 deletions(-) delete mode 100644 clang-tools-extra/test/clang-rename/ClassTestMultiByNameYAML.cpp rename clang-tools-extra/test/clang-rename/Inputs/{ClassTestMultiByNameYAMLRenameAt.yaml => OffsetToNewName.yaml} (100%) rename clang-tools-extra/test/clang-rename/Inputs/{ClassTestMultiByNameYAMLRenameAll.yaml => QualifiedNameToNewName.yaml} (54%) delete mode 100644 clang-tools-extra/test/clang-rename/InvalidOldName.cpp create mode 100644 clang-tools-extra/test/clang-rename/YAMLInput.cpp delete mode 100644 clang-tools-extra/unittests/clang-rename/CMakeLists.txt delete mode 100644 clang-tools-extra/unittests/clang-rename/USRLocFindingTest.cpp diff --git a/clang-tools-extra/clang-rename/USRFindingAction.cpp b/clang-tools-extra/clang-rename/USRFindingAction.cpp index 1383f8f..e04362b9 100644 --- a/clang-tools-extra/clang-rename/USRFindingAction.cpp +++ b/clang-tools-extra/clang-rename/USRFindingAction.cpp @@ -28,6 +28,7 @@ #include "clang/Tooling/CommonOptionsParser.h" #include "clang/Tooling/Refactoring.h" #include "clang/Tooling/Tooling.h" + #include #include #include @@ -45,11 +46,10 @@ namespace { // to virtual method. class AdditionalUSRFinder : public RecursiveASTVisitor { public: - explicit AdditionalUSRFinder(const Decl *FoundDecl, ASTContext &Context, - std::vector *USRs) - : FoundDecl(FoundDecl), Context(Context), USRs(USRs) {} + AdditionalUSRFinder(const Decl *FoundDecl, ASTContext &Context) + : FoundDecl(FoundDecl), Context(Context) {} - void Find() { + std::vector Find() { // Fill OverriddenMethods and PartialSpecs storages. TraverseDecl(Context.getTranslationUnitDecl()); if (const auto *MethodDecl = dyn_cast(FoundDecl)) { @@ -66,7 +66,7 @@ public: } else { USRSet.insert(getUSRForDecl(FoundDecl)); } - USRs->insert(USRs->end(), USRSet.begin(), USRSet.end()); + return std::vector(USRSet.begin(), USRSet.end()); } bool VisitCXXMethodDecl(const CXXMethodDecl *MethodDecl) { @@ -129,69 +129,98 @@ private: const Decl *FoundDecl; ASTContext &Context; - std::vector *USRs; std::set USRSet; std::vector OverriddenMethods; std::vector PartialSpecs; }; } // namespace -struct NamedDeclFindingConsumer : public ASTConsumer { - void HandleTranslationUnit(ASTContext &Context) override { - const SourceManager &SourceMgr = Context.getSourceManager(); - // The file we look for the USR in will always be the main source file. +class NamedDeclFindingConsumer : public ASTConsumer { +public: + NamedDeclFindingConsumer(ArrayRef SymbolOffsets, + ArrayRef QualifiedNames, + std::vector &SpellingNames, + std::vector> &USRList, + bool &ErrorOccurred) + : SymbolOffsets(SymbolOffsets), QualifiedNames(QualifiedNames), + SpellingNames(SpellingNames), USRList(USRList), + ErrorOccurred(ErrorOccurred) {} + +private: + bool FindSymbol(ASTContext &Context, const SourceManager &SourceMgr, + unsigned SymbolOffset, const std::string &QualifiedName) { + DiagnosticsEngine &Engine = Context.getDiagnostics(); + const SourceLocation Point = SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()) .getLocWithOffset(SymbolOffset); - if (!Point.isValid()) - return; - const NamedDecl *FoundDecl = nullptr; - if (OldName.empty()) - FoundDecl = getNamedDeclAt(Context, Point); - else - FoundDecl = getNamedDeclFor(Context, OldName); + + if (!Point.isValid()) { + ErrorOccurred = true; + unsigned InvalidOffset = Engine.getCustomDiagID( + DiagnosticsEngine::Error, + "SourceLocation in file %0 at offset %1 is invalid"); + Engine.Report(Point, InvalidOffset) << SourceMgr.getFilename(Point) + << SymbolOffset; + return false; + } + + const NamedDecl *FoundDecl = QualifiedName.empty() + ? getNamedDeclAt(Context, Point) + : getNamedDeclFor(Context, QualifiedName); + if (FoundDecl == nullptr) { - if (OldName.empty()) { + if (QualifiedName.empty()) { FullSourceLoc FullLoc(Point, SourceMgr); - errs() << "clang-rename: could not find symbol at " - << SourceMgr.getFilename(Point) << ":" - << FullLoc.getSpellingLineNumber() << ":" - << FullLoc.getSpellingColumnNumber() << " (offset " - << SymbolOffset << ").\n"; - } else { - errs() << "clang-rename: could not find symbol " << OldName << ".\n"; + unsigned CouldNotFindSymbolAt = Engine.getCustomDiagID( + DiagnosticsEngine::Error, + "clang-rename could not find symbol (offset %0)"); + Engine.Report(Point, CouldNotFindSymbolAt) << SymbolOffset; + ErrorOccurred = true; + return false; } - return; + unsigned CouldNotFindSymbolNamed = Engine.getCustomDiagID( + DiagnosticsEngine::Error, "clang-rename could not find symbol %0"); + Engine.Report(CouldNotFindSymbolNamed) << QualifiedName; + ErrorOccurred = true; + return false; } - // If FoundDecl is a constructor or destructor, we want to instead take the - // Decl of the corresponding class. + // If FoundDecl is a constructor or destructor, we want to instead take + // the Decl of the corresponding class. if (const auto *CtorDecl = dyn_cast(FoundDecl)) FoundDecl = CtorDecl->getParent(); else if (const auto *DtorDecl = dyn_cast(FoundDecl)) FoundDecl = DtorDecl->getParent(); - *SpellingName = FoundDecl->getNameAsString(); + SpellingNames.push_back(FoundDecl->getNameAsString()); + AdditionalUSRFinder Finder(FoundDecl, Context); + USRList.push_back(Finder.Find()); + return true; + } - AdditionalUSRFinder Finder(FoundDecl, Context, USRs); - Finder.Find(); + void HandleTranslationUnit(ASTContext &Context) override { + const SourceManager &SourceMgr = Context.getSourceManager(); + for (unsigned Offset : SymbolOffsets) { + if (!FindSymbol(Context, SourceMgr, Offset, "")) + return; + } + for (const std::string &QualifiedName : QualifiedNames) { + if (!FindSymbol(Context, SourceMgr, 0, QualifiedName)) + return; + } } - unsigned SymbolOffset; - std::string OldName; - std::string *SpellingName; - std::vector *USRs; + ArrayRef SymbolOffsets; + ArrayRef QualifiedNames; + std::vector &SpellingNames; + std::vector> &USRList; + bool &ErrorOccurred; }; std::unique_ptr USRFindingAction::newASTConsumer() { - std::unique_ptr Consumer( - new NamedDeclFindingConsumer); - SpellingName = ""; - Consumer->SymbolOffset = SymbolOffset; - Consumer->OldName = OldName; - Consumer->USRs = &USRs; - Consumer->SpellingName = &SpellingName; - return std::move(Consumer); + return llvm::make_unique( + SymbolOffsets, QualifiedNames, SpellingNames, USRList, ErrorOccurred); } } // namespace rename diff --git a/clang-tools-extra/clang-rename/USRFindingAction.h b/clang-tools-extra/clang-rename/USRFindingAction.h index df9a7a2..42c233d 100644 --- a/clang-tools-extra/clang-rename/USRFindingAction.h +++ b/clang-tools-extra/clang-rename/USRFindingAction.h @@ -15,7 +15,11 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDING_ACTION_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDING_ACTION_H -#include "clang/Frontend/FrontendAction.h" +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/ArrayRef.h" + +#include +#include namespace clang { class ASTConsumer; @@ -25,20 +29,22 @@ class NamedDecl; namespace rename { struct USRFindingAction { - USRFindingAction(unsigned Offset, const std::string &Name) - : SymbolOffset(Offset), OldName(Name) {} + USRFindingAction(ArrayRef SymbolOffsets, + ArrayRef QualifiedNames) + : SymbolOffsets(SymbolOffsets), QualifiedNames(QualifiedNames), + ErrorOccurred(false) {} std::unique_ptr newASTConsumer(); - // \brief get the spelling of the USR(s) as it would appear in source files. - const std::string &getUSRSpelling() { return SpellingName; } - - const std::vector &getUSRs() { return USRs; } + ArrayRef getUSRSpellings() { return SpellingNames; } + ArrayRef> getUSRList() { return USRList; } + bool errorOccurred() { return ErrorOccurred; } private: - unsigned SymbolOffset; - std::string OldName; - std::string SpellingName; - std::vector USRs; + std::vector SymbolOffsets; + std::vector QualifiedNames; + std::vector SpellingNames; + std::vector> USRList; + bool ErrorOccurred; }; } // namespace rename diff --git a/clang-tools-extra/clang-rename/tool/ClangRename.cpp b/clang-tools-extra/clang-rename/tool/ClangRename.cpp index 8e59994..9cc29ff 100644 --- a/clang-tools-extra/clang-rename/tool/ClangRename.cpp +++ b/clang-tools-extra/clang-rename/tool/ClangRename.cpp @@ -38,28 +38,12 @@ #include 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 in\n\ -. 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 { 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 { } // end namespace yaml } // end namespace llvm -int main(int argc, const char **argv) { - if (argc > 1) { - using MainFunction = std::function; - MainFunction Func = StringSwitch(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 SymbolOffsets( + "offset", + cl::desc("Locates the symbol by offset as opposed to :."), + cl::ZeroOrMore, cl::cat(ClangRenameOptions)); +static cl::opt Inplace("i", cl::desc("Overwrite edited s."), + cl::cat(ClangRenameOptions)); +static cl::list + QualifiedNames("qualified-name", + cl::desc("The fully qualified name of the symbol."), + cl::ZeroOrMore, cl::cat(ClangRenameOptions)); + +static cl::list + NewNames("new-name", cl::desc("The new name to change the symbol to."), + cl::ZeroOrMore, cl::cat(ClangRenameOptions)); +static cl::opt PrintName( + "pn", + cl::desc("Print the found symbol's name prior to renaming to stderr."), + cl::cat(ClangRenameOptions)); +static cl::opt PrintLocations( + "pl", cl::desc("Print the locations affected by renaming to stderr."), + cl::cat(ClangRenameOptions)); +static cl::opt + ExportFixes("export-fixes", + cl::desc("YAML file to store suggested fixes in."), + cl::value_desc("filename"), cl::cat(ClangRenameOptions)); +static cl::opt + 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 NewNames( - "new-name", cl::desc("The new name to change the symbol to."), - (isRenameAll ? cl::ZeroOrMore : cl::Required), cl::cat(*Category)); - cl::list SymbolOffsets( - "offset", - cl::desc("Locates the symbol by offset as opposed to :."), - (isRenameAll ? cl::ZeroOrMore : cl::Required), cl::cat(*Category)); - cl::list 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 Inplace("i", cl::desc("Overwrite edited s."), - cl::cat(*Category)); - cl::opt PrintName( - "pn", - cl::desc("Print the found symbol's name prior to renaming to stderr."), - cl::cat(ClangRenameAtCategory)); - cl::opt PrintLocations( - "pl", cl::desc("Print the locations affected by renaming to stderr."), - cl::cat(ClangRenameAtCategory)); - cl::opt ExportFixes( - "export-fixes", cl::desc("YAML file to store suggested fixes in."), - cl::value_desc("filename"), cl::cat(*Category)); - cl::opt 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> 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> USRList; - std::vector 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> &USRList = + FindingAction.getUSRList(); + const std::vector &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 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); -} diff --git a/clang-tools-extra/docs/clang-rename.rst b/clang-tools-extra/docs/clang-rename.rst index 8e5aba6..bffedbf 100644 --- a/clang-tools-extra/docs/clang-rename.rst +++ b/clang-tools-extra/docs/clang-rename.rst @@ -52,114 +52,86 @@ editors, such as Vim and Emacs, and improve the workflow of users. Although a command line interface exists, it is highly recommended to use the text editor interface instead for better experience. -You can also identify one or more symbols to be renamed by giving the fully qualified -name: +You can also identify one or more symbols to be renamed by giving the fully +qualified name: .. code-block:: console - $ clang-rename rename-all -old-name=foo -new-name=bar test.cpp + $ clang-rename -qualified-name=foo -new-name=bar test.cpp +Renaming multiple symbols at once is supported, too. However, +:program:`clang-rename` doesn't accept both `-offset` and `-qualified-name` at +the same time. So, you can either specify multiple `-offset` or +`-qualified-name`. -Alternatively, old name / new name pairs can be put into a YAML file: - -.. code-block:: yaml - - --- - - OldName: foo - NewName: bar - ... +.. code-block:: console + $ clang-rename -offset=42 -new-name=bar1 -offset=150 -new-name=bar2 test.cpp -That way you can avoid spelling out all the names as command line arguments: +or .. code-block:: console - $ clang-rename rename-all -input=test.yaml test.cpp + $ clang-rename -qualified-name=foo1 -new-name=bar1 -qualified-name=foo2 -new-name=bar2 test.cpp -The YAML file also supports offsets: +Alternatively, {offset | qualified-name} / new-name pairs can be put into a YAML +file: .. code-block:: yaml --- - Offset: 42 - NewName: foo + NewName: bar1 + - Offset: 150 + NewName: bar2 ... +or -:program:`clang-rename` offers the following options: - -.. code-block:: console - - $ clang-rename -help - Usage: clang-rename {rename-at|rename-all} [OPTION]... - - A tool to rename symbols in C/C++ code. +.. code-block:: yaml - Subcommands: - rename-at: Perform rename off of a location in a file. (This is the default.) - rename-all: Perform rename of all symbols matching one or more fully qualified names. + --- + - QualifiedName: foo1 + NewName: bar1 + - QualifiedName: foo2 + NewName: bar2 + ... +That way you can avoid spelling out all the names as command line arguments: .. code-block:: console - $ clang-rename rename-at -help - OVERVIEW: A tool to rename symbols in C/C++ code. - clang-rename renames every occurrence of a symbol found at in - . If -i is specified, the edited files are overwritten to disk. - Otherwise, the results are written to stdout. - - USAGE: clang-rename rename-at [subcommand] [options] [... ] - - OPTIONS: - - Generic Options: - - -help - Display available options (-help-hidden for more) - -help-list - Display list of available options (-help-list-hidden for more) - -version - Display the version of this program - - clang-rename rename-at options: - - -export-fixes= - YAML file to store suggested fixes in. - -extra-arg= - Additional argument to append to the compiler command line. - -extra-arg-before= - Additional argument to prepend to the compiler command line. - -i - Overwrite edited s. - -new-name= - The new name to change the symbol to. - -offset= - Locates the symbol by offset as opposed to :. - -p= - Build path. - -pl - Print the locations affected by renaming to stderr. - -pn - Print the found symbol's name prior to renaming to stderr. + $ clang-rename -input=test.yaml test.cpp +:program:`clang-rename` offers the following options: .. code-block:: console - $ clang-rename rename-all -help - OVERVIEW: A tool to rename symbols in C/C++ code. - clang-rename renames every occurrence of a symbol named . - - USAGE: clang-rename rename-all [subcommand] [options] [... ] + $ clang-rename --help + USAGE: clang-rename [subcommand] [options] [... ] OPTIONS: Generic Options: - -help - Display available options (-help-hidden for more). - -help-list - Display list of available options (-help-list-hidden for more). - -version - Display the version of this program. + -help - Display available options (-help-hidden for more) + -help-list - Display list of available options (-help-list-hidden for more) + -version - Display the version of this program - clang-rename rename-all options: + clang-rename common options: -export-fixes= - YAML file to store suggested fixes in. - -extra-arg= - Additional argument to append to the compiler command line. - -extra-arg-before= - Additional argument to prepend to the compiler command line. + -extra-arg= - Additional argument to append to the compiler command line + -extra-arg-before= - Additional argument to prepend to the compiler command line -i - Overwrite edited s. -input= - YAML file to load oldname-newname pairs from. -new-name= - The new name to change the symbol to. -offset= - Locates the symbol by offset as opposed to :. - -old-name= - The fully qualified name of the symbol, if -offset is not used. - -p= - Build path. - + -p= - Build path + -pl - Print the locations affected by renaming to stderr. + -pn - Print the found symbol's name prior to renaming to stderr. + -qualified-name= - The fully qualified name of the symbol. Vim Integration =============== diff --git a/clang-tools-extra/test/clang-rename/ClassFindByName.cpp b/clang-tools-extra/test/clang-rename/ClassFindByName.cpp index 42b4299..4430891 100644 --- a/clang-tools-extra/test/clang-rename/ClassFindByName.cpp +++ b/clang-tools-extra/test/clang-rename/ClassFindByName.cpp @@ -7,4 +7,4 @@ int main() { } // Test 1. -// RUN: clang-rename rename-all -old-name=Foo -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s +// RUN: clang-rename -qualified-name=Foo -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s diff --git a/clang-tools-extra/test/clang-rename/ClassTestMulti.cpp b/clang-tools-extra/test/clang-rename/ClassTestMulti.cpp index 22911df..81e65c7 100644 --- a/clang-tools-extra/test/clang-rename/ClassTestMulti.cpp +++ b/clang-tools-extra/test/clang-rename/ClassTestMulti.cpp @@ -5,7 +5,7 @@ class Foo2 /* Offset 2 */ { // CHECK: class Bar2 /* Offset 2 */ { }; // Test 1. -// RUN: clang-rename rename-all -offset=6 -new-name=Bar1 -offset=76 -new-name=Bar2 %s -- | sed 's,//.*,,' | FileCheck %s +// RUN: clang-rename -offset=6 -new-name=Bar1 -offset=76 -new-name=Bar2 %s -- | sed 's,//.*,,' | FileCheck %s // To find offsets after modifying the file, use: // grep -Ubo 'Foo.*' diff --git a/clang-tools-extra/test/clang-rename/ClassTestMultiByName.cpp b/clang-tools-extra/test/clang-rename/ClassTestMultiByName.cpp index 9052750..61b69a1 100644 --- a/clang-tools-extra/test/clang-rename/ClassTestMultiByName.cpp +++ b/clang-tools-extra/test/clang-rename/ClassTestMultiByName.cpp @@ -5,4 +5,4 @@ class Foo2 { // CHECK: class Bar2 }; // Test 1. -// RUN: clang-rename rename-all -old-name=Foo1 -new-name=Bar1 -old-name=Foo2 -new-name=Bar2 %s -- | sed 's,//.*,,' | FileCheck %s +// RUN: clang-rename -qualified-name=Foo1 -new-name=Bar1 -qualified-name=Foo2 -new-name=Bar2 %s -- | sed 's,//.*,,' | FileCheck %s diff --git a/clang-tools-extra/test/clang-rename/ClassTestMultiByNameYAML.cpp b/clang-tools-extra/test/clang-rename/ClassTestMultiByNameYAML.cpp deleted file mode 100644 index ecf506f4..0000000 --- a/clang-tools-extra/test/clang-rename/ClassTestMultiByNameYAML.cpp +++ /dev/null @@ -1,10 +0,0 @@ -class Foo1 { // CHECK: class Bar1 -}; - -class Foo2 { // CHECK: class Bar2 -}; - -// Test 1. -// RUN: clang-rename rename-all -input %S/Inputs/ClassTestMultiByNameYAMLRenameAll.yaml %s -- | sed 's,//.*,,' | FileCheck %s -// Test 2. -// RUN: clang-rename rename-all -input %S/Inputs/ClassTestMultiByNameYAMLRenameAt.yaml %s -- | sed 's,//.*,,' | FileCheck %s diff --git a/clang-tools-extra/test/clang-rename/FunctionWithClassFindByName.cpp b/clang-tools-extra/test/clang-rename/FunctionWithClassFindByName.cpp index d197ca1..2cae09a 100644 --- a/clang-tools-extra/test/clang-rename/FunctionWithClassFindByName.cpp +++ b/clang-tools-extra/test/clang-rename/FunctionWithClassFindByName.cpp @@ -9,4 +9,4 @@ int main() { return 0; } -// RUN: clang-rename rename-all -old-name=Foo -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s +// RUN: clang-rename -qualified-name=Foo -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s diff --git a/clang-tools-extra/test/clang-rename/Inputs/ClassTestMultiByNameYAMLRenameAt.yaml b/clang-tools-extra/test/clang-rename/Inputs/OffsetToNewName.yaml similarity index 100% rename from clang-tools-extra/test/clang-rename/Inputs/ClassTestMultiByNameYAMLRenameAt.yaml rename to clang-tools-extra/test/clang-rename/Inputs/OffsetToNewName.yaml diff --git a/clang-tools-extra/test/clang-rename/Inputs/ClassTestMultiByNameYAMLRenameAll.yaml b/clang-tools-extra/test/clang-rename/Inputs/QualifiedNameToNewName.yaml similarity index 54% rename from clang-tools-extra/test/clang-rename/Inputs/ClassTestMultiByNameYAMLRenameAll.yaml rename to clang-tools-extra/test/clang-rename/Inputs/QualifiedNameToNewName.yaml index cb381b3..6e37836 100644 --- a/clang-tools-extra/test/clang-rename/Inputs/ClassTestMultiByNameYAMLRenameAll.yaml +++ b/clang-tools-extra/test/clang-rename/Inputs/QualifiedNameToNewName.yaml @@ -1,6 +1,6 @@ --- -- OldName: Foo1 +- QualifiedName: Foo1 NewName: Bar1 -- OldName: Foo2 +- QualifiedName: Foo2 NewName: Bar2 ... diff --git a/clang-tools-extra/test/clang-rename/InvalidOldName.cpp b/clang-tools-extra/test/clang-rename/InvalidOldName.cpp deleted file mode 100644 index 11f2763..0000000 --- a/clang-tools-extra/test/clang-rename/InvalidOldName.cpp +++ /dev/null @@ -1,2 +0,0 @@ -// RUN: not clang-rename rename-all -new-name=Foo -old-name=Bar %s -- 2>&1 | FileCheck %s -// CHECK: clang-rename: could not find symbol Bar. diff --git a/clang-tools-extra/test/clang-rename/NoNewName.cpp b/clang-tools-extra/test/clang-rename/NoNewName.cpp index 11a637b..4f882d8 100644 --- a/clang-tools-extra/test/clang-rename/NoNewName.cpp +++ b/clang-tools-extra/test/clang-rename/NoNewName.cpp @@ -1,4 +1,4 @@ // Check for an error while -new-name argument has not been passed to // clang-rename. // RUN: not clang-rename -offset=133 %s 2>&1 | FileCheck %s -// CHECK: clang-rename: for the -new-name option: must be specified +// CHECK: clang-rename: -new-name must be specified. diff --git a/clang-tools-extra/test/clang-rename/YAMLInput.cpp b/clang-tools-extra/test/clang-rename/YAMLInput.cpp new file mode 100644 index 0000000..55dbc6d --- /dev/null +++ b/clang-tools-extra/test/clang-rename/YAMLInput.cpp @@ -0,0 +1,10 @@ +class Foo1 { // CHECK: class Bar1 +}; + +class Foo2 { // CHECK: class Bar2 +}; + +// Test 1. +// RUN: clang-rename -input %S/Inputs/OffsetToNewName.yaml %s -- | sed 's,//.*,,' | FileCheck %s +// Test 2. +// RUN: clang-rename -input %S/Inputs/QualifiedNameToNewName.yaml %s -- | sed 's,//.*,,' | FileCheck %s diff --git a/clang-tools-extra/unittests/CMakeLists.txt b/clang-tools-extra/unittests/CMakeLists.txt index aa56f04..24b7eb0 100644 --- a/clang-tools-extra/unittests/CMakeLists.txt +++ b/clang-tools-extra/unittests/CMakeLists.txt @@ -6,7 +6,6 @@ function(add_extra_unittest test_dirname) endfunction() add_subdirectory(clang-apply-replacements) -add_subdirectory(clang-rename) add_subdirectory(clang-query) add_subdirectory(clang-tidy) add_subdirectory(include-fixer) diff --git a/clang-tools-extra/unittests/clang-rename/CMakeLists.txt b/clang-tools-extra/unittests/clang-rename/CMakeLists.txt deleted file mode 100644 index 5e999bc..0000000 --- a/clang-tools-extra/unittests/clang-rename/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -set(LLVM_LINK_COMPONENTS - support - ) - -get_filename_component(CLANG_RENAME_SOURCE_DIR - ${CMAKE_CURRENT_SOURCE_DIR}/../../clang-rename REALPATH) -include_directories( - ${CLANG_RENAME_SOURCE_DIR} - ) - -add_extra_unittest(ClangRenameTests - USRLocFindingTest.cpp - ${CLANG_RENAME_SOURCE_DIR}/USRFinder.cpp - ${CLANG_RENAME_SOURCE_DIR}/USRFindingAction.cpp - ) - -target_link_libraries(ClangRenameTests - clangAST - clangASTMatchers - clangBasic - clangFrontend - clangIndex - clangLex - clangTooling - ) diff --git a/clang-tools-extra/unittests/clang-rename/USRLocFindingTest.cpp b/clang-tools-extra/unittests/clang-rename/USRLocFindingTest.cpp deleted file mode 100644 index f216119..0000000 --- a/clang-tools-extra/unittests/clang-rename/USRLocFindingTest.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#include "USRFindingAction.h" -#include "clang/Tooling/Tooling.h" -#include "gtest/gtest.h" -#include -#include -#include - -namespace clang { -namespace rename { -namespace test { - -// Determines if the symbol group invariants hold. To recap, those invariants -// are: -// (1) All symbols in the same symbol group share the same USR. -// (2) Two symbols from two different groups do not share the same USR. -static void testOffsetGroups(const char *Code, - const std::vector> Groups) { - std::set AllUSRs, CurrUSR; - - for (const auto &Group : Groups) { - // Groups the invariants do not hold then the value of USR is also invalid, - // but at that point the test has already failed and USR ceases to be - // useful. - std::string USR; - for (const auto &Offset : Group) { - USRFindingAction Action(Offset, std::string()); - auto Factory = tooling::newFrontendActionFactory(&Action); - EXPECT_TRUE(tooling::runToolOnCode(Factory->create(), Code)); - const auto &USRs = Action.getUSRs(); - EXPECT_EQ(1u, USRs.size()); - USR = USRs[0]; - CurrUSR.insert(USR); - } - EXPECT_EQ(1u, CurrUSR.size()); - CurrUSR.clear(); - AllUSRs.insert(USR); - } - - EXPECT_EQ(Groups.size(), AllUSRs.size()); -} - - -TEST(USRLocFinding, FindsVarUSR) { - const char VarTest[] = "\n\ -namespace A {\n\ -int foo;\n\ -}\n\ -int foo;\n\ -int bar = foo;\n\ -int baz = A::foo;\n\ -void fun1() {\n\ - struct {\n\ - int foo;\n\ - } b = { 100 };\n\ - int foo = 100;\n\ - baz = foo;\n\ - {\n\ - extern int foo;\n\ - baz = foo;\n\ - foo = A::foo + baz;\n\ - A::foo = b.foo;\n\ - }\n\ - foo = b.foo;\n\ -}\n"; - std::vector> VarTestOffsets(3); - VarTestOffsets[0].push_back(19); - VarTestOffsets[0].push_back(63); - VarTestOffsets[0].push_back(205); - VarTestOffsets[0].push_back(223); - VarTestOffsets[1].push_back(30); - VarTestOffsets[1].push_back(45); - VarTestOffsets[1].push_back(172); - VarTestOffsets[1].push_back(187); - VarTestOffsets[2].push_back(129); - VarTestOffsets[2].push_back(148); - VarTestOffsets[2].push_back(242); - - testOffsetGroups(VarTest, VarTestOffsets); -} - -} // namespace test -} // namespace rename -} // namespace clang -- 2.7.4