reverting r281456

llvm-svn: 281459
This commit is contained in:
Kirill Bobyrev 2016-09-14 13:23:14 +00:00
parent d73ef1738b
commit 8d78af4bb4
9 changed files with 280 additions and 182 deletions

View File

@ -28,7 +28,6 @@
#include "clang/Tooling/CommonOptionsParser.h" #include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Refactoring.h" #include "clang/Tooling/Refactoring.h"
#include "clang/Tooling/Tooling.h" #include "clang/Tooling/Tooling.h"
#include <algorithm> #include <algorithm>
#include <set> #include <set>
#include <string> #include <string>
@ -46,10 +45,11 @@ namespace {
// to virtual method. // to virtual method.
class AdditionalUSRFinder : public RecursiveASTVisitor<AdditionalUSRFinder> { class AdditionalUSRFinder : public RecursiveASTVisitor<AdditionalUSRFinder> {
public: public:
AdditionalUSRFinder(const Decl *FoundDecl, ASTContext &Context) explicit AdditionalUSRFinder(const Decl *FoundDecl, ASTContext &Context,
: FoundDecl(FoundDecl), Context(Context) {} std::vector<std::string> *USRs)
: FoundDecl(FoundDecl), Context(Context), USRs(USRs) {}
std::vector<std::string> Find() { void Find() {
// Fill OverriddenMethods and PartialSpecs storages. // Fill OverriddenMethods and PartialSpecs storages.
TraverseDecl(Context.getTranslationUnitDecl()); TraverseDecl(Context.getTranslationUnitDecl());
if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(FoundDecl)) { if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(FoundDecl)) {
@ -66,7 +66,7 @@ public:
} else { } else {
USRSet.insert(getUSRForDecl(FoundDecl)); 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) { bool VisitCXXMethodDecl(const CXXMethodDecl *MethodDecl) {
@ -129,98 +129,69 @@ private:
const Decl *FoundDecl; const Decl *FoundDecl;
ASTContext &Context; ASTContext &Context;
std::vector<std::string> *USRs;
std::set<std::string> USRSet; std::set<std::string> USRSet;
std::vector<const CXXMethodDecl *> OverriddenMethods; std::vector<const CXXMethodDecl *> OverriddenMethods;
std::vector<const ClassTemplatePartialSpecializationDecl *> PartialSpecs; std::vector<const ClassTemplatePartialSpecializationDecl *> PartialSpecs;
}; };
} // namespace } // namespace
class NamedDeclFindingConsumer : public ASTConsumer { struct NamedDeclFindingConsumer : public ASTConsumer {
public: void HandleTranslationUnit(ASTContext &Context) override {
NamedDeclFindingConsumer(ArrayRef<unsigned> SymbolOffsets, const SourceManager &SourceMgr = Context.getSourceManager();
ArrayRef<std::string> QualifiedNames, // The file we look for the USR in will always be the main source file.
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();
const SourceLocation Point = const SourceLocation Point =
SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()) SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID())
.getLocWithOffset(SymbolOffset); .getLocWithOffset(SymbolOffset);
if (!Point.isValid())
if (!Point.isValid()) { return;
ErrorOccurred = true; const NamedDecl *FoundDecl = nullptr;
unsigned InvalidOffset = Engine.getCustomDiagID( if (OldName.empty())
DiagnosticsEngine::Error, FoundDecl = getNamedDeclAt(Context, Point);
"SourceLocation in file %0 at offset %1 is invalid"); else
Engine.Report(Point, InvalidOffset) << SourceMgr.getFilename(Point) FoundDecl = getNamedDeclFor(Context, OldName);
<< SymbolOffset;
return false;
}
const NamedDecl *FoundDecl = QualifiedName.empty()
? getNamedDeclAt(Context, Point)
: getNamedDeclFor(Context, QualifiedName);
if (FoundDecl == nullptr) { if (FoundDecl == nullptr) {
if (QualifiedName.empty()) { if (OldName.empty()) {
FullSourceLoc FullLoc(Point, SourceMgr); FullSourceLoc FullLoc(Point, SourceMgr);
unsigned CouldNotFindSymbolAt = Engine.getCustomDiagID( errs() << "clang-rename: could not find symbol at "
DiagnosticsEngine::Error, << SourceMgr.getFilename(Point) << ":"
"clang-rename could not find symbol (offset %0)"); << FullLoc.getSpellingLineNumber() << ":"
Engine.Report(Point, CouldNotFindSymbolAt) << SymbolOffset; << FullLoc.getSpellingColumnNumber() << " (offset "
ErrorOccurred = true; << SymbolOffset << ").\n";
return false; } else {
errs() << "clang-rename: could not find symbol " << OldName << ".\n";
} }
unsigned CouldNotFindSymbolNamed = Engine.getCustomDiagID( return;
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 // If FoundDecl is a constructor or destructor, we want to instead take the
// the Decl of the corresponding class. // Decl of the corresponding class.
if (const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(FoundDecl)) if (const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(FoundDecl))
FoundDecl = CtorDecl->getParent(); FoundDecl = CtorDecl->getParent();
else if (const auto *DtorDecl = dyn_cast<CXXDestructorDecl>(FoundDecl)) else if (const auto *DtorDecl = dyn_cast<CXXDestructorDecl>(FoundDecl))
FoundDecl = DtorDecl->getParent(); FoundDecl = DtorDecl->getParent();
SpellingNames.push_back(FoundDecl->getNameAsString()); *SpellingName = FoundDecl->getNameAsString();
AdditionalUSRFinder Finder(FoundDecl, Context);
USRList.push_back(Finder.Find()); AdditionalUSRFinder Finder(FoundDecl, Context, USRs);
return true; Finder.Find();
} }
void HandleTranslationUnit(ASTContext &Context) override { unsigned SymbolOffset;
const SourceManager &SourceMgr = Context.getSourceManager(); std::string OldName;
for (unsigned Offset : SymbolOffsets) { std::string *SpellingName;
if (!FindSymbol(Context, SourceMgr, Offset, "")) std::vector<std::string> *USRs;
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;
}; };
std::unique_ptr<ASTConsumer> USRFindingAction::newASTConsumer() { std::unique_ptr<ASTConsumer> USRFindingAction::newASTConsumer() {
return llvm::make_unique<NamedDeclFindingConsumer>( std::unique_ptr<NamedDeclFindingConsumer> Consumer(
SymbolOffsets, QualifiedNames, SpellingNames, USRList, ErrorOccurred); new NamedDeclFindingConsumer);
SpellingName = "";
Consumer->SymbolOffset = SymbolOffset;
Consumer->OldName = OldName;
Consumer->USRs = &USRs;
Consumer->SpellingName = &SpellingName;
return std::move(Consumer);
} }
} // namespace rename } // namespace rename

View File

@ -15,11 +15,7 @@
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDING_ACTION_H #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDING_ACTION_H
#define 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 "clang/Frontend/FrontendAction.h"
#include "llvm/ADT/ArrayRef.h"
#include <string>
#include <vector>
namespace clang { namespace clang {
class ASTConsumer; class ASTConsumer;
@ -29,22 +25,20 @@ class NamedDecl;
namespace rename { namespace rename {
struct USRFindingAction { struct USRFindingAction {
USRFindingAction(ArrayRef<unsigned> SymbolOffsets, USRFindingAction(unsigned Offset, const std::string &Name)
ArrayRef<std::string> QualifiedNames) : SymbolOffset(Offset), OldName(Name) {}
: SymbolOffsets(SymbolOffsets), QualifiedNames(QualifiedNames),
ErrorOccurred(false) {}
std::unique_ptr<ASTConsumer> newASTConsumer(); std::unique_ptr<ASTConsumer> newASTConsumer();
ArrayRef<std::string> getUSRSpellings() { return SpellingNames; } // \brief get the spelling of the USR(s) as it would appear in source files.
ArrayRef<std::vector<std::string>> getUSRList() { return USRList; } const std::string &getUSRSpelling() { return SpellingName; }
bool errorOccurred() { return ErrorOccurred; }
const std::vector<std::string> &getUSRs() { return USRs; }
private: private:
std::vector<unsigned> SymbolOffsets; unsigned SymbolOffset;
std::vector<std::string> QualifiedNames; std::string OldName;
std::vector<std::string> SpellingNames; std::string SpellingName;
std::vector<std::vector<std::string>> USRList; std::vector<std::string> USRs;
bool ErrorOccurred;
}; };
} // namespace rename } // namespace rename

View File

@ -38,12 +38,28 @@
#include <system_error> #include <system_error>
using namespace llvm; using namespace llvm;
using namespace clang; 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. /// \brief An oldname -> newname rename.
struct RenameAllInfo { struct RenameAllInfo {
std::string OldName;
unsigned Offset = 0; unsigned Offset = 0;
std::string QualifiedName;
std::string NewName; std::string NewName;
}; };
@ -56,8 +72,8 @@ namespace yaml {
/// (de)serialized. /// (de)serialized.
template <> struct MappingTraits<RenameAllInfo> { template <> struct MappingTraits<RenameAllInfo> {
static void mapping(IO &IO, RenameAllInfo &Info) { static void mapping(IO &IO, RenameAllInfo &Info) {
IO.mapOptional("OldName", Info.OldName);
IO.mapOptional("Offset", Info.Offset); IO.mapOptional("Offset", Info.Offset);
IO.mapOptional("QualifiedName", Info.QualifiedName);
IO.mapRequired("NewName", Info.NewName); IO.mapRequired("NewName", Info.NewName);
} }
}; };
@ -65,42 +81,72 @@ template <> struct MappingTraits<RenameAllInfo> {
} // end namespace yaml } // end namespace yaml
} // end namespace llvm } // end namespace llvm
static cl::OptionCategory ClangRenameOptions("clang-rename common options"); 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::list<unsigned> SymbolOffsets( 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", "offset",
cl::desc("Locates the symbol by offset as opposed to <line>:<column>."), cl::desc("Locates the symbol by offset as opposed to <line>:<column>."),
cl::ZeroOrMore, cl::cat(ClangRenameOptions)); (isRenameAll ? cl::ZeroOrMore : cl::Required), cl::cat(*Category));
static cl::opt<bool> Inplace("i", cl::desc("Overwrite edited <file>s."), cl::list<std::string> OldNames(
cl::cat(ClangRenameOptions)); "old-name",
static cl::list<std::string> cl::desc(
QualifiedNames("qualified-name", "The fully qualified name of the symbol, if -offset is not used."),
cl::desc("The fully qualified name of the symbol."), (isRenameAll ? cl::ZeroOrMore : cl::Optional),
cl::ZeroOrMore, cl::cat(ClangRenameOptions)); cl::cat(ClangRenameAllCategory));
cl::opt<bool> Inplace("i", cl::desc("Overwrite edited <file>s."),
static cl::list<std::string> cl::cat(*Category));
NewNames("new-name", cl::desc("The new name to change the symbol to."), cl::opt<bool> PrintName(
cl::ZeroOrMore, cl::cat(ClangRenameOptions));
static cl::opt<bool> PrintName(
"pn", "pn",
cl::desc("Print the found symbol's name prior to renaming to stderr."), cl::desc("Print the found symbol's name prior to renaming to stderr."),
cl::cat(ClangRenameOptions)); cl::cat(ClangRenameAtCategory));
static cl::opt<bool> PrintLocations( cl::opt<bool> PrintLocations(
"pl", cl::desc("Print the locations affected by renaming to stderr."), "pl", cl::desc("Print the locations affected by renaming to stderr."),
cl::cat(ClangRenameOptions)); cl::cat(ClangRenameAtCategory));
static cl::opt<std::string> cl::opt<std::string> ExportFixes(
ExportFixes("export-fixes", "export-fixes", cl::desc("YAML file to store suggested fixes in."),
cl::desc("YAML file to store suggested fixes in."), cl::value_desc("filename"), cl::cat(*Category));
cl::value_desc("filename"), cl::cat(ClangRenameOptions)); cl::opt<std::string> Input(
static cl::opt<std::string> "input", cl::desc("YAML file to load oldname-newname pairs from."),
Input("input", cl::desc("YAML file to load oldname-newname pairs from."), cl::Optional, cl::cat(ClangRenameAllCategory));
cl::Optional, cl::cat(ClangRenameOptions));
int main(int argc, const char **argv) { tooling::CommonOptionsParser OP(argc, argv, *Category, Usage);
tooling::CommonOptionsParser OP(argc, argv, ClangRenameOptions);
if (!Input.empty()) { 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 = ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer =
llvm::MemoryBuffer::getFile(Input); llvm::MemoryBuffer::getFile(Input);
if (!Buffer) { if (!Buffer) {
@ -113,8 +159,8 @@ int main(int argc, const char **argv) {
llvm::yaml::Input YAML(Buffer.get()->getBuffer()); llvm::yaml::Input YAML(Buffer.get()->getBuffer());
YAML >> Infos; YAML >> Infos;
for (const auto &Info : Infos) { for (const auto &Info : Infos) {
if (!Info.QualifiedName.empty()) if (!Info.OldName.empty())
QualifiedNames.push_back(Info.QualifiedName); OldNames.push_back(Info.OldName);
else else
SymbolOffsets.push_back(Info.Offset); SymbolOffsets.push_back(Info.Offset);
NewNames.push_back(Info.NewName); NewNames.push_back(Info.NewName);
@ -122,17 +168,18 @@ int main(int argc, const char **argv) {
} }
// Check the arguments for correctness. // Check the arguments for correctness.
if (NewNames.empty()) { 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); exit(1);
} }
// Check if NewNames is a valid identifier in C++17. // Check if NewNames is a valid identifier in C++17.
for (const auto &NewName : NewNames) {
LangOptions Options; LangOptions Options;
Options.CPlusPlus = true; Options.CPlusPlus = true;
Options.CPlusPlus1z = true; Options.CPlusPlus1z = true;
IdentifierTable Table(Options); IdentifierTable Table(Options);
for (const auto &NewName : NewNames) {
auto NewNameTokKind = Table.get(NewName).getTokenID(); auto NewNameTokKind = Table.get(NewName).getTokenID();
if (!tok::isAnyIdentifier(NewNameTokKind)) { if (!tok::isAnyIdentifier(NewNameTokKind)) {
errs() << "ERROR: new name is not a valid identifier in C++17.\n\n"; 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()) { if (!OldNames.empty() && OldNames.size() != NewNames.size()) {
errs() << "clang-rename: number of symbol offsets(" << SymbolOffsets.size() errs() << "clang-rename: number of old names (" << OldNames.size()
<< ") + number of qualified names (" << QualifiedNames.size() << ") do not equal to number of new names (" << NewNames.size()
<< ") must be equal to number of new names(" << NewNames.size()
<< ").\n\n"; << ").\n\n";
cl::PrintHelpMessage(); cl::PrintHelpMessage();
exit(1); exit(1);
} }
auto Files = OP.getSourcePathList(); if (!SymbolOffsets.empty() && SymbolOffsets.size() != NewNames.size()) {
tooling::RefactoringTool Tool(OP.getCompilations(), Files); errs() << "clang-rename: number of symbol offsets (" << SymbolOffsets.size()
rename::USRFindingAction FindingAction(SymbolOffsets, QualifiedNames); << ") do not equal to number of new names (" << NewNames.size()
Tool.run(tooling::newFrontendActionFactory(&FindingAction).get()); << ").\n\n";
const std::vector<std::vector<std::string>> &USRList = cl::PrintHelpMessage();
FindingAction.getUSRList(); exit(1);
const std::vector<std::string> &PrevNames = FindingAction.getUSRSpellings();
if (PrintName) {
for (const auto &PrevName : PrevNames) {
outs() << "clang-rename found name: " << PrevName << '\n';
}
} }
if (FindingAction.errorOccurred()) { std::vector<std::vector<std::string>> USRList;
// Diagnostics are already issued at this point. 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); exit(1);
} }
if (PrintName) {
errs() << "clang-rename: found name: " << PrevName << '\n';
}
}
// Perform the renaming. // Perform the renaming.
rename::RenamingAction RenameAction(NewNames, PrevNames, USRList, rename::RenamingAction RenameAction(NewNames, PrevNames, USRList,
Tool.getReplacements(), PrintLocations); Tool.getReplacements(), PrintLocations);
std::unique_ptr<tooling::FrontendActionFactory> Factory = auto Factory = tooling::newFrontendActionFactory(&RenameAction);
tooling::newFrontendActionFactory(&RenameAction);
int ExitCode; int ExitCode;
if (Inplace) { if (Inplace) {
@ -223,3 +287,24 @@ int main(int argc, const char **argv) {
exit(ExitCode); 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);
}

View File

@ -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 Although a command line interface exists, it is highly recommended to use the
text editor interface instead for better experience. text editor interface instead for better experience.
You can also identify one or more symbols to be renamed by giving the fully You can also identify one or more symbols to be renamed by giving the fully qualified
qualified name: name:
.. code-block:: console .. 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 Alternatively, old name / new name pairs can be put into a YAML file:
$ 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:
.. code-block:: yaml .. code-block:: yaml
--- ---
- Offset: 42 - OldName: foo
NewName: bar NewName: bar
- QualifiedName: foo
NewName: something
... ...
@ -84,12 +76,40 @@ That way you can avoid spelling out all the names as command line arguments:
$ clang-rename rename-all -input=test.yaml test.cpp $ 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: :program:`clang-rename` offers the following options:
.. code-block:: console .. code-block:: console
$ clang-rename --help $ clang-rename -help
USAGE: clang-rename [subcommand] [options] <source0> [... <sourceN>] 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: OPTIONS:
@ -99,19 +119,47 @@ That way you can avoid spelling out all the names as command line arguments:
-help-list - Display list of available options (-help-list-hidden for more) -help-list - Display list of available options (-help-list-hidden for more)
-version - Display the version of this program -version - Display the version of this program
clang-rename common options: clang-rename rename-at options:
-export-fixes=<filename> - YAML file to store suggested fixes in. -export-fixes=<filename> - YAML file to store suggested fixes in.
-extra-arg=<string> - Additional argument to append 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 -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.
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.
-i - Overwrite edited <file>s. -i - Overwrite edited <file>s.
-input=<string> - YAML file to load oldname-newname pairs from. -input=<string> - YAML file to load oldname-newname pairs from.
-new-name=<string> - The new name to change the symbol to. -new-name=<string> - The new name to change the symbol to.
-offset=<uint> - Locates the symbol by offset as opposed to <line>:<column>. -offset=<uint> - Locates the symbol by offset as opposed to <line>:<column>.
-p=<string> - Build path -old-name=<string> - The fully qualified name of the symbol, if -offset is not used.
-pl - Print the locations affected by renaming to stderr. -p=<string> - Build path.
-pn - Print the found symbol's name prior to renaming to stderr.
-qualified-name=<string> - The fully qualified name of the symbol.
Vim Integration Vim Integration
=============== ===============

View File

@ -7,4 +7,4 @@ int main() {
} }
// Test 1. // 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

View File

@ -5,7 +5,7 @@ class Foo2 /* Offset 2 */ { // CHECK: class Bar2 /* Offset 2 */ {
}; };
// Test 1. // 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: // To find offsets after modifying the file, use:
// grep -Ubo 'Foo.*' <file> // grep -Ubo 'Foo.*' <file>

View File

@ -5,4 +5,4 @@ class Foo2 { // CHECK: class Bar2
}; };
// Test 1. // 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

View File

@ -9,4 +9,4 @@ int main() {
return 0; 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

View File

@ -1,4 +1,4 @@
// Check for an error while -new-name argument has not been passed to // Check for an error while -new-name argument has not been passed to
// clang-rename. // clang-rename.
// RUN: not clang-rename -offset=133 %s 2>&1 | FileCheck %s // 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