omtcyfz updated this revision to Diff 71130. omtcyfz added a comment. Remove redundant arguments passed to diagnostic.
https://reviews.llvm.org/D24224 Files: clang-rename/USRFindingAction.cpp clang-rename/USRFindingAction.h clang-rename/tool/ClangRename.cpp docs/clang-rename.rst test/clang-rename/ClassFindByName.cpp test/clang-rename/ClassTestMulti.cpp test/clang-rename/ClassTestMultiByName.cpp test/clang-rename/ClassTestMultiByNameYAML.cpp test/clang-rename/FunctionWithClassFindByName.cpp test/clang-rename/Inputs/ClassTestMultiByNameYAMLRenameAll.yaml test/clang-rename/Inputs/ClassTestMultiByNameYAMLRenameAt.yaml test/clang-rename/InvalidOldName.cpp test/clang-rename/NoNewName.cpp
Index: test/clang-rename/NoNewName.cpp =================================================================== --- test/clang-rename/NoNewName.cpp +++ 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. Index: test/clang-rename/InvalidOldName.cpp =================================================================== --- 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. Index: test/clang-rename/Inputs/ClassTestMultiByNameYAMLRenameAt.yaml =================================================================== --- test/clang-rename/Inputs/ClassTestMultiByNameYAMLRenameAt.yaml +++ /dev/null @@ -1,6 +0,0 @@ ---- -- Offset: 6 - NewName: Bar1 -- Offset: 44 - NewName: Bar2 -... Index: test/clang-rename/Inputs/ClassTestMultiByNameYAMLRenameAll.yaml =================================================================== --- test/clang-rename/Inputs/ClassTestMultiByNameYAMLRenameAll.yaml +++ /dev/null @@ -1,6 +0,0 @@ ---- -- OldName: Foo1 - NewName: Bar1 -- OldName: Foo2 - NewName: Bar2 -... Index: test/clang-rename/FunctionWithClassFindByName.cpp =================================================================== --- test/clang-rename/FunctionWithClassFindByName.cpp +++ test/clang-rename/FunctionWithClassFindByName.cpp @@ -9,4 +9,4 @@ 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 Index: test/clang-rename/ClassTestMultiByNameYAML.cpp =================================================================== --- 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 Index: test/clang-rename/ClassTestMultiByName.cpp =================================================================== --- test/clang-rename/ClassTestMultiByName.cpp +++ test/clang-rename/ClassTestMultiByName.cpp @@ -5,4 +5,4 @@ }; // 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 Index: test/clang-rename/ClassTestMulti.cpp =================================================================== --- test/clang-rename/ClassTestMulti.cpp +++ test/clang-rename/ClassTestMulti.cpp @@ -5,7 +5,7 @@ }; // 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.*' <file> Index: test/clang-rename/ClassFindByName.cpp =================================================================== --- test/clang-rename/ClassFindByName.cpp +++ test/clang-rename/ClassFindByName.cpp @@ -7,4 +7,4 @@ } // 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 Index: docs/clang-rename.rst =================================================================== --- docs/clang-rename.rst +++ docs/clang-rename.rst @@ -52,21 +52,29 @@ 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 +Or even combine it: -Alternatively, old name / new name pairs can be put into a YAML file: +.. 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: .. code-block:: yaml --- - - OldName: foo + - Offset: 42 NewName: bar + - QualifiedName: foo + NewName: something ... @@ -76,90 +84,34 @@ $ 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 {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. + $ clang-rename --help + USAGE: clang-rename [subcommand] [options] <source0> [... <sourceN>] - -.. 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: + clang-rename common 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. + -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. - -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>. - -old-name=<string> - The fully qualified name of the symbol, if -offset is not used. - -p=<string> - Build path. - + -qualified-name=<string> - The fully qualified name of the symbol. Vim Integration =============== Index: clang-rename/tool/ClangRename.cpp =================================================================== --- clang-rename/tool/ClangRename.cpp +++ 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,81 +56,51 @@ /// (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); } }; } // 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); - - 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; - } +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)); - 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,83 +113,65 @@ 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); } } // 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); } // 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"; exit(1); } } - 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() + 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); } - 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); - } - - 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 +223,3 @@ 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); -} Index: clang-rename/USRFindingAction.h =================================================================== --- clang-rename/USRFindingAction.h +++ 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 <string> +#include <vector> namespace clang { class ASTConsumer; @@ -25,20 +29,22 @@ namespace rename { struct USRFindingAction { - USRFindingAction(unsigned Offset, const std::string &Name) - : SymbolOffset(Offset), OldName(Name) {} + USRFindingAction(ArrayRef<unsigned> SymbolOffsets, + ArrayRef<std::string> QualifiedNames) + : SymbolOffsets(SymbolOffsets), QualifiedNames(QualifiedNames), + ErrorOccurred(false) {} std::unique_ptr<ASTConsumer> 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<std::string> &getUSRs() { return USRs; } + ArrayRef<std::string> getUSRSpellings() { return SpellingNames; } + ArrayRef<std::vector<std::string>> getUSRList() { return USRList; } + bool errorOccurred() { return ErrorOccurred; } private: - unsigned SymbolOffset; - std::string OldName; - std::string SpellingName; - std::vector<std::string> USRs; + std::vector<unsigned> SymbolOffsets; + std::vector<std::string> QualifiedNames; + std::vector<std::string> SpellingNames; + std::vector<std::vector<std::string>> USRList; + bool ErrorOccurred; }; } // namespace rename Index: clang-rename/USRFindingAction.cpp =================================================================== --- clang-rename/USRFindingAction.cpp +++ clang-rename/USRFindingAction.cpp @@ -28,6 +28,7 @@ #include "clang/Tooling/CommonOptionsParser.h" #include "clang/Tooling/Refactoring.h" #include "clang/Tooling/Tooling.h" + #include <algorithm> #include <set> #include <string> @@ -45,11 +46,10 @@ // to virtual method. class AdditionalUSRFinder : public RecursiveASTVisitor<AdditionalUSRFinder> { public: - explicit AdditionalUSRFinder(const Decl *FoundDecl, ASTContext &Context, - std::vector<std::string> *USRs) - : FoundDecl(FoundDecl), Context(Context), USRs(USRs) {} + AdditionalUSRFinder(const Decl *FoundDecl, ASTContext &Context) + : FoundDecl(FoundDecl), Context(Context) {} - void Find() { + std::vector<std::string> Find() { // Fill OverriddenMethods and PartialSpecs storages. TraverseDecl(Context.getTranslationUnitDecl()); if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(FoundDecl)) { @@ -66,7 +66,7 @@ } else { USRSet.insert(getUSRForDecl(FoundDecl)); } - USRs->insert(USRs->end(), USRSet.begin(), USRSet.end()); + return std::vector<std::string>(USRSet.begin(), USRSet.end()); } bool VisitCXXMethodDecl(const CXXMethodDecl *MethodDecl) { @@ -129,69 +129,99 @@ 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 -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<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(); + 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"; + unsigned CouldNotFindSymbolAt = Engine.getCustomDiagID( + DiagnosticsEngine::Error, + "clang-rename could not find symbol (offset %0)"); + Engine.Report(Point, CouldNotFindSymbolAt) << SymbolOffset; + ErrorOccurred = true; + return false; } 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(); - *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<std::string> *USRs; + 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<NamedDeclFindingConsumer> Consumer( - new NamedDeclFindingConsumer); - SpellingName = ""; - Consumer->SymbolOffset = SymbolOffset; - Consumer->OldName = OldName; - Consumer->USRs = &USRs; - Consumer->SpellingName = &SpellingName; - return std::move(Consumer); + return llvm::make_unique<NamedDeclFindingConsumer>( + SymbolOffsets, QualifiedNames, SpellingNames, USRList, ErrorOccurred); } } // namespace rename
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits