Index: clang-rename/USRFindingAction.h =================================================================== --- clang-rename/USRFindingAction.h +++ clang-rename/USRFindingAction.h @@ -16,6 +16,7 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDING_ACTION_H_ #include "clang/Frontend/FrontendAction.h" +#include namespace clang { class ASTConsumer; @@ -25,20 +26,19 @@ namespace rename { struct USRFindingAction { - USRFindingAction(unsigned Offset, const std::string &Name) - : SymbolOffset(Offset), OldName(Name) {} + USRFindingAction(const std::vector &SymbolOffsets, + const std::vector &OldNames) + : SymbolOffsets(SymbolOffsets), OldNames(OldNames) {} 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; } + const std::vector &getUSRSpellings() { return SpellingNames; } + const std::vector> &getUSRList() { return USRList; } private: - unsigned SymbolOffset; - std::string OldName; - std::string SpellingName; - std::vector USRs; + const std::vector &SymbolOffsets; + const std::vector &OldNames; + std::vector SpellingNames; + std::vector> USRList; }; } // namespace rename Index: clang-rename/USRFindingAction.cpp =================================================================== --- clang-rename/USRFindingAction.cpp +++ clang-rename/USRFindingAction.cpp @@ -45,11 +45,10 @@ // to virtual method. class AdditionalUSRFinder : public RecursiveASTVisitor { public: - explicit AdditionalUSRFinder(const Decl *FoundDecl, ASTContext &Context, - std::vector *USRs) - : FoundDecl(FoundDecl), Context(Context), USRs(USRs) {} + explicit 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)) { @@ -67,7 +66,8 @@ } else { USRSet.insert(getUSRForDecl(FoundDecl)); } - USRs->insert(USRs->end(), USRSet.begin(), USRSet.end()); + USRs.insert(USRs.end(), USRSet.begin(), USRSet.end()); + return USRs; } bool VisitCXXMethodDecl(const CXXMethodDecl *MethodDecl) { @@ -134,65 +134,76 @@ const Decl *FoundDecl; ASTContext &Context; - std::vector *USRs; + std::vector USRs; std::set USRSet; std::vector OverriddenMethods; std::vector PartialSpecs; }; } // namespace -struct NamedDeclFindingConsumer : public ASTConsumer { +class NamedDeclFindingConsumer : public ASTConsumer { +public: + explicit NamedDeclFindingConsumer( + const std::vector &SymbolOffsets, + const std::vector &OldNames, + std::vector &SpellingNames, + std::vector> &USRList) + : SymbolOffsets(SymbolOffsets), OldNames(OldNames), + SpellingNames(SpellingNames), USRList(USRList) {} + 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()) - return; - const NamedDecl *FoundDecl = nullptr; - if (OldName.empty()) { - FoundDecl = getNamedDeclAt(Context, Point); - } else { - FoundDecl = getNamedDeclFor(Context, OldName); - } - if (FoundDecl == nullptr) { - FullSourceLoc FullLoc(Point, SourceMgr); - errs() << "clang-rename: could not find symbol at " - << SourceMgr.getFilename(Point) << ":" - << FullLoc.getSpellingLineNumber() << ":" - << FullLoc.getSpellingColumnNumber() << " (offset " << SymbolOffset - << ").\n"; - return; - } + for (unsigned I = 0; I < OldNames.size(); ++I) { + unsigned SymbolOffset = SymbolOffsets[I]; + const std::string &OldName = OldNames[I]; + 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()) + return; + const NamedDecl *FoundDecl = nullptr; + if (OldName.empty()) { + FoundDecl = getNamedDeclAt(Context, Point); + } else { + FoundDecl = getNamedDeclFor(Context, OldName); + } + if (FoundDecl == nullptr) { + FullSourceLoc FullLoc(Point, SourceMgr); + errs() << "clang-rename: could not find symbol at " + << SourceMgr.getFilename(Point) << ":" + << FullLoc.getSpellingLineNumber() << ":" + << FullLoc.getSpellingColumnNumber() << " (offset " + << SymbolOffset << ").\n"; + return; + } - // 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(); + // 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(); + } + SpellingNames.push_back(FoundDecl->getNameAsString()); + AdditionalUSRFinder Finder(FoundDecl, Context); + std::vector NextUSRBunch = Finder.Find(); + USRList.push_back(NextUSRBunch); } - *SpellingName = FoundDecl->getNameAsString(); - - AdditionalUSRFinder Finder(FoundDecl, Context, USRs); - Finder.Find(); } - unsigned SymbolOffset; - std::string OldName; - std::string *SpellingName; - std::vector *USRs; +private: + const std::vector &SymbolOffsets; + const std::vector &OldNames; + std::vector &SpellingNames; + std::vector> &USRList; }; std::unique_ptr USRFindingAction::newASTConsumer() { std::unique_ptr Consumer( - new NamedDeclFindingConsumer); - SpellingName = ""; - Consumer->SymbolOffset = SymbolOffset; - Consumer->OldName = OldName; - Consumer->USRs = &USRs; - Consumer->SpellingName = &SpellingName; + new NamedDeclFindingConsumer(SymbolOffsets, OldNames, SpellingNames, + USRList)); return std::move(Consumer); } Index: clang-rename/tool/ClangRename.cpp =================================================================== --- clang-rename/tool/ClangRename.cpp +++ clang-rename/tool/ClangRename.cpp @@ -175,11 +175,11 @@ } // 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"; @@ -203,39 +203,36 @@ 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(); + std::vector SymbolOffsetsVector(Count, 0); + std::vector OldNamesVector(Count, ""); 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 (!SymbolOffsets.empty()) { + SymbolOffsetsVector[I] = SymbolOffsets[I]; + } + if (!OldNames.empty()) { + OldNamesVector[I] = OldNames[I]; } + } - if (PrintName) { - errs() << "clang-rename: found name: " << PrevName << '\n'; + rename::USRFindingAction USRAction(SymbolOffsetsVector, OldNamesVector); + Tool.run(tooling::newFrontendActionFactory(&USRAction).get()); + const std::vector> &USRList = USRAction.getUSRList(); + const std::vector &PrevNames = USRAction.getUSRSpellings(); + if (PrintName) { + for (const auto &PrevName : PrevNames) { + outs() << "clang-rename found name: " << PrevName << '\n'; } } // 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) {