summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clang-rename/tool/ClangRename.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/clang-rename/tool/ClangRename.cpp')
-rw-r--r--clang-tools-extra/clang-rename/tool/ClangRename.cpp211
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);
-}
OpenPOWER on IntegriCloud