forked from OSchip/llvm-project
parent
d73ef1738b
commit
8d78af4bb4
|
@ -28,7 +28,6 @@
|
|||
#include "clang/Tooling/CommonOptionsParser.h"
|
||||
#include "clang/Tooling/Refactoring.h"
|
||||
#include "clang/Tooling/Tooling.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
@ -46,10 +45,11 @@ namespace {
|
|||
// to virtual method.
|
||||
class AdditionalUSRFinder : public RecursiveASTVisitor<AdditionalUSRFinder> {
|
||||
public:
|
||||
AdditionalUSRFinder(const Decl *FoundDecl, ASTContext &Context)
|
||||
: FoundDecl(FoundDecl), Context(Context) {}
|
||||
explicit AdditionalUSRFinder(const Decl *FoundDecl, ASTContext &Context,
|
||||
std::vector<std::string> *USRs)
|
||||
: FoundDecl(FoundDecl), Context(Context), USRs(USRs) {}
|
||||
|
||||
std::vector<std::string> Find() {
|
||||
void Find() {
|
||||
// Fill OverriddenMethods and PartialSpecs storages.
|
||||
TraverseDecl(Context.getTranslationUnitDecl());
|
||||
if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(FoundDecl)) {
|
||||
|
@ -66,7 +66,7 @@ public:
|
|||
} else {
|
||||
USRSet.insert(getUSRForDecl(FoundDecl));
|
||||
}
|
||||
return std::vector<std::string>(USRSet.begin(), USRSet.end());
|
||||
USRs->insert(USRs->end(), USRSet.begin(), USRSet.end());
|
||||
}
|
||||
|
||||
bool VisitCXXMethodDecl(const CXXMethodDecl *MethodDecl) {
|
||||
|
@ -129,98 +129,69 @@ private:
|
|||
|
||||
const Decl *FoundDecl;
|
||||
ASTContext &Context;
|
||||
std::vector<std::string> *USRs;
|
||||
std::set<std::string> USRSet;
|
||||
std::vector<const CXXMethodDecl *> OverriddenMethods;
|
||||
std::vector<const ClassTemplatePartialSpecializationDecl *> PartialSpecs;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
class NamedDeclFindingConsumer : public ASTConsumer {
|
||||
public:
|
||||
NamedDeclFindingConsumer(ArrayRef<unsigned> SymbolOffsets,
|
||||
ArrayRef<std::string> QualifiedNames,
|
||||
std::vector<std::string> &SpellingNames,
|
||||
std::vector<std::vector<std::string>> &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();
|
||||
|
||||
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.
|
||||
const SourceLocation Point =
|
||||
SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID())
|
||||
.getLocWithOffset(SymbolOffset);
|
||||
|
||||
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 (!Point.isValid())
|
||||
return;
|
||||
const NamedDecl *FoundDecl = nullptr;
|
||||
if (OldName.empty())
|
||||
FoundDecl = getNamedDeclAt(Context, Point);
|
||||
else
|
||||
FoundDecl = getNamedDeclFor(Context, OldName);
|
||||
if (FoundDecl == nullptr) {
|
||||
if (QualifiedName.empty()) {
|
||||
if (OldName.empty()) {
|
||||
FullSourceLoc FullLoc(Point, SourceMgr);
|
||||
unsigned CouldNotFindSymbolAt = Engine.getCustomDiagID(
|
||||
DiagnosticsEngine::Error,
|
||||
"clang-rename could not find symbol (offset %0)");
|
||||
Engine.Report(Point, CouldNotFindSymbolAt) << SymbolOffset;
|
||||
ErrorOccurred = true;
|
||||
return false;
|
||||
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 CouldNotFindSymbolNamed = Engine.getCustomDiagID(
|
||||
DiagnosticsEngine::Error, "clang-rename could not find symbol %0");
|
||||
Engine.Report(CouldNotFindSymbolNamed) << QualifiedName;
|
||||
ErrorOccurred = true;
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
// 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<CXXConstructorDecl>(FoundDecl))
|
||||
FoundDecl = CtorDecl->getParent();
|
||||
else if (const auto *DtorDecl = dyn_cast<CXXDestructorDecl>(FoundDecl))
|
||||
FoundDecl = DtorDecl->getParent();
|
||||
|
||||
SpellingNames.push_back(FoundDecl->getNameAsString());
|
||||
AdditionalUSRFinder Finder(FoundDecl, Context);
|
||||
USRList.push_back(Finder.Find());
|
||||
return true;
|
||||
*SpellingName = FoundDecl->getNameAsString();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
ArrayRef<unsigned> SymbolOffsets;
|
||||
ArrayRef<std::string> QualifiedNames;
|
||||
std::vector<std::string> &SpellingNames;
|
||||
std::vector<std::vector<std::string>> &USRList;
|
||||
bool &ErrorOccurred;
|
||||
unsigned SymbolOffset;
|
||||
std::string OldName;
|
||||
std::string *SpellingName;
|
||||
std::vector<std::string> *USRs;
|
||||
};
|
||||
|
||||
std::unique_ptr<ASTConsumer> USRFindingAction::newASTConsumer() {
|
||||
return llvm::make_unique<NamedDeclFindingConsumer>(
|
||||
SymbolOffsets, QualifiedNames, SpellingNames, USRList, ErrorOccurred);
|
||||
std::unique_ptr<NamedDeclFindingConsumer> Consumer(
|
||||
new NamedDeclFindingConsumer);
|
||||
SpellingName = "";
|
||||
Consumer->SymbolOffset = SymbolOffset;
|
||||
Consumer->OldName = OldName;
|
||||
Consumer->USRs = &USRs;
|
||||
Consumer->SpellingName = &SpellingName;
|
||||
return std::move(Consumer);
|
||||
}
|
||||
|
||||
} // namespace rename
|
||||
|
|
|
@ -15,11 +15,7 @@
|
|||
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDING_ACTION_H
|
||||
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDING_ACTION_H
|
||||
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "clang/Frontend/FrontendAction.h"
|
||||
|
||||
namespace clang {
|
||||
class ASTConsumer;
|
||||
|
@ -29,22 +25,20 @@ class NamedDecl;
|
|||
namespace rename {
|
||||
|
||||
struct USRFindingAction {
|
||||
USRFindingAction(ArrayRef<unsigned> SymbolOffsets,
|
||||
ArrayRef<std::string> QualifiedNames)
|
||||
: SymbolOffsets(SymbolOffsets), QualifiedNames(QualifiedNames),
|
||||
ErrorOccurred(false) {}
|
||||
USRFindingAction(unsigned Offset, const std::string &Name)
|
||||
: SymbolOffset(Offset), OldName(Name) {}
|
||||
std::unique_ptr<ASTConsumer> newASTConsumer();
|
||||
|
||||
ArrayRef<std::string> getUSRSpellings() { return SpellingNames; }
|
||||
ArrayRef<std::vector<std::string>> getUSRList() { return USRList; }
|
||||
bool errorOccurred() { return ErrorOccurred; }
|
||||
// \brief get the spelling of the USR(s) as it would appear in source files.
|
||||
const std::string &getUSRSpelling() { return SpellingName; }
|
||||
|
||||
const std::vector<std::string> &getUSRs() { return USRs; }
|
||||
|
||||
private:
|
||||
std::vector<unsigned> SymbolOffsets;
|
||||
std::vector<std::string> QualifiedNames;
|
||||
std::vector<std::string> SpellingNames;
|
||||
std::vector<std::vector<std::string>> USRList;
|
||||
bool ErrorOccurred;
|
||||
unsigned SymbolOffset;
|
||||
std::string OldName;
|
||||
std::string SpellingName;
|
||||
std::vector<std::string> USRs;
|
||||
};
|
||||
|
||||
} // namespace rename
|
||||
|
|
|
@ -38,12 +38,28 @@
|
|||
#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;
|
||||
};
|
||||
|
||||
|
@ -56,8 +72,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);
|
||||
}
|
||||
};
|
||||
|
@ -65,42 +81,72 @@ template <> struct MappingTraits<RenameAllInfo> {
|
|||
} // end namespace yaml
|
||||
} // end namespace llvm
|
||||
|
||||
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));
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
tooling::CommonOptionsParser OP(argc, argv, ClangRenameOptions);
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
if (!Input.empty()) {
|
||||
// Populate QualifiedNames and NewNames from a YAML file.
|
||||
// Populate OldNames and NewNames from a YAML file.
|
||||
ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer =
|
||||
llvm::MemoryBuffer::getFile(Input);
|
||||
if (!Buffer) {
|
||||
|
@ -113,8 +159,8 @@ int main(int argc, const char **argv) {
|
|||
llvm::yaml::Input YAML(Buffer.get()->getBuffer());
|
||||
YAML >> Infos;
|
||||
for (const auto &Info : Infos) {
|
||||
if (!Info.QualifiedName.empty())
|
||||
QualifiedNames.push_back(Info.QualifiedName);
|
||||
if (!Info.OldName.empty())
|
||||
OldNames.push_back(Info.OldName);
|
||||
else
|
||||
SymbolOffsets.push_back(Info.Offset);
|
||||
NewNames.push_back(Info.NewName);
|
||||
|
@ -122,17 +168,18 @@ int main(int argc, const char **argv) {
|
|||
}
|
||||
|
||||
// Check the arguments for correctness.
|
||||
|
||||
if (NewNames.empty()) {
|
||||
errs() << "clang-rename: -new-name must be specified.\n\n";
|
||||
errs() << "clang-rename: either -new-name or -input is required.\n\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";
|
||||
|
@ -140,38 +187,55 @@ int main(int argc, const char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
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()
|
||||
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);
|
||||
}
|
||||
|
||||
auto Files = OP.getSourcePathList();
|
||||
tooling::RefactoringTool Tool(OP.getCompilations(), Files);
|
||||
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 (!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()
|
||||
<< ").\n\n";
|
||||
cl::PrintHelpMessage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (FindingAction.errorOccurred()) {
|
||||
// Diagnostics are already issued at this point.
|
||||
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);
|
||||
}
|
||||
|
||||
if (PrintName) {
|
||||
errs() << "clang-rename: found name: " << PrevName << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
// Perform the renaming.
|
||||
rename::RenamingAction RenameAction(NewNames, PrevNames, USRList,
|
||||
Tool.getReplacements(), PrintLocations);
|
||||
std::unique_ptr<tooling::FrontendActionFactory> Factory =
|
||||
tooling::newFrontendActionFactory(&RenameAction);
|
||||
auto Factory = tooling::newFrontendActionFactory(&RenameAction);
|
||||
int ExitCode;
|
||||
|
||||
if (Inplace) {
|
||||
|
@ -223,3 +287,24 @@ int main(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);
|
||||
}
|
||||
|
|
|
@ -52,29 +52,21 @@ 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 -qualified-name=foo -new-name=bar test.cpp
|
||||
$ clang-rename rename-all -old-name=foo -new-name=bar test.cpp
|
||||
|
||||
Or even combine it:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ clang-rename -offset=42 -new-name=whatever -qualified-name=foo -new-name=bar test.cpp
|
||||
|
||||
Alternatively, {offset | qualified-name} / new-name pairs can be put into a YAML
|
||||
file:
|
||||
Alternatively, old name / new name pairs can be put into a YAML file:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
- Offset: 42
|
||||
- OldName: foo
|
||||
NewName: bar
|
||||
- QualifiedName: foo
|
||||
NewName: something
|
||||
...
|
||||
|
||||
|
||||
|
@ -84,34 +76,90 @@ That way you can avoid spelling out all the names as command line arguments:
|
|||
|
||||
$ clang-rename rename-all -input=test.yaml test.cpp
|
||||
|
||||
|
||||
The YAML file also supports offsets:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
- Offset: 42
|
||||
NewName: foo
|
||||
...
|
||||
|
||||
|
||||
:program:`clang-rename` offers the following options:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ clang-rename --help
|
||||
USAGE: clang-rename [subcommand] [options] <source0> [... <sourceN>]
|
||||
$ clang-rename -help
|
||||
Usage: clang-rename {rename-at|rename-all} [OPTION]...
|
||||
|
||||
A tool to rename symbols in C/C++ code.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
.. 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 <offset> in
|
||||
<source0>. 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] <source0> [... <sourceN>]
|
||||
|
||||
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=<filename> - YAML file to store suggested fixes in.
|
||||
-extra-arg=<string> - Additional argument to append to the compiler command line.
|
||||
-extra-arg-before=<string> - Additional argument to prepend to the compiler command line.
|
||||
-i - Overwrite edited <file>s.
|
||||
-new-name=<string> - The new name to change the symbol to.
|
||||
-offset=<uint> - Locates the symbol by offset as opposed to <line>:<column>.
|
||||
-p=<string> - Build path.
|
||||
-pl - Print the locations affected by renaming to stderr.
|
||||
-pn - Print the found symbol's name prior to renaming to stderr.
|
||||
|
||||
|
||||
.. 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 <old-name>.
|
||||
|
||||
USAGE: clang-rename rename-all [subcommand] [options] <source0> [... <sourceN>]
|
||||
|
||||
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 common options:
|
||||
clang-rename rename-all options:
|
||||
|
||||
-export-fixes=<filename> - YAML file to store suggested fixes in.
|
||||
-extra-arg=<string> - Additional argument to append to the compiler command line
|
||||
-extra-arg-before=<string> - Additional argument to prepend to the compiler command line
|
||||
-extra-arg=<string> - Additional argument to append to the compiler command line.
|
||||
-extra-arg-before=<string> - Additional argument to prepend to the compiler command line.
|
||||
-i - Overwrite edited <file>s.
|
||||
-input=<string> - YAML file to load oldname-newname pairs from.
|
||||
-new-name=<string> - The new name to change the symbol to.
|
||||
-offset=<uint> - Locates the symbol by offset as opposed to <line>:<column>.
|
||||
-p=<string> - 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=<string> - The fully qualified name of the symbol.
|
||||
-old-name=<string> - The fully qualified name of the symbol, if -offset is not used.
|
||||
-p=<string> - Build path.
|
||||
|
||||
|
||||
Vim Integration
|
||||
===============
|
||||
|
|
|
@ -7,4 +7,4 @@ int main() {
|
|||
}
|
||||
|
||||
// Test 1.
|
||||
// RUN: clang-rename -qualified-name=Foo -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
|
||||
// RUN: clang-rename rename-all -old-name=Foo -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
|
||||
|
|
|
@ -5,7 +5,7 @@ class Foo2 /* Offset 2 */ { // CHECK: class Bar2 /* Offset 2 */ {
|
|||
};
|
||||
|
||||
// Test 1.
|
||||
// RUN: clang-rename -offset=6 -new-name=Bar1 -offset=76 -new-name=Bar2 %s -- | sed 's,//.*,,' | FileCheck %s
|
||||
// RUN: clang-rename rename-all -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.*' <file>
|
||||
|
|
|
@ -5,4 +5,4 @@ class Foo2 { // CHECK: class Bar2
|
|||
};
|
||||
|
||||
// Test 1.
|
||||
// RUN: clang-rename -qualified-name=Foo1 -new-name=Bar1 -qualified-name=Foo2 -new-name=Bar2 %s -- | sed 's,//.*,,' | FileCheck %s
|
||||
// RUN: clang-rename rename-all -old-name=Foo1 -new-name=Bar1 -old-name=Foo2 -new-name=Bar2 %s -- | sed 's,//.*,,' | FileCheck %s
|
||||
|
|
|
@ -9,4 +9,4 @@ int main() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// RUN: clang-rename -qualified-name=Foo -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
|
||||
// RUN: clang-rename rename-all -old-name=Foo -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
|
||||
|
|
|
@ -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: -new-name must be specified.
|
||||
// CHECK: clang-rename: for the -new-name option: must be specified
|
||||
|
|
Loading…
Reference in New Issue